【问题标题】:Inject dll, and call procedure from this dll注入dll,并从此dll调用过程
【发布时间】:2016-02-13 17:09:17
【问题描述】:

inject dll in another process已经出现了,但是还需要调用这个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;

谢谢

【问题讨论】:

  • 不在 DllMain 中显示 UI。调用 CreateThread 并在那里完成工作。
  • 我,我需要从主应用调用 setHWND
  • 好吧,就这样吧。但不是来自 DllMain。正如文档所涵盖的那样。在 DllMain 中调用 CreateThread 来完成这项工作。

标签: delphi winapi dll


【解决方案1】:

正如旧/新事物中所解释的那样。你不能在 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 加载和死锁的风险,但是您仍然不能在线程中调用同步。
如果要同步,则必须创建另一个线程并在那里同步。

【讨论】:

    【解决方案2】:

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

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

    使用 Windows 调用约定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-07
      • 1970-01-01
      • 2013-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多