Scale Posted October 16, 2011 Posted October 16, 2011 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.
quosego Posted October 16, 2011 Posted October 16, 2011 (edited) 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 October 16, 2011 by quosego
Scale Posted October 16, 2011 Author Posted October 16, 2011 (edited) 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.dllRedirect OPpushadpush [kernel32]call GetModuleHandleApush eaxpush [LoadLibraryA]call GetProcAddressApush [test.dll]call eaxpopadjmp EP Edited October 16, 2011 by Scale
Aguila Posted October 16, 2011 Posted October 16, 2011 (edited) 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 October 16, 2011 by Aguila
quosego Posted October 16, 2011 Posted October 16, 2011 (edited) small little trick to avoid using data pointersdb "test.dll"call 1:1:pop eax // Gets relative offset data pointer.sub eax, 0Eh // if I've not miscounted that is.push eaxcall [kernel32.LoadLibraryA]etc. Edited October 16, 2011 by quosego 1
Scale Posted October 16, 2011 Author Posted October 16, 2011 Thanks for all the replies!I'll take a look as soon as i can.
BoB Posted October 17, 2011 Posted October 17, 2011 Another way that does not require address for string: Call @L1 db "test.dll", 0@L1: Call [kernel32.LoadLibraryA]Have fun!BoB 1
mudlord Posted October 17, 2011 Posted October 17, 2011 I found you could have replaced that with a JMP, same stuff too.Found it super useful for some stuff I am working on...
deepzero Posted October 17, 2011 Posted October 17, 2011 isnt thecall [kernel32.LoadLibraryA]still va dependent in both cases?
Killboy Posted October 17, 2011 Posted October 17, 2011 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
kao Posted October 17, 2011 Posted October 17, 2011 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 esisub esi, offset _nextadd 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.
Killboy Posted October 17, 2011 Posted October 17, 2011 Actually, you can. File-infector viruses and shellcode have been doing that for decades. It's as simple as:call _next_next:pop esisub esi, offset _nextadd esi, StandardImagebaseFromDllHeader; now you have proper Imagebase of the DLL in esiKnowing 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.
quosego Posted October 17, 2011 Posted October 17, 2011 (edited) 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 October 17, 2011 by quosego
BoB Posted October 18, 2011 Posted October 18, 2011 (edited) What i do now is:Write the 3 string to .data section, LoadLibraryA, kernel32, test.dllRedirect OPpushadpush [kernel32]call GetModuleHandleApush eaxpush [LoadLibraryA]call GetProcAddressApush [test.dll]call eaxpopadjmp EPAs 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 EPOf 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 EPHave fun!BoB Edited October 18, 2011 by BoB
Scale Posted October 19, 2011 Author Posted October 19, 2011 (edited) 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! BoBI 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.PUSHADMOV EBP,DWORD PTR SS:[ESP+24]ADD EBP,11C4F0PUSH EBP ; /FileNameCALL <JMP.&KERNEL32.LoadLibraryA> ; \KERNEL32.LoadLibraryAADD EBP,10PUSH EBP ; /ProcnamePUSH EAX ; |hModuleCALL <JMP.&KERNEL32.GetProcAddress> ; \KERNEL32.GetProcAddressCALL EAX [b]//This is where the application becomes unresponsive[/b]POPADPUSH EBPMOV EBP,ESPPUSH EDIPUSH ESIJMP 603810C5So 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 October 19, 2011 by Scale
BoB Posted October 20, 2011 Posted October 20, 2011 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 EPHave fun!BoB
Scale Posted October 20, 2011 Author Posted October 20, 2011 (edited) Hey BoB,I am trying to apply your code but this part baffles me:CALL @L0005 ; lpStartAddress = Address of ThreadProc codeHow does it ever reach @ThreadProc?ThanksEDIT: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 October 20, 2011 by Scale
BoB Posted October 20, 2011 Posted October 20, 2011 (edited) Hi Scale, Glad to read it works, I did it from my head so may have been slightly wrong 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) Have fun! BoB Edited October 20, 2011 by BoB
chickenbutt Posted October 23, 2011 Posted October 23, 2011 looks like issues with relocation, also the old byte alignment issue with inlining. Maybe not, I've been up two days..
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now