Так что у меня есть функция крюка в winspool.drv!WritePrinter
, который успешно подключен к неуправляемому C ++, удаленно внедренному в spoolsv.exe.
В настоящее время ловушка, кажется, либо заменяет исходную функцию, либо портит стек необнаружимым способом: после перехвата вызовы WritePrinter не приводят к активности принтера вне ловушки.
Я понял, что есть по крайней мере один способ вызова оригинальной функции, так называемый LhGetOldProc
, Однако, использование этого приводит к сбоям, не уверен, является ли это ошибкой, связанной с easyhook, или это просто плохое приведение.
Крюк обратного вызова с LhGetOldProc
:
UCHAR *uc = NULL;
LhGetOldProc(hhW, &uc);
typedef BOOL (*wp)(_In_ HANDLE, _In_ LPVOID, _In_ DWORD cbBuf, _Out_ LPDWORD);
wp my_wp = reinterpret_cast<wp>(reinterpret_cast<long>(uc)); // http://stackoverflow.com/questions/1096341/function-pointers-casting-in-c
BOOL res ;
if (my_wp == 0x0) {
return -1;
} else {
res = my_wp(hPrinter, pBuf, cbBuf, pcWritten); // crash
}
Код крючка:
HMODULE hSpoolsv = LoadLibraryA("winspool.drv");
TRACED_HOOK_HANDLE hHook = new HOOK_TRACE_INFO();
NTSTATUS NtStatus;
UNICODE_STRING* NameBuffer = NULL;
HANDLE hRemoteThread;
FORCE(LhInstallHook(GetProcAddress(hSpoolsv, "WritePrinter"), WritePrinterHookA, 0x0, hHook));
ULONG ACLEntries[1] = { (ULONG) - 1 };
FORCE(LhSetExclusiveACL(ACLEntries, 1, hHook));
hhW = hHook;
TIL: в 2013 году CodePlex (где находится дискуссионный список EasyHook) не принимает домены третьего уровня для электронной почты при регистрации в учетной записи Microsoft. Не собираюсь использовать Firebug для обхода формы.
Стек поврежден, потому что указатель на вашу функцию имеет неправильное соглашение о вызовах.
Соглашение о вызовах по умолчанию — __cdecl, который ожидает, что вызывающая сторона очистит стек.
typedef BOOL (* wp)(_In_ HANDLE ....);
равна:
typedef BOOL (__cdecl* wp)(_In_ HANDLE ...);
но функции winapi используют соглашение о вызовах __stdcall, которое ожидает, что вызываемый объект очистит стек.
вам нужно будет ввести определение функции __stdcall:
typedef BOOL (__stdcall* wp)(_In_ HANDLE ....);
Других решений пока нет …