首页 文章

delphi xe3 dll注入64位dll到64位进程不起作用

提问于
浏览
3

我正在使用此代码将我的64位dll注入到Windows 7 64位的64位进程中,CreateRemoteThread返回200但仍然没有注入dll,我用另一个源测试了我的dll并且它工作正常,Process Explorer显示我的代码不起作用,这个代码有什么问题,我正在使用delphi XE3,我已经在64位目标平台上编译代码 .

function InjectDLL(dwPID: DWORD; DLLPath: pwidechar): integer;
var
dwThreadID: Cardinal;
hProc, hThread, hKernel: NativeUInt;
BytesWritten: NativeUInt;
pRemoteBuffer, pLoadLibrary: Pointer;
begin
try
hProc := OpenProcess(PROCESS_ALL_ACCESS, False, dwPID);
if hProc = 0 then
begin
  Result := 0;
  Exit;
end;
pRemoteBuffer := VirtualAllocEx(hProc, nil, Length(DLLPath) + 1, MEM_COMMIT,
  PAGE_READWRITE);
if pRemoteBuffer = nil then
begin
  Result := 0;
  Exit;
end;
if WriteProcessMemory(hProc, Pointer(pRemoteBuffer), lpvoid(DLLPath),
  Length(DLLPath) + 1, BytesWritten) = False then
begin
  Result := 0;
  Exit;
end;
hKernel := GetModuleHandle(pwidechar('kernel32.dll'));
pLoadLibrary := (GetProcAddress(hKernel, pansichar('LoadLibraryA')));
hThread := CreateRemoteThread(hProc, Pointer(nil), 0, Pointer(pLoadLibrary),
  Pointer(pRemoteBuffer), 0, dwThreadID);

WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProc, Pointer(pRemoteBuffer), Length(DLLPath) + 1,
  MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProc);
// ShowMessage(IntToStr(hThread)+' '+ inttostr(dwThreadID));
Result := 1;
except
on d: exception do
begin
end;
end;
end;

1 回答

  • 4

    您正在调用 LoadLibraryA ,但将UTF-16编码数据传递给它 . 切换到 LoadLibraryW 或将模块名称转换为ANSI .

    我会做前者 . 除了切换到 LoadLibraryW 之外,还需要复制整个缓冲区 . 通过用 SizeOf(Char)*(Length(DLLPath) + 1) 替换 Length(DLLPath) + 1 的两个实例来实现这一点 .

    还有一些评论:

    • 使用 PROCESS_ALL_ACCESS 过多 . 你只需要 PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ .

    • GetProcAddress(hKernel, pansichar('LoadLibraryA')) 中的 PAnsiChar 演员看起来错了 . 因为 'LoadLibraryA' 是UTF-16编码的 . 只需使用 GetProcAddress(hKernel, 'LoadLibraryA') . 或者 'LoadLibraryW' 如果沿着这条路走下去 .

    • 对句柄使用 NativeUInt 是错误的 . 它实际上并不重要,但你应该使用 THandle .

    • 使用 MEM_RELEASE 时,必须传递 0 作为size参数 .

    把它们放在一起,代码看起来像这样:

    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;
    

    就个人而言,我可能会传递 string 而不是 PWideChar ,但也许你还有其他动机去做 .

相关问题