uso el siguiente código:
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;
implementarías su gancho/parche/desvío llamando RedirectProcedure
:
RedirectProcedure(@LoadResourceModule, @MyLoadResourceModule);
Esto funcionará para código de 32 bits. También funcionará para el código de 64 bits siempre que las funciones antiguas y nuevas residan en el mismo módulo ejecutable. De lo contrario, la distancia de salto puede exceder el rango de un entero de 32 bits.
Me interesaría mucho si alguien pudiera proporcionar una alternativa que funcionara para el espacio de direcciones de 64 bits, independientemente de lo lejos que estuvieran las dos direcciones.
Esto se llama 'detour' comprobar esta pregunta [Cómo cambiar la aplicación (desvío) de una función declarada externamente] (http://stackoverflow.com/questions/6905287/ how-to-change-the-implementation-detour-of-an-externally-declarated-function) – RRUZ
Estaba pensando en lo mismo hoy, así que usar esta técnica permitiría, por ejemplo, agregar código en la transmisión de componentes (desde DFM a la aplicación) mecanismo? Entonces, por ejemplo, podría tener un lugar central para registrar las clases de componentes usados, o hacer alguna garantía de calidad ('¡no use clases de BDE! O esa versión anterior del componente X!'). – mjn
@mjn Hay otros puntos de extensión que permiten hacer eso más fácilmente. Por ejemplo 'TReader.OnFindComponentClass'. El código de aplicación siempre debe ser un último recurso cuando nada más puede hacer el trabajo. –