Примечание. Это декомпилированный код Ghidra, начало изображения в 0x00400000, поэтому мы работаем с Program.exe+001a0d39 по сравнению с базой изображения. < /p>
005a0d39 01 87 94 ADD dword ptr [EDI + 0x194 ], EAX
01 00 00
< /code>
edi содержит указатель на структуру, и он добавляет значение к смещению 0x194. Чтобы применить изменение. < /p>
Eax и EDI Получите конкретные данные контекста, необходимые для новой функции.005a0d3f 8b cf MOV this ,EDI
< /code>
Таким образом, замена добавления (6 байта) вызовом (5byte) на функцию, определенную в моем файле .dll (запасной байт может стать просто непредвзятымvoid WriteCall(BYTE* location, BYTE* newFunction) {
DWORD oldProtect;
VirtualProtect(location, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
location[0] = 0xE8; // CALL
intptr_t relAddr = (intptr_t)(newFunction - location) - 5;
*reinterpret_cast(location + 1) = static_cast(relAddr);
location[5] = 0x90; // fill spare with NOP
VirtualProtect(location, 6, oldProtect, &oldProtect);
}
< /code>
и, используя чит-двигатель, он, похоже, хорошо выполняет свою работу, новая функция: < /p>
int jump_back;
extern "C" __declspec(dllexport) __declspec(naked) noinl void MyFun_Wrapper() {
__asm { // note: I am usin MCVS
pushfd // Save flags
// Save general-purpose registers
push ebx
push ecx
push edx
push esi
push edi
push ebp
push esp
//we don't need to push the EAX as we need to update it anyway
push edi // param subject to add (2nd parameter)
push eax // param added number (1st parameter)
call MyFun
add esp, 8 // Clean up parameters
pop esp
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
add[edi + 0x194], eax // Update XP with function return value
popfd // Restore flags
jmp jump_back
}
}
< /code>
Jump_back установлен на инструкцию после старого добавления, в данном случае = base + 001a0d3f (она установлена как первая инструкция на DLL_Process_attach < /code>) < /p>
Это то, что Myfun выглядит как:
) < /p>
Это то, что Myfun выглядит:
) < /p>
extern "C" __declspec(dllexport) noinl int __cdecl MyFun(int eax, my::clazz* edi)
Поскольку я делаю некоторые операции по плаванию внутри функций, я также пытался сохранить и загрузить указанные регистры, но безрезультатно. Проблема в том, что после того, как программа продолжает свое обычное выполнение, она сразу после этого вылетает, я подозреваю, что есть что -то, что она не сохранена должным образом, или какой -то шаг я пропустил.>
Примечание. Это декомпилированный код Ghidra, начало изображения в 0x00400000, поэтому мы работаем с Program.exe+001a0d39 по сравнению с базой изображения. < /p> [code]005a0d39 01 87 94 ADD dword ptr [EDI + 0x194 ], EAX 01 00 00 < /code> edi содержит указатель на структуру, и он добавляет значение к смещению 0x194. Чтобы применить изменение. < /p> Eax и EDI Получите конкретные данные контекста, необходимые для новой функции.005a0d3f 8b cf MOV this ,EDI < /code> Таким образом, замена добавления (6 байта) вызовом (5byte) на функцию, определенную в моем файле .dll (запасной байт может стать просто непредвзятымvoid WriteCall(BYTE* location, BYTE* newFunction) { DWORD oldProtect;
VirtualProtect(location, 6, oldProtect, &oldProtect); } < /code> и, используя чит-двигатель, он, похоже, хорошо выполняет свою работу, новая функция: < /p> int jump_back; extern "C" __declspec(dllexport) __declspec(naked) noinl void MyFun_Wrapper() { __asm { // note: I am usin MCVS pushfd // Save flags
// Save general-purpose registers push ebx push ecx push edx push esi push edi push ebp push esp //we don't need to push the EAX as we need to update it anyway
push edi // param subject to add (2nd parameter) push eax // param added number (1st parameter) call MyFun add esp, 8 // Clean up parameters
pop esp pop ebp pop edi pop esi pop edx pop ecx pop ebx
add[edi + 0x194], eax // Update XP with function return value
popfd // Restore flags
jmp jump_back }
} < /code> Jump_back установлен на инструкцию после старого добавления, в данном случае = base + 001a0d3f (она установлена как первая инструкция на DLL_Process_attach < /code>) < /p> Это то, что Myfun выглядит как: ) < /p> Это то, что Myfun выглядит:
) < /p> extern "C" __declspec(dllexport) noinl int __cdecl MyFun(int eax, my::clazz* edi)[/code] Поскольку я делаю некоторые операции по плаванию внутри функций, я также пытался сохранить и загрузить указанные регистры, но безрезультатно. Проблема в том, что после того, как программа продолжает свое обычное выполнение, она сразу после этого вылетает, я подозреваю, что есть что -то, что она не сохранена должным образом, или какой -то шаг я пропустил.>