注入dll,并从此dll调用过程

时间:2016-02-13 17:09:17

标签: delphi winapi dll

在另一个进程中注入dll已经横空出世,但仍然需要在这个dll中调用该函数,如何实现呢? 但更具体地说,在注入过程之后,我需要调用setHWND函数来发送值,从我的应用程序到注入过程...

切片dll

 procedure Init(Reason: integer);
    begin
      Dll_reason := Reason;
      HookPoint_Address := 0;
      if (Reason = DLL_PROCESS_ATTACH) then
      begin
        ShowMessage('Прикрепились');
        InitHook;
      end;
    end;

    procedure setHWND(hwnd: Cardinal);
    begin
     hwnd_param:=hwnd;
    end;

    exports
      setHWND;

    begin
      DLLProc := Init;
      Init(DLL_PROCESS_ATTACH);

切片注射器

function InjectDLL(dwPID: DWORD; DLLPath: PWideChar): integer;
var
  dwThreadID: Cardinal;
  hProc, hThread, hKernel: THandle;
  BytesToWrite, BytesWritten: SIZE_T;
  pRemoteBuffer, pLoadLibrary: Pointer;
begin
  hProc := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or
    PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False, dwPID);
  if hProc = 0 then
    exit(0);
  try
    BytesToWrite := SizeOf(WideChar) * (Length(DLLPath) + 1);
    pRemoteBuffer := VirtualAllocEx(hProc, nil, BytesToWrite, MEM_COMMIT,
      PAGE_READWRITE);
    if pRemoteBuffer = nil then
      exit(0);
    try
      if not WriteProcessMemory(hProc, pRemoteBuffer, DLLPath, BytesToWrite,
        BytesWritten) then
        exit(0);
      hKernel := GetModuleHandle('kernel32.dll');
      pLoadLibrary := GetProcAddress(hKernel, 'LoadLibraryW');
      hThread := CreateRemoteThread(hProc, nil, 0, pLoadLibrary, pRemoteBuffer,
        0, dwThreadID);
      try
        WaitForSingleObject(hThread, INFINITE);
      finally
        CloseHandle(hThread);
      end;
    finally
      VirtualFreeEx(hProc, pRemoteBuffer, 0, MEM_RELEASE);
    end;
  finally
    CloseHandle(hProc);
  end;
  exit(1);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  PID: DWORD;
  dir: string;
begin
  SetSeDebugPrivilege;
  PID := GetPID('zorron.exe');
  if (PID > 0) then
  begin
    dir := GetCurrentDir;
    InjectDLL(PID, PWideChar(dir + '\trans.dll'));
  end;

end;

THX

2 个答案:

答案 0 :(得分:0)

正如旧/新事物中所解释的那样。你不能在DllMain功能中做真正的工作 如果您执行此操作并且在DllMain忙碌时应用程序停止,应用程序将会死锁 DllMain中的许多其他活动也可能导致死锁,请参阅:https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971%28v=vs.85%29.aspx

这就是为什么你要创建一个新主题使用CreateThread
只记得不同步你的线程,因为这会导致死锁。只要你不同步,你就是金。

注入dll之后,就会启动一个新线程,如下所示:

procedure DoWorkInDLL(data: pointer): bool; stdcall;
begin
  ...
end;

procedure EntryPoint(Reason: dword);
var
  ThreadID: cardinal;
begin
  if Reason = DLL_PROCESS_ATTACH then begin
    Win32Check(CreateThread(nil,0, @Main, nil, 0, ThreadId));
  end;
  Assert(ThreadID <> 0);
end;


begin
  DLLProc:= @EntryPoint;
  EntryPoint(DLL_PROCESS_ATTACH);
end.

我现在的文档所以不要使用CreateThread,但实际上只是同步问题才是问题。
这里的问题是通常应用程序启动dll,但是当你注入一个dll时,情况绝对不是这样,因此你必须调整你的参考点。 在DoWork函数内部,您可以调用SetHWnd,因为您现在已经脱离了dll加载和死锁的风险,但是您仍然无法在线程内调用同步。
如果要进行同步,则必须创建另一个线程并在那里进行同步。

答案 1 :(得分:0)

如果需要导出setHWND(),请确保使用stdcall指令

procedure setHWND(hwnd: Cardinal); stdcall;
begin
 hwnd_param:=hwnd;
end;

使用Windows调用约定。