Подтвердить что ты не робот

Как я могу подключить функции Windows в C/С++?

Если у меня есть функция foo(), что окна реализованы в kernel32.dll, и она всегда возвращает true, могу ли я иметь свою программу: "bar.exe" зацепить/объединить эту функцию Windows и заставить ее возвращать false для всех процессов вместо этого?

Итак, если мой svchost, например, вызывает foo(), он вернет false вместо true. То же самое действие следует ожидать для всех других выполняемых в настоящее время процессов.

Если да, то как? Наверное, я ищу общесистемный крючок или что-то в этом роде.

4b9b3361

Ответ 1

Взгляните на Detours, он идеально подходит для такого рода вещей.


Для общесистемной перехвата прочитайте эту статью из MSDN.


Сначала создайте DLL, которая обрабатывает функции. В этом примере ниже перечислены функции отправки и приема сокетов.

#include <windows.h>
#include <detours.h>

#pragma comment( lib, "Ws2_32.lib" )
#pragma comment( lib, "detours.lib" )
#pragma comment( lib, "detoured.lib" )

int ( WINAPI *Real_Send )( SOCKET s, const char *buf, int len, int flags ) = send;
int ( WINAPI *Real_Recv )( SOCKET s, char *buf, int len, int flags ) = recv;  
int WINAPI Mine_Send( SOCKET s, const char* buf, int len, int flags );
int WINAPI Mine_Recv( SOCKET s, char *buf, int len, int flags );

int WINAPI Mine_Send( SOCKET s, const char *buf, int len, int flags ) {
    // .. do stuff ..

    return Real_Send( s, buf, len, flags );
}

int WINAPI Mine_Recv( SOCKET s, char *buf, int len, int flags ) {
    // .. do stuff ..

    return Real_Recv( s, buf, len, flags );
}

BOOL WINAPI DllMain( HINSTANCE, DWORD dwReason, LPVOID ) {
    switch ( dwReason ) {
        case DLL_PROCESS_ATTACH:       
            DetourTransactionBegin();
            DetourUpdateThread( GetCurrentThread() );
            DetourAttach( &(PVOID &)Real_Send, Mine_Send );
            DetourAttach( &(PVOID &)Real_Recv, Mine_Recv );
            DetourTransactionCommit();
            break;

        case DLL_PROCESS_DETACH:
            DetourTransactionBegin();
            DetourUpdateThread( GetCurrentThread() );
            DetourDetach( &(PVOID &)Real_Send, Mine_Send );
            DetourDetach( &(PVOID &)Real_Recv, Mine_Recv );
            DetourTransactionCommit(); 
        break;
    }

    return TRUE;
}

Затем создайте программу для вставки DLL в целевое приложение.

#include <cstdio>
#include <windows.h>
#include <tlhelp32.h>

void EnableDebugPriv() {
    HANDLE hToken;
    LUID luid;
    TOKEN_PRIVILEGES tkp;

    OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken );

    LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luid );

    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    AdjustTokenPrivileges( hToken, false, &tkp, sizeof( tkp ), NULL, NULL );

    CloseHandle( hToken ); 
}

int main( int, char *[] ) {
    PROCESSENTRY32 entry;
    entry.dwSize = sizeof( PROCESSENTRY32 );

    HANDLE snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, NULL );

    if ( Process32First( snapshot, &entry ) == TRUE ) {
        while ( Process32Next( snapshot, &entry ) == TRUE ) {
            if ( stricmp( entry.szExeFile, "target.exe" ) == 0 ) {
                EnableDebugPriv();

                char dirPath[MAX_PATH];
                char fullPath[MAX_PATH];

                GetCurrentDirectory( MAX_PATH, dirPath );

                sprintf_s( fullPath, MAX_PATH, "%s\\DllToInject.dll", dirPath );

                HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, entry.th32ProcessID );
                LPVOID libAddr = (LPVOID)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "LoadLibraryA" );
                LPVOID llParam = (LPVOID)VirtualAllocEx( hProcess, NULL, strlen( fullPath ), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );

                WriteProcessMemory( hProcess, llParam, fullPath, strlen( fullPath ), NULL );
                CreateRemoteThread( hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)libAddr, llParam, NULL, NULL );
                CloseHandle( hProcess );
            }
        }
    }

    CloseHandle( snapshot );

    return 0;
}

Этого должно быть более чем достаточно, чтобы вы начали!

Ответ 2

EASYHOOK http://www.codeplex.com/easyhook

Доминировать все вышеупомянутые методы в простоте, гибкости и функциональности.

