четвер, 7 листопада 2013 р.

Відстеження з середини DLL її приєднання та від'єднання до процесу

Тему про відстеження з середини DLL її приєднання до процесу та від'єднання можна знайти в сотнях статей. Наприклад, детально це розписано в блозі Gunsmoker'а. Але в більшості видно одну й ту ж саму помилку. А саме:


library MyDLL; 

procedure DllMain(Reason: Integer); 
begin 
  { This is called when Reason = DETACH } 
end; 

begin 
  { This executes when a process ATTACHes. } 
  DllProc := @DllMain; 
end. 

Реалізувавши таким чином бібліотеку можна бути впевненим, що основний код бібліотеки буде викликаний 4 рази на подіях:
  • DLL_PROCESS_ATTACH = 1; // Executable attaches to DLL
  • DLL_THREAD_ATTACH = 2; // Thread in exe calls DLL
  • DLL_THREAD_DETACH = 3; // Thread leaves DLL
  • DLL_PROCESS_DETACH = 0; // Exe detaches from DLL
Відповідно, присвоєння DllProc := @DllMain також буде викликано 4 рази, при цьому вказівник на DllMain може бути втрачено. Тому варто його зберегти, а при виході з бібліотеки відновити:


library MyDLL; 

uses ...;

var
  OldDllProc : TDLLProc;

procedure DllMain(Reason: Integer);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
      begin
        OldDllProc := @DllProc;
        DllProc    := @MyProc;
      end;
    DLL_PROCESS_DETACH:
      begin
        DllProc := OldDllProc;
      end;
  end;
end;

begin
  if (DllProc = nil) then
    DllMain(DLL_PROCESS_ATTACH);
end.


Таким чином можна уникнути втрат пам'яті та виконання зайвого або навіть шкідливого в даній ситуації коду.

Немає коментарів :

Дописати коментар