Я знаю, что это длинный пост, но в основном это код и картинки, это быстро читается! Прежде всего, вот что я пытаюсь сделать:
Я пытаюсь выполнить массив BYTE в отключенной функции, чтобы вернуться к исходному коду, как если бы я не обходил anyhting. Вот мой код:
DllMain (DetourAddress все это имеет значение):
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
AllocConsole();
freopen("CONOUT$", "w", stdout);
DetourAddress((void*)HookAddress, (void*)&DetourFunc);
case DLL_PROCESS_DETACH:
FreeConsole();
break;
}
return TRUE;
}
DetourAddress (код ясен сам по себе):
void DetourAddress(void* funcPtr, void* hook)
{
// write jmp
BYTE cmd[5] =
{
0xE9, //jmp
0x00, 0x00, 0x00, 0x00 //address
};
// make memory readable/writable
DWORD dwProtect;
VirtualProtect(funcPtr, 5, PAGE_EXECUTE_READWRITE, &dwProtect);
// read bytes about to be replaced
ReadProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, mem, 5, NULL);
// write jmp in cmd
DWORD offset = ((DWORD)hook - (DWORD)funcPtr - 5); // (dest address) - (source address) - (jmp size)
memcpy(&cmd[1], &offset, 4); // write address into jmp
WriteProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, cmd, 5, 0); // write jmp
// reprotect
VirtualProtect(funcPtr, 5, dwProtect, NULL);
}
DetourFunc:
_declspec(naked) void DetourFunc()
{
__asm
{
PUSHFD
PUSHAD
}
printf("function detoured\n");
__asm
{
POPAD
POPFD
}
// make memory readable/writable
DWORD dwProtect;
VirtualProtect(mem, 6, PAGE_EXECUTE_READWRITE, &dwProtect);
pByteExe();
// reprotect
VirtualProtect(mem, 6, dwProtect, NULL);
__asm
{
jmp HookReturnAddress
}
}
И завершаем глобальные переменные typedef для pByteExe() и включаем:
#include <Windows.h>
#include <cstdio>
DWORD HookAddress = 0x08B1418,
HookReturnAddress = HookAddress+5;
typedef void ( * pFunc)();
BYTE mem[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0xC3 };
pFunc pByteExe = (pFunc) &mem
Как вы можете видеть в DetourFunc, я пытаюсь выполнить мой байтовый массив (mem) напрямую. Используя OllyDbg, это заставляет меня туда:
Это именно те байты, которые я пытаюсь выполнить. Только проблема в том, что она дает мне ошибку нарушения доступа при выполнении... Любая идея, почему? Я бы подумал: "VirtualProtect (mem, 5, PAGE_EXECUTE_READWRITE, & dwProtect); сделало бы его безопасным для доступа... Спасибо за вашу помощь!
EDIT: Я просто понял, что произошло нечто странное... когда я "вступаю" в ollydbg, инструкции mem верны, но, как только я немного прокручу, они снова обращаются к этому:
Любая идея почему?
Вы забыли смещение модуля...
DWORD module = (DWORD)GetModuleHandle(NULL);
DWORD real_address = module + (DWORD)ADDRESS;
АДРЕС должен, конечно, относиться к вашему модулю. (Смещение модуля не всегда одинаково)
И кстати. почему вы берете WriteProcessMemory, когда вы вводите свою DLL? Простой memcpy достаточно...
VirtualProtect
? Также на странице VirtualProtect в MSDN говорится, что нужно вызыватьFlushInstructionCache
после изменения инструкций.