Search code examples
delphidll-injection

Dll injection in x64 process don't work


I have made a dll (32 Bits plattform) and now I want inject in any x64 process.

Was found several examples on web of source codes in Delphi that promisses do this, but when was tested, none dll was injected in any x64 process, already when tested with x86 process these codes works very fine!.

I found a unique example that promisses inject a dll file in x64 process, but in my tests, nothing have worked when was tried inject a dll in notepad.exe for example.

So, someone here have a example of dll injector working for x64 processors or can help me to do this with this example following (if this is possible) ?

Any suggestions will welcome!

My last attempt was:

Injector

  function InjectDLL(const dwPID: DWORD; {$IFDEF UNICODE} DLLPath: PWideChar
    {$ELSE} DLLPath: PAnsiChar {$ENDIF} ): Integer;

    const
      Kernel32 = 'kernel32.dll';
    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);
    {$REGION 'Check for UNICODE'}
    {$IFDEF UNICODE}
          hKernel := GetModuleHandleW(Kernel32);
          pLoadLibrary := GetProcAddress(hKernel, 'LoadLibraryW');
    {$ELSE}
          hKernel := GetModuleHandleA(Kernel32);
          pLoadLibrary := GetProcAddress(hKernel, 'LoadLibraryA');
    {$ENDIF}
    {$ENDREGION}
          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;

begin

if InjectDLL(4864, 'C:\SampleDLL') <> 0 then begin
    ShowMessage('woO!');

end;

end.

Dll

 uses
  System.SysUtils,
  System.Classes,
  Variants,
  Winapi.Windows;

Function StartThread(pFunction : TFNThreadStartRoutine; iPriority : Integer = Thread_Priority_Normal; iStartFlag : Integer = 0) : THandle;
var
ThreadID : DWORD;
begin
Result := CreateThread(nil, 0, pFunction, nil, iStartFlag, ThreadID);
if Result <> Null then
SetThreadPriority(Result, iPriority);
end;

Function CloseThread( ThreadHandle : THandle) : Boolean;
begin
Result := TerminateThread(ThreadHandle, 1);
CloseHandle(ThreadHandle);
end;

procedure ThisIsTheThread;
begin
 MessageBoxW(0,'I am in your target : Dll file','woO!',0)
end;

procedure Run;
Var
hThread : THandle;
begin
hThread := StartThread(@ThisIsTheThread);
hThread := StartThread(@ThisIsTheThread,THREAD_PRIORITY_ERROR_RETURN);
CloseThread(hThread);
end;


procedure mydllproc(Reason: Integer);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
      begin
         Run;
      end;
  end;
end;

begin
  DllProc := mydllproc;
  mydllproc(DLL_PROCESS_ATTACH);

end.

PS: works fine with 32 Bits process as said above.

Source


Solution

  • A 64 bit process can only load 64 bit modules. A 32 bit process can only load 32 bit modules.

    It should therefore be clear that you cannot inject your 32 bit DLL into a 64 bit process. In order to inject into a 64 bit process you will need to recompile your DLL as a 64 bit module.

    Once you do that, you'll have to change your DLL. You aren't allowed to do very much in DllMain, as is detailed by the MSDN docs. Certainly showing a dialog is total contravention of the rules. Call CreateThread from your DllMain and do the work there.