Я пишу простую программу внедрения и перехвата Dll, и все было в порядке, когда я вручную объявлял функции для перехвата следующим образом для CreateFileA:
HANDLE WINAPI Hook_CreateFileA(
LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile
)
{
...
return CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
Но теперь мне нужно написать функцию, которая обрабатывает любую функцию из kernel32.dll, например. Это означает, что я ничего не знаю о функции, кроме ее имени и, следовательно, адреса.
Я немного знаю о соглашении о вызовах - параметры функции помещаются в прямом порядке (__stdcall), а затем вызывается функция. Я попытался написать функцию __declspec(naked), которая выглядит так:
PVOID __declspec(naked) HookAnyFunction()
{
/* do something */
__asm {
mov ebx, [esp]
add esp, 4
call pfnFuncAddr
sub esp, 4
mov[esp], ebx
ret
}
}
pfnFuncAddr — адрес исходной функции. Но вылетает приложение с внедренной Dll. Я предполагаю, что мой код портит стек или что-то в этом роде. Что я делаю неправильно? Надеюсь, мое объяснение имеет смысл.
ebx
вызывающего абонента, что может привести к сбою. Не уверен, что есть хороший способ обойти это, заметьте. - person Harry Johnston   schedule 15.05.2017pfnFuncAddr
, вам нужно заменить исходный адрес возврата (в [esp]) на выделенную исполняемую заглушку памяти, которая начинается с инструкции call до вашего обработчика почтового вызова. а затем должны быть некоторые данные - сохраненный исходный обратный адрес, имя функции, сохраненные параметры. в результате в обработчике сообщения вы получили адрес этого блока (это будет обратный адрес из инструкции call в заглушке) - можете отправить лог, включая возвращаемое значение, изменить его, если хотите. наконец, освободите блок-заглушку и вернитесь к исходному обратному адресу. - person RbMm   schedule 15.05.2017