-4

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

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Davi Reis
  • 39
  • 2
  • 8
  • 2
    You can't mix 32 bit and 64 bit code in one process neither with DLL injection nor with regular DLL loading. This simply can not work due to significant architecture difference. So you do need 64 bit DLL for being injected into 64 bit processes. Now what your examples probably promise you is that you don't actually need 64 bit application to begin DLL injection into 64 bit process. But surely they don't promise for 32 bit DLL to work with 64 bit process as that is simply impossible. – SilverWarior Feb 02 '16 at 05:10
  • I believe you have misunderstood what those "examples on web of source codes" do promise. If a piece of code is said to work in both 32 bit and 64 bit, it means that you can **compile** it, as is, for both architectures. – Tom Brunberg Feb 02 '16 at 07:03

1 Answers1

3

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.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • OK, So, why this code above even compiled for x64 (Injector and dll together) still don't works for notepad.exe (x64) for example? PS: Tested in Windows 7 Ultimate x64. – Davi Reis Feb 02 '16 at 11:56
  • That's a different question. – David Heffernan Feb 02 '16 at 11:57
  • I had spoke about notepad.exe above, see. – Davi Reis Feb 02 '16 at 12:04
  • You asked about injecting a 32 bit DLL into a 64 bit host. You said, *I have made a dll (32 Bits plattform) and now I want inject in any x64 process.* That's the question that I answered. It's rather unfair that you now seem to want the answer to a different question. – David Heffernan Feb 02 '16 at 12:09
  • Then, I have that create a new question only for know about this? help me here in this same question please :-) – Davi Reis Feb 02 '16 at 12:10
  • I answered the question that you asked. Or do you think otherwise? – David Heffernan Feb 02 '16 at 12:10
  • Very likely the problem is showing a dialog from DllMain. That's not allowed. – David Heffernan Feb 02 '16 at 12:25
  • I tested your suggestion about `CreateThread` api, but still not works for notepad.exe, calc.exe... x64 respectively. [See](http://pastebin.com/gjK8rimk). PS: [Dll was compiled as 64 bits](http://i.imgur.com/FqGSiO1.png) – Davi Reis Feb 02 '16 at 14:38
  • Well, I guess there's something wrong with your code. Your attitude and approach to this is really frustrating. You ask one question and then expect us to answer something else completely. You copy code from the web without any real understanding, and then ask for help with it. Anyway, why are you even trying to inject? – David Heffernan Feb 02 '16 at 14:52
  • Because I seen [this recent video](http://sendvid.com/e002bzij) on web last week, and I want make a project capable of inject dll in calc.exe, notepad.exe also :-). – Davi Reis Feb 02 '16 at 15:09
  • You know what, forget it. I'm wasting my time here. I've done this kind of injection many times, but it's too draining to help you. http://meta.stackoverflow.com/questions/258206/what-is-a-help-vampire – David Heffernan Feb 02 '16 at 15:13
  • OK, but knew that all code used by me are exactly these ok?:-) – Davi Reis Feb 02 '16 at 15:46
  • I answered the question you asked and I resent the way you disregard the norms of this community. – David Heffernan Feb 02 '16 at 15:57
  • [this code that you left here](http://stackoverflow.com/questions/12670668/delphi-xe3-dll-injection-for-64bit-dll-to-64bit-proccess-doesnt-work) worked as you said there? I'm testing here now, and don't worked. – Davi Reis Feb 02 '16 at 22:35
  • Yes, works! I tested now, sorry. But for 64 bits process made in Delphi. if I want inject in some Windows x64 native application, this really don't works :-( – Davi Reis Feb 02 '16 at 23:49
  • I can't comment on this without detail. And you can't do this in comments. – David Heffernan Feb 03 '16 at 07:15
  • When you had tested this code there, he worked for x64 notepad.exe on Windows 7 x64 for example? do you remember? – Davi Reis Feb 03 '16 at 11:57
  • I cannot remember. You still appear to be calling a function in user32 from DllMain. – David Heffernan Feb 03 '16 at 11:58
  • No, I'm using `CreateThread` as had showed to you in comment above. – Davi Reis Feb 03 '16 at 12:00
  • That code could be wrong. I really don't want to invest more time in comments to this question now that your code has moved on so far. It's time for a new question with the very latest code you have. – David Heffernan Feb 03 '16 at 12:01
  • I'm blocked for create a new question, I will go update my code above only in Dll part, that was where was changed. – Davi Reis Feb 03 '16 at 12:06
  • I rolled back because your code broke my answer by removing the original content. If you want to add more, that would be fine. However, your code is totally wrong. Can you please read the docs for `CreateThread`. Look carefully at what is required for a thread function. You need it to be `function ThreadProc(lpParameter: Pointer): DWORD; stdcall;` Your function has the wrong signature. You also terminate the thread immediately, likely before it can do anything. Why are you calling `TerminateThread`. – David Heffernan Feb 03 '16 at 12:22
  • Now the other comment to make is to ask why you are testing this DLL by injecting it. You should be testing your code in a simple host that you can debug. Make sure that your DLL works well first. Then inject it. By testing everything altogether you can't tell whether your DLL code is wrong, or whether your injector is wrong. Then you get stuck. This is debugging 101. Learn to isolate problems. You don't need code, you need to learn debugging skills. Then you'll be far better placed. – David Heffernan Feb 03 '16 at 12:23
  • updated again above. This is result with a 64 Bits Delphi program as test and Windows 7 Ultimate x64. [See](http://i.imgur.com/kGeInvE.png). Already with notepad.exe 64Bits for example, present in this OS version, don't work. – Davi Reis Feb 03 '16 at 12:55
  • I reverted again because you again removed the original content. I'm not going to respond to any more of these comments until you start listening to me, and working with me. – David Heffernan Feb 03 '16 at 12:58
  • First of all, do some debugging. Test the DLL without injection. Then inject a do nothing DLL. And gradually work up to the full thing. Check for errors when calling API functions. Read the documentation properly. You don't appear to be doing any of this up to now. Sorry if it sounds harsh but I do not want to spoon feed you code. I'd like to help you learn. – David Heffernan Feb 03 '16 at 13:18
  • notepad and calc in windows 10 are UWA programmes and - though i don;t know fore sure in this case - no other win32 communication feature that i have tried with them works. Test your application with another programme (even one that you have written yourself). notepad and calc on win10 might as well be in a virtual machine – Helen Fairgrieve Apr 21 '16 at 07:58