Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Delphi: Разработка компонентов > Вызов _AfterConstruction


Автор: 0day 08.03.12, 11:54
А все ли объекты вызывают System._AfterConstruction ?

Автор: ViktorXP 08.03.12, 12:05
да.
пс. Если более правильно выразится то эта функция взывает метод AfterConstruction у объекта. компилятор просто "расставляет" ее в нужном месте. (точно также как и неявное выделение/освобождение памяти строк/динамических массивов)

Автор: 0day 08.03.12, 12:18
Да точно!)

Кому интересно накидал код, выводит имена создаваемых классов.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    type
      PEXCEPTION_POINTERS = ^EXCEPTION_POINTERS;
      EXCEPTION_POINTERS = packed record
         ExceptionRecord :^EXCEPTION_RECORD;
         ContextRecord   :PCONTEXT;
    end;
     
    function AddVectoredExceptionHandler(FirstHandler:ULONG; VectoredHandler:Pointer):pointer;stdcall; external 'kernel32.dll';
    var
     Ref:integer = 0;
     
    function OnAfterConstruction(obj:TObject): TObject;
    begin
     
      if ( Ref = 0 ) then
      begin
       Inc(Ref);
        obj.AfterConstruction;
        ShowMessage(obj.ClassName);
       Dec(Ref);
      end;
     
      result:=obj;
    end;
     
     
    FUNCTION VectoredHandler( ExceptionInfo:PEXCEPTION_POINTERS):ULONG;stdcall;
    var
     p:Pointer;
    begin
      Result:=0;
      if ( ExceptionInfo^.ExceptionRecord^.ExceptionCode = EXCEPTION_SINGLE_STEP ) then
      begin
        p :=PWORD( ExceptionInfo^.ContextRecord^.Eip);
        if ( PBYTE(PChar(p)-1)^ = $F1) and ( PBYTE(PChar(p))^ = $C3) then
        begin
         ExceptionInfo^.ContextRecord^.Eip := Cardinal(@OnAfterConstruction);
         result:=$ffffffff;
        end;
      end;
     
    end;
     
     
    var
      ptr:pointer;
      Attr:Cardinal;
      ObjRef:TObjectRef;
    begin
     
      FindTypeInfoObject( pointer($401000),ObjRef );
      ptr:= GetVMTItem(ObjRef.VMT,MetodAfterConstruction);
      AddVectoredExceptionHandler(1,@VectoredHandler);
      VirtualProtect(ptr,sizeof(ptr),PAGE_EXECUTE_READWRITE,@Attr);
        PWord(ptr)^ := $C3F1;
      VirtualProtect(ptr,sizeof(ptr),Attr,@Attr);
     
      Application.Initialize;
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end.

Projects.rar (, : 252)

Добавлено
Версия однопоточная, для нескольких потоков нужно юзать TLS для переменной Ref.
Работает для 7 версии дельфи.
При запущенном отладчике дельфи работать не будет.

Автор: ViktorXP 08.03.12, 21:03
это получается что если я создам объект в AfterConstruction то его же собственный AfterConstruction не вызовется.

Автор: 0day 09.03.12, 08:53
ViktorXP
Цитата ViktorXP @
это получается что если я создам объект в AfterConstruction то его же собственный AfterConstruction не вызовется.

Почему? покажи пример.

Там перехват у TObject.AfterConstruction который сам по себе пустой метод.
Так как твой объект будет наследоваться от TObject то AfterConstruction твоего обьекта должна быть вызвана.

Автор: ViktorXP 09.03.12, 17:33
Цитата 0day @
var
 Ref:integer = 0;
 
function OnAfterConstruction(obj:TObject): TObject;
begin
 
  if ( Ref = 0 ) then
  begin
   Inc(Ref);
    obj.AfterConstruction;
    ShowMessage(obj.ClassName);
   Dec(Ref);
  end;
 
  result:=obj;
end;

после инкремента Ref, уловие не будет срабатывать и соответственно все объекты которые будут порождены в период от инкремента до декремента будут отрабатывать мимо этого куска кода. соответственно obj.AfterConstruction для их не вывозется

Автор: 0day 09.03.12, 20:54
ViktorXP
В целом AfterConstruction вроде как можно и не вызывать даже, там все равно ret.
Тоесть AfterConstruction у TObject все равно пустой метод.
я не прав?

А не подскажите почему TForm не вызывает AfterConstruction ?

Автор: leo 10.03.12, 08:55
Цитата 0day @
В целом AfterConstruction вроде как можно и не вызывать даже, там все равно ret.

У TObject - да, а у той же TCustomForm и ее наследниках - во-первых, не пустой, во-вторых, не вызывает inherited, поэтому твой код для TForm и не работает. А если бы был вызов inherited, то твой OnAfterConstruction мог бы "наломать дров" из-за повторногом вызова obj.AfterConstruction

Автор: 0day 10.03.12, 17:21
А в каком случаи вызывается NewInstance ? При выделении под класс памяти ?

Автор: leo 11.03.12, 04:32
Да

PS: Интересно, для чего ты FindTypeInfoObject юзаешь - для инжекта в сторонний процесс или exe? Малварь изобретаешь или свою навесную защиту и т.п.?

Автор: 0day 11.03.12, 06:06
нужно немного изменить поведение программы, с закрытыми исходниками.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)