我有可以在内存区域中找到字节序列的模式。
0x74、0x26、0x48、0x8B、0x05、0、0、0、0、0x48、0x8D、0x0D、0、0、0、0
其中 0 - 可以用任何字节填充。 效果很好。
基本上这些字节给了我
.text:000000014002AD99 74 26 jz 短 loc_14002ADC1
.text:000000014002AD9B 48 8B 05 86 D1 64 01 mov rax, qword_141677F28
问题是如何从14002AD99地址获取qword_141677F28?
在 x32 位应用程序中,我能够执行类似的操作: 000000014002AD9B + 2。然后我得到了我需要的地址,但在 x64 位中它的工作方式有点不同。我没有得到正确的结果,而是得到了完全错误的结果,而不是 qword_14167777F28。
内存中qword_之后的地址是正确的。它给了我我想要的东西,但我该怎么办? 我需要解析asm代码还是有其他方法来获取qword_141677F28?
DWORD WINAPI thread(_In_ LPVOID core)
{
AllocConsole();
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
std::vector<BYTE> pattern{ 0x74, 0x26, 0x48, 0x8B, 0x05, 0, 0, 0, 0, 0x48, 0x8D, 0x0D, 0, 0, 0, 0 };
uintptr_t* address = get_address<uintptr_t*>(pattern, "xrEngine.exe");
std::cout << std::hex << address + 5; // wrong result
std::cin.get();
FreeLibraryAndExitThread(static_cast<HMODULE>(core), 0);
}```
您需要读取偏移量5处的4字节位移,然后将基址和两条指令的长度相加:
14002AD99 + 164D186 + 2 + 7 = 141677F28
类似这样的:
uint32_t disp = *(uint32_t*)((uint8_t*)address + 5);
std::cout << std::hex << (uint32_t)address + disp + 2 + 7;