Easyhook: неуправляемый перехват, как вызвать исходную функцию / изменить статус возврата?

Так что у меня есть функция крюка в winspool.drv!WritePrinter, который успешно подключен к неуправляемому C ++, удаленно внедренному в spoolsv.exe.

В настоящее время ловушка, кажется, либо заменяет исходную функцию, либо портит стек необнаружимым способом: после перехвата вызовы WritePrinter не приводят к активности принтера вне ловушки.

Я понял, что есть по крайней мере один способ вызова оригинальной функции, так называемый LhGetOldProc, Однако, использование этого приводит к сбоям, не уверен, является ли это ошибкой, связанной с easyhook, или это просто плохое приведение.

Итак, как правильно вызвать оригинальную функцию в неуправляемой версии 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 для обхода формы.

4

Решение

Стек поврежден, потому что указатель на вашу функцию имеет неправильное соглашение о вызовах.

Соглашение о вызовах по умолчанию — __cdecl, который ожидает, что вызывающая сторона очистит стек.

typedef BOOL (* wp)(_In_   HANDLE ....);

равна:

typedef BOOL (__cdecl* wp)(_In_   HANDLE ...);

но функции winapi используют соглашение о вызовах __stdcall, которое ожидает, что вызываемый объект очистит стек.
вам нужно будет ввести определение функции __stdcall:

typedef BOOL (__stdcall* wp)(_In_   HANDLE ....);
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]