Это не обсуждалось ранее в процессах Hook. Я прочитал весь лист этой темы и с абсолютным сертификатом, EASYHOOK значительно превосходит. Независимо от того, используете ли вы C, С++, CLR, что угодно.

Я немного вставлю с домашней страницы codeplex, чтобы обеспечить достаточную оплату omage.

Ниже приведен неполный список функций:

  • Так называемый "барьер блокировки резьбы" избавится от многих основных проблем при подключении неизвестных API; эта технология уникальна для EasyHook.
  • Вы можете написать обработчики управляемых крючков для неуправляемых API-интерфейсов
  • Вы можете использовать все удобные управляемые коды, например NET Remoting, WPF и WCF, например
  • Документированный, чистый неуправляемый API-интерфейс для подключения
  • Поддержка 32- и 64-битного режима ядра (также проверьте мой драйвер PatchGuard 3 обхода, который можно найти в списке выпусков)
  • В целевом объекте не осталось ресурсов или утечек памяти.
  • Экспериментальный механизм инъекций стелса, который не привлечет внимания ни к одному из существующих AV-программ.
  • EasyHook32.dll и EasyHook64.dll являются чистыми неуправляемыми модулями и могут использоваться без какой-либо установленной инфраструктуры .NET!
  • Все крючки устанавливаются и автоматически удаляются стабильным образом.
  • Поддержка Windows Vista с пакетом обновления 1 (SP1) и Windows Server 2008 с пакетом обновления 1 (SP1) x64 с использованием полностью недокументированных API-интерфейсов, позволяющих подключаться к любому сеансу терминала.
  • Управляемая/Неуправляемая трассировка стека модулей внутри обработчика крюка
  • Получить управляемый/неуправляемый модуль вызова внутри обработчика привязки
  • Создавать собственные трассировки стека внутри обработчика крюка
  • Вы сможете писать библиотеки инъекций и процессы хоста, скомпилированные для AnyCPU, что позволит вам вставлять ваш код в 32- и 64-битные процессы из 64- и 32-битных процессов, используя ту же самую сборку во всех случаев.
  • EasyHook поддерживает RIP-относительное перемещение адреса для 64-битных целей.
  • Не требуется распаковка/установка.
  • Распространяемый компонент Visual Studio не требуется.

Я рад, что мой проститутка по-прежнему знает несколько трюков в сравнении, что заставляет меня держать их вокруг. Но, конечно, когда вам нужен КРЮК, 99 раз 100, EASYHOOK'r выведет вас туда быстрее. И он довольно активно поддерживается.

Ответ 3

Пожалуйста, дайте более подробную информацию о функции, которую вы хотите подключить! Существует несколько способов получить свой собственный код, вызываемый в таком случае, например:

  • Вы можете создать поддельную DLL с тем же именем, что и DLL, которая содержит функцию, которую вы хотите подключить (и скопировать ее в папку foo.exe). Эта библиотека будет выставлять те же функции, что и исходная DLL. Каждая открытая функция просто обходит вызов исходной DLL, за исключением функции, которую вы хотите подключить.

  • Вы можете изменить таблицу указателей функций во время выполнения, например, с помощью (коммерческого) пакета Detour, упомянутого в "кухне". Тем не менее, сделать такую ​​привязку можно легко сделать самостоятельно, см. эту статью, чтобы узнать, как.

  • Вы можете узнать, где определенная функция вызывается в foo.exe, и просто заменить код сборки, который вызывает функцию с кодом, который возвращает true ". В основном, вы исправляете" foo.exe".

  • Для определенных функций Windows предлагает автоматическое переключение, например. для событий клавиш и мыши. Для этого проверьте функцию SetWindowsHook.

Ответ 4

Это зависит от версии Windows, на которую вы хотите настроить таргетинг. Тем не менее, если вы играете в Pre-Vista, вы можете просто использовать SetWindowsHookEx для вставки вашей DLL в каждый запущенный процесс. Затем вашей DLL необходимо будет подключить соответствующую функцию с помощью Detours или аналогичного.

Ответ 5

Если вы пишете свой крючок в сборке и не используете Detours (по какой-либо причине), вам нужна некоторая ключевая информация о сохранении FALSE:

  • Win32, установите EAX в 0
  • Win64, установите RAX на 0

Вам нужно установить EAX или RAX (в зависимости от платформы) на ноль, поскольку последнее, что выполняет функция, которую вы подключаете. Это приведет к тому, что вызывающий код получит 0 в качестве возвращаемого значения (при условии, что они возвращают значение типа int или указателя).