Моя цель — перехватить OutputDebugStringA, чтобы я мог читать любые переданные ему сообщения. Я не пытаюсь подключить какой-либо другой процесс, а скорее текущий, просто чтобы научиться подключать.
Я не использую Detours и предпочел бы их не использовать, так как хочу узнать, как работает перехват на более глубоком уровне.
Я использую этот код для подключения:
void MakeJMP(BYTE *pAddress, DWORD dwJumpTo, DWORD dwLen);
void myCallback(LPCSTR s);
DWORD dwAddr = (DWORD) GetProcAddress(GetModuleHandleA("kernel32.dll"), "OutputDebugStringA");
// I cast it to byte and later to DWORD so it adds 5
DWORD dwRetAddr = ((BYTE)dwAddr) + 5; // +5 because I will override 5 bytes
void __declspec(naked) My_OutputDebugStringA(){
__asm{
mov edi, edi
push ebp
mov ebp, esp
// ^those 5 bytes are overriden from the original OutputDebugStringA stub from kernel32.dll, so I restore them here
pushad;
pushfd; // to prevent stack messing
push [ebp+8]; // OutputDebugStringA takes a LPCSTR parameter which is ebp + 8 (KernelBase.dll)
call myCallback; // call my callback to print the string
popfd;
popad;
jmp [dwRetAddr]; // jump back to next instruction so execution continues
}
}
int _tmain(int argc, _TCHAR* argv[]){
printf("OutputDebugStringA address is: %8X\nPress any key to hook...", dwAddr);
system("pause > nul");
MakeJMP((BYTE*) dwAddr, (DWORD) My_OutputDebugStringA, 5);
puts("Hooked. Press any key to call it...\n");
system("pause > nul");
printf("Calling OutputDebugStringA (%8X) with \"hi\"\n", dwAddr);
OutputDebugStringA("hi");
//puts("Called\n");
//system("pause");
return 0;
}
void myCallback(LPCSTR s){
printf("\n===Inside hook!===\nParam address is %8X", &s);
}
void MakeJMP(BYTE *pAddress, DWORD dwJumpTo, DWORD dwLen){
DWORD dwOldProtect, dwBkup, dwRelAddr;
VirtualProtect(pAddress, dwLen, PAGE_EXECUTE_READWRITE, &dwOldProtect);
dwRelAddr = (DWORD)(dwJumpTo - (DWORD)pAddress) - 5;
*pAddress = 0xE9;
*((DWORD *)(pAddress + 0x1)) = dwRelAddr;
for (DWORD x = 0x5; x < dwLen; x++) *(pAddress + x) = 0x90;
VirtualProtect(pAddress, dwLen, dwOldProtect, &dwBkup);
return;
}
Моя функция вызывается, например:
Однако там он ломается, и я получаю исключение:
И это приводит меня к файлу fflush.c
:
Я проверяю, что есть у 0x77020c02
(из исключения), и вижу это:
Судя по последнему изображению, я предполагаю, что это может быть проблема с восстановлением контекста и / или очисткой, но... честно говоря, я понятия не имею, почему это происходит, я раньше подключал такие функции (не окна), и я не было проблем.
Примечание: я не использую такие хуки в реальном коде, я просто пытаюсь сделать это без внешней помощи, такой как MS Detours.
Я немного новичок, поэтому любое объяснение будет очень признательно. :)
ebp
,ebp+4
иebp+8
(этот должен быть хорошим), но когда я смотрю на напечатанные адреса в памяти, я вижу случайный мусор вместо строки, которую я передал. - person rev   schedule 04.07.2014