我正在开发一款在线游戏。我有完整的服务器源代码,但我使用的游戏客户端是封闭源代码,需要一些逆向工程。我正在尝试正确调用draw_rectangle
函数。在下图中,您可以看到OLLY的截图。
有功能:
DRAW_BLACK_BAR(健康栏的黑框),
DRAW_COLORED_BAR(里面的健康状况),
DRAW_NICK(已经上钩)
CALL DWORD PTR DS:[EDX + 14]始终指向0x4EB2F0
因此,addres在调试器中包含该函数:
正如您所看到的,堆栈上有参数,例如Surface_id,位置,大小,颜色和指向生物的指针。
这是我的钩子:
superHook(dwHandle, 0x4C8C28, (unsigned int)newFunc); //instead of call print rectangle func for colored bar
void superHook(HANDLE dwHandle, int adr, unsigned int targetFunction)
{
//its not normal CALL ADDR which takes 5 bytes (E8 + 4x bytes for address)
//It is CALL DWORD PTR DS:[EDX+14] which takes 3bytes, so we will take more space
//and we will rebuild the function
// jmp to address +2x nop
BYTE bytes[7] = { 0xE9, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x90};
DWORD targetAddr = targetFunction - adr - 5;
*(DWORD*)(bytes + 1) = targetAddr;
WriteProcessMemory(dwHandle, (void *)adr, bytes, 7, NULL);
}
void newFunc()
{
//Rebuild the function (Earsed commands to be able to put JMP address)
__asm {
MOV ECX, DWORD PTR SS : [EBP - 0x18]
PUSH ESI
}
//Here I can access all the registers and stack before CALL will be executed
//call draw rectangle
__asm {
CALL DWORD PTR DS : [EDX + 0x14]//always call 0x4EB2F0?
}
//go back
__asm {
PUSH 0x4C8C2F
RET
}
}
它工作正常,因为我可以访问堆栈上的参数并修改它们(更改颜色,大小,位置等)。但是,我希望能够创建另一个矩形,例如下一个具有另一种颜色和位置的矩形。我尝试了很多组合设置新的堆栈,参数调用func然后再用原始的调用它,但我总是最终导致客户端崩溃。
这是我尝试创建新呼叫+恢复旧呼叫的示例之一 https://pastebin.com/RUmaPGya(pastebin不能使这篇文章太长)