Я пытаюсь перенаправить TObject.AfterConstruction на другую процедуру, используя приведенный ниже код, но через некоторое время начинает возникать множество исключений. Примечание. :Я использую этот тип перенаправления во многих других решениях.
unit Unit109;
interface
uses
Windows;
implementation
uses
SyncObjs, SysUtils;
type
PJump = ^TJump;
TJump = packed record
OpCode: Byte;
Distance: Pointer;
end;
TObjectHack = class(TObject)
public
procedure AfterConstruction;
end;
function GetMethodAddress(AStub: Pointer): Pointer;
const
CALL_OPCODE = $E8;
begin
if PBYTE(AStub)^ = CALL_OPCODE then
begin
Inc(Integer(AStub));
Result := Pointer(Integer(AStub) + SizeOf(Pointer) + PInteger(AStub)^);
end
else
Result := nil;
end;
procedure AddressPatch(const ASource, ADestination: Pointer);
const
JMP_OPCODE = $E9;
SIZE = SizeOf(TJump);
var
NewJump: PJump;
OldProtect: Cardinal;
begin
if VirtualProtect(ASource, SIZE, PAGE_EXECUTE_READWRITE, OldProtect) then
begin
NewJump := PJump(ASource);
NewJump.OpCode := JMP_OPCODE;
NewJump.Distance := Pointer(Integer(ADestination) - Integer(ASource) - 5);
FlushInstructionCache(GetCurrentProcess, ASource, SizeOf(TJump));
VirtualProtect(ASource, SIZE, OldProtect, @OldProtect);
end;
end;
procedure OldAfterConstruction;
asm
call TObject.AfterConstruction;
end;
{ TCriticalSectionHack }
procedure TObjectHack.AfterConstruction;
begin
end;
initialization
AddressPatch(GetMethodAddress(@OldAfterConstruction), @TObjectHack.AfterConstruction);
end.
Может быть, AfterConstruction хранится в VMT (vmtAfterConstruction = -28 )и его нужно изменить другим способом? например:
PatchCodeDWORD(PDWORD(Integer(Self) + vmtAfterConstruction), DWORD(@TObjectHack.AfterConstruction));
procedure PatchCodeDWORD(ACode: PDWORD; AValue: DWORD);
var
LRestoreProtection, LIgnore: DWORD;
begin
if VirtualProtect(ACode, SizeOf(ACode^), PAGE_EXECUTE_READWRITE, LRestoreProtection) then
begin
ACode^ := AValue;
VirtualProtect(ACode, SizeOf(ACode^), LRestoreProtection, LIgnore);
FlushInstructionCache(GetCurrentProcess, ACode, SizeOf(ACode^));
end;
end;
Я пробовал оба способа, но безуспешно, кто-нибудь может мне помочь?
Если кто-то хочет прочитать об этих подходах:
Tks