как я уже упоминал - "портировано 1 к 1 с с++":
получение указателя на экземпляр UNetworkHandler'а
Код:
UNetworkHandler: Pointer
//UNetworkHandler_Init
procedure UNetworkHandlerInit_hook();
asm
mov UNetworkHandler, ecx //сохраняем указатель на экземпляр
MOV EAX,DWORD PTR FS:[0] //
jmp DWORD PTR initUH_orig //прыгаем в оригинальную
end;
внедрение кода (ставим свои адреса и радуемся)
Код:
function InitThread(lpParameter: pointer):dword;// stdcall;
begin
//подождать engine.dll, и начать внедрение своего кода
repeat
Sleep(100);
until (GetModuleHandleA('engine.dll')<>0);
buf := DWORD(@UNetworkHandlerInit_hook);
//тут магия, хардкод и шанс попортить регистры.
initUH_orig:=Engine+$003B2D96;
comm :=$e9;
// Обычно страницы в этой области недоступны для записи
// поэтому принудительно разрешаем запись
VirtualProtect(ptr(Engine+$003B2D90),5,PAGE_READWRITE, @op);
//вычисляем смещение которое запишем в джамп
offset := buf - (Engine+$003B2D90 + 5);
// Пишем новый адрес
// нужно писать СМЕЩЕНИЕ!
WriteProcessMemory(GetCurrentProcess(), ptr(Engine+$003B2D90),@comm,1,written);
WriteProcessMemory(GetCurrentProcess(), ptr(Engine+$003B2D90+$01),@offset,4,written);
end;
"DLL Main"
Код:
procedure DLLEntryPoint(dwReason: DWORD); export;
var
ThreadId:dword;
begin
case dwReason of
DLL_PROCESS_ATTACH:
begin
CreateThread(nil,0,@ InitThread,nil,0,ThreadId);
end;
DLL_PROCESS_DETACH:
begin
end;
end
end;
все это "хардкод", "дурной тон" и "так нельзя"
и не забываем все действия десять раз перепроверить в отладчике.