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

delphi xe3 dll injection for 64bit dll to 64bit process doesn't work

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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;


您正在调用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参数。

将所有内容放在一起,代码应如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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,但也许您有其他动机。