У меня есть шаблон, который найдет последовательность байтов в области памяти.
0x74, 0x26, 0x48, 0x8B, 0x05, 0, 0, 0, 0, 0x48, 0x8D, 0x0D, 0, 0, 0, 0
Где 0 – его можно заполнить любым байтом. Он работает нормально.
По сути, эти байты дают мне
.text:000000014002AD99 74 26 jz short loc_14002ADC1
.text:000000014002AD9B 48 8B 05 86 D1 64 01 mov rax, qword_141677F28
Вопрос в том, как мне получить qword_141677F28
с адреса 14002AD99?
В 32-битном приложении мне удалось сделать что-то вроде этого:
000000014002AD9B+2. И тут я получил тот адрес, который мне был нужен, но в х64 битной версии он работает немного по-другому. Я не получаю правильный результат и вместо qword_14167777F28
получаю совершенно неправильный результат.
В памяти адрес после qword_
правильный. Это дает мне то, что я хотел, но что мне делать?
Нужно ли мне анализировать ассемблерный код или есть какой-то другой способ получить 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);
}```
не существует таких вещей, как 64- или 32-битные приложения
Вам нужно прочитать 4-байтовое смещение по смещению 5, затем добавить базовый адрес и длину двух инструкций: 14002AD99 + 164D186 + 2 + 7 = 141677F28
Что-то вроде этого:
int32_t disp = *(int32_t*)((uint8_t*)address + 5);
std::cout << std::hex << (uint64_t)address + disp + 2 + 7;
Бро, ты легенда. Благодарю вас <3
Итак, вы хотите знать, как процессор понимает, на какой адрес перейти, когда он видит инструкцию JZ SHORT?