-
Был у меня вопрос: Зачем там, значит, лишний mov ( и в debug и в release) System.pas.15974: begin
00404768 53 push ebx
00404769 8BD8 mov ebx,eax
System.pas.15975: Result := InitInstance(_GetMem(InstanceSize));
0040476B 8BC3 mov eax,ebx 0040476D E826000000 call TObject.InstanceSize
и тут, думая “Как жить дальше? [22]”, в голове звучит фраза: * 5 байт, 5! Карл! * )) uses Windows, SysUtils;
type TInstanceIntercept = class sealed private procedure AfterNew; procedure BeforeFree; class procedure Init; static; end;
class procedure TInstanceIntercept.Init; type TJp = packed record Op:Byte; Offset:NativeInt; end; const cJ = SizeOf(TJp);
procedure Jmpp(pN, pF : NativeInt); var Bp : ^TJp; Jp : TJp; Mp : Cardinal; begin Jp.Op := $E9;
Bp := @TObject.NewInstance; Jp.Offset := pN - NativeInt(Bp) - cJ; VirtualProtect(Bp, cJ, PAGE_EXECUTE_READWRITE, Mp); Bp^ := Jp; VirtualProtect(Bp, cJ, Mp, nil);
Bp := @TObject.FreeInstance; Jp.Offset := pF - NativeInt(Bp) - cJ; VirtualProtect(Bp, cJ, PAGE_EXECUTE_READWRITE, Mp); Bp^ := Jp; VirtualProtect(Bp, cJ, Mp, nil); end;
label pNI, pNew, pFree; asm lea eax, pNew lea edx, pFree call Jmpp ret // pNI: push ebx mov ebx,eax jmp TObject.NewInstance + cJ pNew: call pNI push eax call AfterNew pop eax ret // pFree: push ebx push ecx push edx push eax call BeforeFree pop eax pop edx pop ecx mov ebx,eax jmp TObject.FreeInstance + cJ end;
procedure TInstanceIntercept.AfterNew; begin OutputDebugString( PChar('Ctor '+ Self.ClassType.ClassName + ' $' + IntToHex(NativeInt(Self), SizeOf(Pointer)*2) ) ); end;
procedure TInstanceIntercept.BeforeFree; begin OutputDebugString( PChar('Dtor '+ Self.ClassType.ClassName + ' $' + IntToHex(NativeInt(Self), SizeOf(Pointer)*2) ) ); end;
begin TInstanceIntercept.Init;
try TObject.Create.Free; except end; end.
|