先说下我的目的:有程序A和B,程序A运行时将DLL注入程序B,DLL作用是监控A的运行,如果A被关闭那就结束B现在向B注入DLL实现了我想要问的就是如何在注入DLL时传入A的PID,或者说有什么好的办法监控A不被关闭,用findwindow肯定不行的吧,有同名的窗体就检测不到了
DLL监控代码library TestDll;uses
  Windows,
  Classes,
  MMSystem;type
  TCFThread = class(TThread)
  private
    timerid:integer;
    htimerevent:Thandle;
  protected
    procedure Execute; override;
  public
    constructor Create();
    procedure SetOver;
    destructor Destroy(); override;
  published
  end;{$R *.res}constructor TCFThread.Create();
begin
  FreeOnTerminate := True;
  inherited Create(False);
end;procedure TCFThread.SetOver;
begin
  timerid := timesetevent(5, 0, TFNTimecallback(htimerevent), 0, time_periodic or time_callback_event_set);
end;destructor TCFThread.Destroy();
begin
  inherited Destroy;
end;procedure TCFThread.Execute;
begin
  htimerevent := CreateEvent(nil, False, False, nil);
  timerid := timesetevent(5*1000, 0, TFNTimecallback(htimerevent), 0, time_periodic or time_callback_event_set);
    repeat
      if WaitForSingleObject(htimerevent,INFINITE) = WAIT_OBJECT_0 then
      begin
        if Terminated then break;
        MessageBox(0,'测试!','DLL注入成功',0);
      end;
    until false;
  timekillevent(timerid);
  CloseHandle(htimerevent);
end;var
  Thread: TCFThread;
begin
  Thread := TCFThread.Create();
end.

解决方案 »

  1.   

    注入部分: 这个是注入的记事本
    var
      h: LongWord; //放句柄,中间顺便放下pid。
      tmp: LongWord;  //占格式,收集垃圾。
      DllName: PAnsiChar;
      MySize: LongWord; //放字符串长度。
      Parameter: Pointer; //放参数的指针(位置在目标进程内)
    begin
      DllName:='TestDll.dll';
      MySize:=StrLen(DllName)+1;
      WinExec('notepad',1);
      GetWindowThreadProcessId(FindWindow('notepad',nil),@h);
      h:=OpenProcess(PROCESS_ALL_ACCESS,False,h);
      Parameter:=VirtualAllocEx(h,nil,MySize,MEM_COMMIT,PAGE_READWRITE);
      WriteProcessMemory(h,Parameter,Pointer(DllName),MySize,tmp);
      CreateRemoteThread(h,nil,0,GetProcAddress(GetModuleHandle('KERNEL32.Dll'),'LoadLibraryA'),Parameter,0,tmp);
    end;
      

  2.   

    可以使用消息广播
    var 
      TestMsg:UINT;TestMsg:=RegisterWindowMessage('测试);
    PostMessage(HWND_BROADCAST,TestMsg,0,0);
    procedure TForm1.HandleMessage(var Msg:tagMSG;var Handle:Boolean);
    begin
      if Msg.message=TestMsg then
        begin
          //
        end;
    end;
      

  3.   

    你搜索下  PostMessage(HWND_BROADCAST 
    相关的   进程之间互相定时发送 然后等待回复
      

  4.   

    消息广播那个  在DLL内接收广播吗?
      

  5.   

    既然B程序不是你寫的,可試著傳入A的進程或進程ID...
      

  6.   

    to kye_jufei我这个帖子就是在问如何传过去啊
      

  7.   

    用共享内存已经实现了数据的传递现在的问题是 传递的PID值,传过去读取到的也是正确的  可是检测ProcessHandle := OpenProcess(PROCESS_DUP_HANDLE, FALSE, Pid);  结果不正确
      

  8.   

    設置斷點跟蹤一下代碼,如果實在不行,可在B程序時根據A的進程名來取A的PID:(你自己研究一下)
      uses
    TLhelp32;
    Function GetPID(_GetPID:String):String;
    var
         h:thandle;
         f:boolean;
         lppe:tprocessentry32;
    begin
         h := CreateToolhelp32Snapshot(TH32cs_SnapProcess, 0);
         lppe.dwSize := sizeof(lppe);
         f := Process32First(h, lppe);     //lppe.szExeFile是進程的名字,自己挑選你要的
         //lppe.th32ProcessID就是你要的進程號
         while integer(f) <> 0 do
         begin
           //if lppe.szExeFile='QQ.exe' then showmessage('ok');
           if lppe.szExeFile = _GetPID then
           begin
             Result:=(inttostr(lppe.th32ProcessID));
             break;
           end;
           f := Process32Next(h, lppe);
         end;
    end;
      

  9.   

    不難,如果你僅僅想通過 遠端 DLL 來判斷 A 是否還在運行,可以這樣做。在 A 和 DLL 中同時定義一個 相同內容的 互斥變量。A 啟動以後,建立該 互斥變量,然後注入 DLL ,關閉時同時註銷該 互斥變量。DLL 在運行期採用線程循環測試該 互斥變量 是否存在,不存在則說明 A 已經被關閉。
      

  10.   

    互斥的方式确实可以  感谢mysterx提供思路