终于搞定DLL HOOK的问题,注意变量的问题

  • 发布于:2024-02-12
  • 133 人围观
function MsgHookProc(Code: Integer; WParam: Longint;Msg:Longint): LRESULT;stdcall;
  begin
  
   if (Code = HC_ACTION) then
   begin
   if PMsg(Msg)^.Message = WM_LBUTTONDBLCLK then
   PMsg(Msg)^.Message := 0;
  
   if PMsg(Msg)^.Message = WM_LBUTTONUP then
   begin
   WM_USER_LButtonDown := RegisterWindowMessage('Tsinghua Tongfang Carputer Mouse Hook LButtonDown');
   postMessage(DLLData^.Hook,WM_USER_LButtonDown,0,0);
   end;
   end;
   Result :=CallNextHookEx(HookHandle, Code, WParam, Longint(@Msg));
  end;
  
  问题全部出在红色部分,由于全局DLL的实例很多,导致“任何”DLL的内部变量离开了当时的函数都是不可信的,原来我在DLL的init里面注册了该自定义消息,结果在真实的DLL里面(非调用进程HOOK情况下)消息全部都变成了0,所以没有消息发给我的主程序。
  
  这种变量可以现用现取,或者干脆就用定死的WM_USER+1000这种方式。但是如果是那种需要外部传入的参数,必须使用系统提供的共享内存段来保存。
  
  DLL初始化函数里面创建该共享内存段
  
  procedure MyDLLHandler(Reason: Integer);
  var
   FHandle: LongWORD;
  begin
   case Reason of
   DLL_PROCESS_ATTACH:
   begin //建立文件映射,以实现DLL中的全局变量
   FHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,sizeof(TData), 'THTFMMI_DLLDATA');
   if FHandle = 0 then
   if GetLastError = ERROR_ALREADY_EXISTS then
   begin
   FHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'THTFMMI_DLLDATA');
   if FHandle = 0 then Exit;
   end else Exit;
   DLLData := MapViewOfFile(FHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
   if DLLData = nil then
   begin
   windows.Beep(8000,50);
   CloseHandle(FHandle);
   end;
   end;
   DLL_PROCESS_DETACH:
   begin
   if Assigned(DLLData) then
   begin
   UnmapViewOfFile(DLLData);
   DLLData := nil;
   h:=0;
   end;
   end;
   end;
  end;
  
  
  调用者需要映射该共享内存段并设定参数,直接传递参数过来是不行的,除非接受传参的函数里面立刻映射共享内存段并设定。
  
  function TDataModule1.enableHook : boolean;
  var
   FHandle: LongWORD;
   DLLData : PData;
  begin
   result := false;
   FHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'THTFMMI_DLLDATA');
   if Fhandle = 0 then Exception.Create('Cannot open memory map in exe');
   if FHandle > 0 then
   begin
   DLLData := MapViewOfFile(FHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
   if DLLData <> nil then
   begin
   DLLData^.Hook := Application.MainForm.Handle;
   result := EnableMsgHook;
   end
   else
   begin
   Exception.Create('Cannot map memory in exe');
   closehandle(Fhandle);
   end;
   end;
  end;
万企互联
标签: