Jump to content
Tuts 4 You

Adding libraries / injecting alternative


Scale

Recommended Posts

Hey guys,

So short back story, bought a new laptop which has an nvidia optimus card.

Now the optimus softare injects into each process it does this for power saving (switch between onboard and dedicated GPU's),

But this also causes recording software not to function.

So i wrote a library which simply filters which process it should or should not manage.

Now i have been injecting it by hand (createremotethread).

I tried redirect the EP of the library to load my library then resume as normal, but now every time i restart the process all pointers become incorrect. (pointers to .data section where i wrote "LoadLibraryA", "kernel32", "test.dll" which i use in my code cave). I *think* ollydbg 2 might be the case here because i remember doing something similar on olly 1 without issues, but i can't get it to function properly on w7 x64.

The question:

Is a redirect OP to a code cave the best solution to loading an extra library?

Isn't it possible to add my library to the import table, so it loads on it's own?

Thanks allot for you time.

Link to comment

You can load your dll with AppInit_DLLs, then only add your dll to the program directory you wish to have the library and it should not load globally but only in that app.

I use it to quickly inject code into heavily crced apps. As for codecaves, most likely ASLR disrupts your code. You have to make it dynamic.

You can add it to the imports, but it's not something I prefer. Codecaves are usually my second option to load external dll's, or replace existing dll's with modified ones.


REGEDIT4[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows]
"AppInit_DLLs"="test.dll"
"LoadAppInit_DLLs"=dword:00000001
Edited by quosego
Link to comment

Thanks for your response quosego.

Could you elaborate on making it dynamic?

What i do now is:

Write the 3 string to .data section, LoadLibraryA, kernel32, test.dll

Redirect OP

pushad
push [kernel32]
call GetModuleHandleA
push eax
push [LoadLibraryA]
call GetProcAddressA
push [test.dll]
call eax
popad
jmp EP
Edited by Scale
Link to comment

you need to get the api addresses from the iat, I guess you know that.

Furthermore the data pointers become incorrect, because your dll has probably some relocation section (dynamic imagebase). google pe relocation

Edited by Aguila
Link to comment

small little trick to avoid using data pointers

db "test.dll"
call 1:
1:
pop eax // Gets relative offset data pointer.
sub eax, 0Eh // if I've not miscounted that is.
push eax
call [kernel32.LoadLibraryA]
etc.
Edited by quosego
  • Like 1
Link to comment

If you have the address of GetProcAddress and GetModuleHandle, chances are you will find LoadLibrary in that IAT as well.

You can't start without ANY address, you need to have GetModuleHandle and GetProcAddress from the IAT. But chances are you will find LoadLibrary in that IAT as well.

It's like trying to pull yourself out of the sand by your own hair :s

Link to comment

You can't start without ANY address

Actually, you can. File-infector viruses and shellcode have been doing that for decades. It's as simple as:


call _next
_next:
pop esi
sub esi, offset _next
add esi, StandardImagebaseFromDllHeader
; now you have proper Imagebase of the DLL in esi

Knowing correct imagebase you can access all the necessary data from IAT/.data section/whatever other part of that DLL.

Also, you could get list of loaded DLLs from PEB and process their export tables to find all the APIs you need. But it's almost certainly an overkill for the simple task at hand. ;)

Isn't it possible to add my library to the import table, so it loads on it's own?

That is probably the easiest solution. There are even tools for that, for example IIDKing.

Cheers,

kao.

Link to comment

Actually, you can. File-infector viruses and shellcode have been doing that for decades. It's as simple as:


call _next
_next:
pop esi
sub esi, offset _next
add esi, StandardImagebaseFromDllHeader
; now you have proper Imagebase of the DLL in esi

Knowing correct imagebase you can access all the necessary data from IAT/.data section/whatever other part of that DLL.

How is that not knowing an address? You still need to add the RVA of the data you need.

And that still doesn't get you the adress of an API unless it is in the IAT.

The only general solution is enumerating the modules via PEB, as you mentioned.

Link to comment

You can actually get the imagebase of kernel32.dll at the ep by getting [esp] (all PE's originate from kernel32.dll) and walking the image untile the MZ header. Then use LoadLibraryA and getprocaddress, you have to code your own Getprocaddress for the first API's though.. It's a sweet trick I stole partly from Oreans. Which walks the entire memorybase to get API's. (mine skips that by getting kernel32 directly)

Edited by quosego
Link to comment

What i do now is:

Write the 3 string to .data section, LoadLibraryA, kernel32, test.dll

Redirect OP

pushad
push [kernel32]
call GetModuleHandleA
push eax
push [LoadLibraryA]
call GetProcAddressA
push [test.dll]
call eax
popad
jmp EP

As you are jumping from EP of a DLL to your code cave you can get Imagebase from there and add that to the API rvas you already have in your code.

Using RVA of APIs and Imagebase there is no problem with relocated addresses..

Here is your code rewritten without need of relocations:


; IN: [ESP+4] = Imagebase
; IN: [ESP+8] = Reason DllMain was called CMP [ESP+8], 1 ; You only want to load your library once at startup of the DLL
JNE @L0004
PUSHAD
;
; Get LoadLibraryA Api address
;
MOV EBP, [ESP+0x24] ; EBP = Correct Imagebase
CALL @L0001
DB "kernel32.dll",0 ; Puts string into stack with the call
@L0001:
CALL [EBP+0x12345678] ; Change this 0x12345678 to RVA of GetModuleHandleA in the IAT
CALL @L0002
DB "LoadLibraryA", 0 ; Puts string into stack with the call
@L0002:
PUSH EAX ; Kernel32 imagebase
CALL [EBP+0x12345678] ; Change this 0x12345678 to RVA of GetProcAddress in the IAT ;
; Load the DLL
;
CALL @L0003
DB "test.dll",0 ; Puts string into stack with the call
@L0003:
CALL EAX ; Call LoadLibraryA("Test.dll")
POPAD ;
; Redirect to real DLL EP
;
@L0004:
JMP EP

Of course, if LoadLibraryA is in the IAT then can use simpler code:


; IN: [ESP+4] = Imagebase
; IN: [ESP+8] = Reason DllMain was called CMP [ESP+8], 1 ; You only want to load your library once at startup of the DLL
JNE @L0002 ;
; Load the DLL
;
PUSHAD
MOV EBP, [ESP+0x24] ; EBP = Correct Imagebase
CALL @L0001
DB "test.dll",0 ; Puts string into stack with the call
@L0001:
CALL [EBP+0x12345678] ; Change this 0x12345678 to RVA of LoadLibraryA in the IAT
POPAD ;
; Redirect to real DLL EP
;
@L0002:
JMP EP

Have fun!

BoB

Edited by BoB
Link to comment
As you are jumping from EP of a DLL to your code cave you can get Imagebase from there and add that to the API rvas you already have in your code. Using RVA of APIs and Imagebase there is no problem with relocated addresses.. Here is your code rewritten without need of relocations:
 ; IN: [ESP+4] = Imagebase ; IN: [ESP+8] = Reason DllMain was called CMP [ESP+8], 1 ; You only want to load your library once at startup of the DLL JNE @L0004 PUSHAD ; ; Get LoadLibraryA Api address ; MOV EBP, [ESP+0x24] ; EBP = Correct Imagebase CALL @L0001 DB "kernel32.dll",0 ; Puts string into stack with the call @L0001: CALL [EBP+0x12345678] ; Change this 0x12345678 to RVA of GetModuleHandleA in the IAT CALL @L0002 DB "LoadLibraryA", 0 ; Puts string into stack with the call @L0002: PUSH EAX ; Kernel32 imagebase CALL [EBP+0x12345678] ; Change this 0x12345678 to RVA of GetProcAddress in the IAT ; ; Load the DLL ; CALL @L0003 DB "test.dll",0 ; Puts string into stack with the call @L0003: CALL EAX ; Call LoadLibraryA("Test.dll") POPAD ; ; Redirect to real DLL EP ; @L0004: JMP EP 

Of course, if LoadLibraryA is in the IAT then can use simpler code:

 ; IN: [ESP+4] = Imagebase ; IN: [ESP+8] = Reason DllMain was called CMP [ESP+8], 1 ; You only want to load your library once at startup of the DLL JNE @L0002 ; ; Load the DLL ; PUSHAD MOV EBP, [ESP+0x24] ; EBP = Correct Imagebase CALL @L0001 DB "test.dll",0 ; Puts string into stack with the call @L0001: CALL [EBP+0x12345678] ; Change this 0x12345678 to RVA of LoadLibraryA in the IAT POPAD ; ; Redirect to real DLL EP ; @L0002: JMP EP 

Have fun! BoB

I implemented this method, since it's just so simple and works great.

However i bumped into a new problem, If after loading my dll and then using getprocaddress to get the main function and call it the process starts looping or something.

No exceptions and can't seem to step to see where it loops.

I think this is similar to coding inside DllMain. So now i am a bit confused, If your not allowed to directly execute code then what?

Did a test loading the Dll but then not calling it's function then later from another process call it using CreateRemoteThread which worked perfectly.


PUSHAD
MOV EBP,DWORD PTR SS:[ESP+24]
ADD EBP,11C4F0
PUSH EBP ; /FileName
CALL <JMP.&KERNEL32.LoadLibraryA> ; \KERNEL32.LoadLibraryA
ADD EBP,10
PUSH EBP ; /Procname
PUSH EAX ; |hModule
CALL <JMP.&KERNEL32.GetProcAddress> ; \KERNEL32.GetProcAddress
CALL EAX [b]//This is where the application becomes unresponsive[/b]
POPAD
PUSH EBP
MOV EBP,ESP
PUSH EDI
PUSH ESI
JMP 603810C5

So this brings me to the question, If i am not allowed to directly execute code is my only option to hook another function to call my function later on?

Sorry if i am not making any sence it's past 3AM and my mind isn't really functioning properly anymore.

Edited by Scale
Link to comment

Hi Scale,

Probably the target is not initialized at that point to execute the export correctly. There are a couple of ways to make this work, but calling your export from a thread is the simplest way.

For example (again, fill in the rvas):


; DLL entrypoint
CMP [ESP+8], 1
JNE @L0006 PUSHAD
MOV EBP, [ESP + 0x24] ; Get address of CreateThread Api
CALL @L0001
DB "Kernel32.DLL", 0
@L0001:
CALL [EBP + RvaOf_LoadLibraryA]
CALL @L0002
DB "CreateThread", 0
@L0002:
PUSH EAX
CALL [EBP + RvaOf_GetProcAddress]
XCHG EAX, EBX ; Load your DLL and find export address
CALL @L0003
DB "Test.DLL", 0
@L0003:
CALL [EBP + RvaOf_LoadLibraryA]
CALL @L0004
DB "YourExport", 0
@L0004:
PUSH EAX
CALL [EBP + RvaOf_GetProcAddress] ; Create the thread, it will not actually execute until main exe thread does
PUSH 0 ; lpThreadAttributes
PUSH 0 ; dwStackSize
CALL @L0005 ; lpStartAddress = Address of ThreadProc code ; Thread code, address of export is passed as param
@ThreadProc:
PUSHAD
MOV EAX, [ESP+0x24] ; EAX = Param
; Add any needed params here
CALL EAX
POPAD
SUB EAX, EAX
RET 4@L0005:
PUSH EAX ; lpParameter = Address of export
PUSH 0 ; dwCreationFlags
PUSH 0 ; lpThreadId
CALL EBX ; CreateThread Api
POPAD@L0006:
JMP EP

Have fun!

BoB

Link to comment

Hey BoB,

I am trying to apply your code but this part baffles me:

CALL @L0005 ; lpStartAddress = Address of ThreadProc code

How does it ever reach @ThreadProc?

Thanks

EDIT:

It works! My mind still doesn't understand but it works!

The reason i don't understand is my first attempt i used a CreateThread in DllMain to call the export, So all you had to do was load the library but this didn't work.

As for the lpStartAddress i used EBP again subtracted to reach the threadproc from the data section and push it onto the stack.

Edited by Scale
Link to comment

Hi Scale,

Glad to read it works, I did it from my head so may have been slightly wrong smile.png

Playing with EBP is messy, I like to keep it as imagebase and use rvas instead of add/sub each time, but personal preference I guess.

I know it looks odd, but when I do this in code:


CALL @L0001
DB "SOMETHING", 0
@L0001:

It puts the address of the data or code following the CALL instruction into the stack, so that is how the ThreadProc code is added.

This way no addresses are needed either. Consider this code:


CALL @L0001
NOP
NOP
RET@L0001:
PUSH 0
CALL GetModuleHandleA
RET

Here the small function gets module base and returns to the code after the call instruction, which is 2 nops. The call pushes the next instruction address into the stack for returning, I use this to put address of code or data to the stack (by not returning) wink.png

Have fun!

BoB

Edited by BoB
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...