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

两盒软妹~` 提交于 2019-12-05 18:45:28

You are calling LoadLibraryA, but passing it UTF-16 encoded data. Either switch to LoadLibraryW or convert the module name to ANSI.

I would do the former. As well as switching to LoadLibraryW, you need to copy the entire buffer. Achieve that by replacing the two instances of Length(DLLPath) + 1 with SizeOf(Char)*(Length(DLLPath) + 1).

Some more comments:

  • Using PROCESS_ALL_ACCESS is excessive. You only need PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ.
  • The PAnsiChar cast in GetProcAddress(hKernel, pansichar('LoadLibraryA')) looks wrong. Because 'LoadLibraryA' is UTF-16 encoded. Just use GetProcAddress(hKernel, 'LoadLibraryA'). Or 'LoadLibraryW' if you go down that route.
  • Using NativeUInt for handles is wrong. It doesn't actually matter, but you should use THandle.
  • When using MEM_RELEASE you must pass 0 for the size parameter.

Put that all together and the code should look like this:

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;

Personally, I'd probably pass in a string rather than a PWideChar, but perhaps you have some other motivation for doing that.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!