Конференция "Прочее" » Может кому пригодится
 
  • NoUser © (27.03.16 20:20) [0]
    Был у меня вопрос:
    Зачем там, значит, лишний  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.
 
Конференция "Прочее" » Может кому пригодится
Есть новые Нет новых   [134434   +27][b:0][p:0.001]