Io uso il seguente codice:
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;
si implementa il tuo gancio/patch/deviazione chiamando RedirectProcedure
:
RedirectProcedure(@LoadResourceModule, @MyLoadResourceModule);
questo lavoro per codice a 32 bit. Funzionerà anche per il codice a 64 bit purché sia le vecchie che le nuove funzioni risiedano nello stesso modulo eseguibile. In caso contrario, la distanza di salto potrebbe superare l'intervallo di un numero intero a 32 bit.
Sarei molto interessato se qualcuno potesse fornire un'alternativa che funzionasse per lo spazio di indirizzamento a 64 bit, a prescindere da quanto distanti fossero i due indirizzi.
fonte
2012-01-23 20:43:09
Questo si chiama 'detour' controllare questa domanda [Come modificare la realizzazione (deviazione) di una funzione dichiarata esterno] (http://stackoverflow.com/questions/6905287/ come cambiare l'implementazione-deviazione di una funzione dichiarata esternamente) – RRUZ
Oggi stavo pensando allo stesso modo, quindi l'utilizzo di questa tecnica consentirebbe ad esempio di aggiungere codice nello streaming dei componenti (da DFM alla domanda) meccanismo? Così, per esempio, potrei avere un posto centrale per registrare le classi di componenti usate, o fare qualche controllo di qualità ('non usare le classi BDE o quella vecchia versione del componente X!')? – mjn
@mjn Ci sono altri punti di estensione che consentono di farlo più facilmente. Ad esempio 'TReader.OnFindComponentClass'. Il codice di patching dovrebbe essere sempre l'ultima risorsa quando nient'altro può portare a termine il lavoro. –