Я использую следующий код:
procedure PatchCode(Address: Pointer; const NewCode; Size: Integer);
var
OldProtect: DWORD;
begin
if VirtualProtect(Address, Size, PAGE_EXECUTE_READWRITE, OldProtect) then
begin
Move(NewCode, Address^, Size);
FlushInstructionCache(GetCurrentProcess, Address, Size);
VirtualProtect(Address, Size, OldProtect, @OldProtect);
end;
end;
type
PInstruction = ^TInstruction;
TInstruction = packed record
Opcode: Byte;
Offset: Integer;
end;
procedure RedirectProcedure(OldAddress, NewAddress: Pointer);
var
NewCode: TInstruction;
begin
NewCode.Opcode := $E9;//jump relative
NewCode.Offset := NativeInt(NewAddress)-NativeInt(OldAddress)-SizeOf(NewCode);
PatchCode(OldAddress, NewCode, SizeOf(NewCode));
end;
Вы реализуете свой ловушку / патч / обход, вызывая RedirectProcedure
:
RedirectProcedure(@LoadResourceModule, @MyLoadResourceModule);
Это будет работать для 32-битного кода.Он также будет работать для 64-битного кода при условии, что и старая, и новая функции находятся в одном исполняемом модуле.В противном случае расстояние перехода может превысить диапазон 32-разрядного целого числа.
Мне было бы очень интересно, если бы кто-нибудь мог предоставить альтернативу, которая работала бы для 64-разрядного адресного пространства, независимо от того, насколько далеко друг от друга были расположены эти адреса.