Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting 64 Bit DLL using code cave

I'm trying to inject a 64 Bit DLL into 64 Bit Process (explorer for the matter).
I've tried using Remote-thread\Window Hooks techniques but some Anti-Viruses detects my loader as a false positive.
After reading this article : Dll Injection by Darawk, I decided to use code caves.
It worked great for 32bit but because VS doesn't support inline assembly for 64 Bit I had to write the op-codes and operands explicitly.
I looked at this article : 64Bit injection using code cave, as the article states, there are some differences:

There are several differences that had to be incorporated here:

  1. MASM64 uses fastcall, so the function's argument has to be passed in a register and not on the stack.
  2. The length of the addresses - 32 vs. 64 bit - must be taken into account.
  3. MASM64 has no instruction that pushes all registers on the stack (like pushad in 32bit) so this had to be done by pushing all the registers explicitly.

I followed those guidelines and ran the article's example but none of what I did worked.
The target process just crashed at the moment I resumed the main thread and I don't know how to really look into it because ollydbg has no 64 bit support.

This is how the code looks before I injected it:

   codeToInject:  
000000013FACD000  push        7741933Ah  
000000013FACD005  pushfq  
000000013FACD006  push        rax  
000000013FACD007  push        rcx  
000000013FACD008  push        rdx  
000000013FACD009  push        rbx  
000000013FACD00A  push        rbp  
000000013FACD00B  push        rsi  
000000013FACD00C  push        rdi  
000000013FACD00D  push        r8  
000000013FACD00F  push        r9  
000000013FACD011  push        r10  
000000013FACD013  push        r11  
000000013FACD015  push        r12  
000000013FACD017  push        r13  
000000013FACD019  push        r14  
000000013FACD01B  push        r15  
000000013FACD01D  mov         rcx,2CA0000h  
000000013FACD027  mov         rax,76E36F80h  
000000013FACD031  call        rax  
000000013FACD033  pop         r15  
000000013FACD035  pop         r14  
000000013FACD037  pop         r13  
000000013FACD039  pop         r12  
000000013FACD03B  pop         r11  
000000013FACD03D  pop         r10  
000000013FACD03F  pop         r9  
000000013FACD041  pop         r8  
000000013FACD043  pop         rdi  
000000013FACD044  pop         rsi  
000000013FACD045  pop         rbp  
000000013FACD046  pop         rbx  
000000013FACD047  pop         rdx  
000000013FACD048  pop         rcx  
000000013FACD049  pop         rax  
000000013FACD04A  popfq  
000000013FACD04B  ret   

Seems fine to me but I guess I'm missing something.
My complete code can be found here : Source code

Any ideas\suggestions\alternatives?

like image 907
Omer Avatar asked Mar 07 '12 18:03

Omer


2 Answers

The first push that stores the return value only pushes a 32-bit value. dwOldIP in your code is a DWORD as well, it should be a DWORD64. Having to cast to DWORD from ctx.Rip should've been enough of a hint ;)

Also, make sure the stack is 16-byte aligned upon entering the call to LoadLibrary. Some APIs throw exceptions if the stack is not aligned properly.

like image 57
pezcode Avatar answered Sep 27 '22 22:09

pezcode


Apparently, The main problem was that I allocated the code cave data without the EXECUTE_PAGE_READWRITE permission and therefore the chunk of data was treated as data and not as opcodes.

like image 43
Omer Avatar answered Sep 27 '22 22:09

Omer