Member 13419717 Ответов: 1

Традиционное подключение API вызывает сбой


Я использую API Hooking, как это предлагается в этом примере:

Функции API/подключение/Перехват с помощью инструкции jmp ака сращивание

Одна из функций, которую я подключаю, - это функция BitBlt (). В функции hooked я создаю новый поток с помощью CreateThread ().

BOOL WINAPI MY_BitBlt(HDC hdcDest, int xDest, int yDest, int width, int height, HDC hdcSrc, int xSrc, int ySrc, DWORD dwRop)
{
    VirtualProtect((LPVOID)pOrig_BitBlt_Address, SIZE_6, my_BitBlt_Protect, NULL);
    memcpy(pOrig_BitBlt_Address, old_BitBlt_Bytes, SIZE_6);
    BOOL rv = Real_BitBlt(hdcDest, xDest, yDest, width, height, hdcSrc, xSrc, ySrc, dwRop); // Calls the actual function
    memcpy(pOrig_BitBlt_Address, JMP_BitBlt, SIZE_6);
    VirtualProtect((LPVOID)pOrig_BitBlt_Address, SIZE_6, old_BitBlt_Protect, NULL);
    CreateThread(NULL, 0, _SampleProc, NULL , 0, 0);
    ...
    return rv;
}

Иногда даже после выгрузки DLL поток, созданный внутри BitBlt (), остается в памяти и вызывает исключение нарушения доступа, что, в свою очередь, приводит к сбою приложения. Катастрофа непоследовательна.

Затем я попытался создать поток с пустым потоком proc, это тоже привело к сбою.

Если я не создам новый поток, сбой не произойдет.

Разве не безопасно создавать потоки внутри подключенной функции?

Примечание: Я использую SetWindowsHookEx () для инъекции DLL.

Моя общая идея состоит в том, чтобы получить некоторую информацию от целевого приложения к моему приложению. Чтобы достичь этого, я сначала загружаю свою библиотеку dll в свое приложение, а затем использую SetWindowsHookEx() для применения специфического крючка потока. Когда моя dll загружается в целевой процесс, я выполняю зацепление API, как упоминалось выше.

Что я уже пробовал:

У меня есть способ обойти это, используя общую память вместо создания потоков. Кроме того, я слышал, как люди говорили, что я должен использовать батут в этом сценарии, но я не мог получить пример этого, хотя у меня есть основное представление о том, как это работает. Может ли кто-нибудь помочь мне с этой проблемой?

1 Ответов

Рейтинг:
0

Randor

Привет,

Этот код в Википедии низкого качества... он даже не использует Функция FlushInstructionCache[^] чтобы избежать сбоя или приостановки других потоков в процессе. Да, этот код предназначен для 1-ядерного процессора и однопоточного приложения. В противном случае код будет вызывать периодические сбои.

На компьютере с несколькими ядрами... инструкции, окружающие BitBlt, могут находиться в кэше процессора L1,L2 или L3...

Кроме того... чтобы избежать условий гонки, большинство библиотек крючков приостанавливают все другие потоки, кроме себя... а затем пишут инструкции батута.


с наилучшими пожеланиями,
- Дэвид Делон