Я сделал 32-битную тестовую программу и пытаюсь обойти эту функцию (внутренне):
void Function(int number)
{
std::cout << "Your number is: " << number << std::endl;
}
, используя эту функцию обхода (которая вызывает ошибку сегментации SIGSEV в memcpy, даже хотя память действительна и защищена выполнением / чтением / записью):
bool Detour(byte_t* src, byte_t* dst, size_t size)
{
if(size < HOOK_MIN_SIZE) return false;
mprotect(src, size, PROT_EXEC | PROT_READ | PROT_WRITE);
mem_t jmpAddr = ((mem_t)dst - (mem_t)src) - HOOK_MIN_SIZE;
byte_t CodeCave[] = { JMP, 0x0, 0x0, 0x0, 0x0 };
*(mem_t*)((mem_t)CodeCave + sizeof(JMP)) = jmpAddr;
memcpy(src, CodeCave, sizeof(CodeCave));
return true;
}
Она вызывается так:
Detour((byte_t*)&Function, (byte_t*)&hkFunction, HOOK_SIZE);
HOOK_MIN_SIZE равно 5, чтобы соответствовать переходу сборки (0xE9 0x00 0x00 0x00 0x00), а HOOK_SIZE равен 7, поскольку он должен соответствовать всем перезаписанным инструкциям (для батута, но это не имеет значения в этом случае):
Dump of assembler code for function Function(int):
0x5655631d <+0>: push ebp
0x5655631e <+1>: mov ebp,esp
0x56556320 <+3>: push ebx
0x56556321 <+4>: sub esp,0x4
0x56556324 <+7>: call 0x56556220 <__x86.get_pc_thunk.bx>
Ошибка GDB:
Program received signal SIGSEGV, Segmentation fault.
0x565564c9 in Detour (
src=0x5655631d <Function(int)> "U\211\345S\203\354\004\350\367\376\377\377\201\303\367+",
dst=0x56556372 <hkFunction(int)> "U\211\345S\203\354\004\350\242\376\377\377\201â+", size=7) at main.cpp:51
51 memcpy(src, CodeCave, sizeof(CodeCave));
Typedefs:
typedef unsigned int mem_t;
typedef unsigned char byte_t;
В чем проблема с этой функцией обхода? Я уже успешно сделал свой собственный на Windows для 32- и 64-разрядных, но, похоже, он отличается от Linux.