![]() |
|
[C] [SRC] Intercepting system service calls on WoW64 Processes - Printable Version +- Hack Forums (https://hackforums.net) +-- Forum: Tech (https://hackforums.net/forumdisplay.php?fid=444) +--- Forum: Coding (https://hackforums.net/forumdisplay.php?fid=151) +---- Forum: Software Development (https://hackforums.net/forumdisplay.php?fid=118) +---- Thread: [C] [SRC] Intercepting system service calls on WoW64 Processes (/showthread.php?tid=4888648) |
[SRC] Intercepting system service calls on WoW64 Processes - excr4sh - Jun 30, 2015 Hello, so I decide to share this project I wrote some time ago, basically what this code does is set a hook at wow64cpu!X86SwitchTo64BitMode in order to intercept all sistem services functions, the advantage of this method is that you can intercept all functions with a single hook. implement the code as a DLL project, so to use it you should inject the DLL in the target process, injector is included. monitoring calls in firefox: [img]http://s4.postimg.org/4f0ijfbml/firefox_hook.jpg[/img] Note that this method can be avoided using native calls (64-bit version of ntdll) or direct syscall in any case normal applications do not. MSVC project can be downloaded from my github: https://github.com/Excr4sh/Wow64SsvcIntrcp Quick look: Code #include "Wow64Hook.h"* - hezboula123 - Jun 30, 2015 Nice, clean. I like it. Good job. Ironically intercepting sys calls on wow64 is more straight forward than on x86. KiFastSystemCall isn't large enough for a five byte relative jump instruction. I like the idea of not using a LDE for Nt* Functions. You can always guarantee the patch size. I still cringe at Microsoft generic linked list implementation. oh well. * - excr4sh - Jun 30, 2015 (Jun 30, 2015 11:43 PM)hezboula123 Wrote: Nice, clean. I like it.that's true, it requires less than 5-bytes long so you can make it work but that's even possible. I may add it to the project so it work in both 32 and 64b-bit Windows. * - hezboula123 - Jun 30, 2015 (Jun 30, 2015 11:52 PM)FordCl Wrote: that's true, it requires less than 5-bytes long so you can make it work but that's even possible. I may add it to the project so it work in both 32 and 64b-bit Windows. Definitely possible. backwards short jumps that lead to relative 4 byte jumps would be a solution. CONTAINING_RECORD(List, WOW64_SYSCALL_INFO, ListEntry); Let me guess what this does, considering type of listentry exists in type of wow64_syscall_info this macro finds the corresponding 'list' pointer along with the other data types defined in the type of 'wow64_syscall_info' structure in memory then returns the base (type of wow64_syscall_info)? I'm guessing since the address of the list entry is +8 of the structure you can just subtract 8 from the pointer, it's essentially what the macro is doing i believe. Edit: Just looked up the macro, looks like i was right. (type *)((char*)(address) -(unsigned long)(&((type *)0)->field))) * - RISC - Jul 1, 2015 (Jun 30, 2015 11:43 PM)hezboula123 Wrote: Nice, clean. I like it. You can make a two byte relative jump to KiIntSystemCall and perform the five byte patch from there. It's more straight forward than X86SwitchTo64BitMode. The only real downside I see to X86SwitchTo64BitMode is that it's relative to the thread's stack. Where as KiFastSystemCall, all the threads rely on a single global function. * - excr4sh - Jul 1, 2015 (Jul 1, 2015 01:02 AM)RISC Wrote: You can make a two byte relative jump to KiIntSystemCall and perform the five byte patch from there. It's more straight forward than X86SwitchTo64BitMode. The only real downside I see to X86SwitchTo64BitMode is that it's relative to the thread's stack. Where as KiFastSystemCall, all the threads rely on a single global function.You talk about this: 0:000:x86> dt ntdll32!_TEB +0x000 NtTib : _NT_TIB +0x01c EnvironmentPointer : Ptr32 Void +0x020 ClientId : _CLIENT_ID +0x028 ActiveRpcHandle : Ptr32 Void +0x02c ThreadLocalStoragePointer : Ptr32 Void +0x030 ProcessEnvironmentBlock : Ptr32 _PEB +0x034 LastErrorValue : Uint4B +0x038 CountOfOwnedCriticalSections : Uint4B +0x03c CsrClientThread : Ptr32 Void +0x040 Win32ThreadInfo : Ptr32 Void +0x044 User32Reserved : [26] Uint4B +0x0ac UserReserved : [5] Uint4B +0x0c0 WOW32Reserved : Ptr32 Void The real Hook is set at wow64cpu!X86SwitchTo64BitMode, WOW32Reserved is a pointer which points to that direction. * - RISC - Jul 1, 2015 (Jul 1, 2015 01:37 AM)FordCl Wrote: You talk about this: Ah, I wasn't reading the code correctly. I thought you were overwriting the pointer itself. * - excr4sh - Jul 1, 2015 (Jul 1, 2015 01:49 AM)RISC Wrote: Ah, I wasn't reading the code correctly. I thought you were overwriting the pointer itself.Imagine that one thread calls a function that goes through the hook, in my proxy or sub-sequent calls you can make a call to some function of the system such as CreateFile, that call would pass right through NtCreateFile -> FS: [0xC0] -> My hook, proxy function -> and back to CreateFile, This would cause a infinite loop and in most cases, a Stack Overflow that is why I modify the pointer temporarily. * - Only3 - Jul 1, 2015 good share if RISC didnt kill it must be hq * - Mouse❤️ - Jul 1, 2015 Oh, lookie, one of those rare actually security related posts. I don't know anything about injection past the 5 byte jmp so I'll just crawl back into my mousehole. * - RISC - Jul 1, 2015 (Jul 1, 2015 02:18 AM)FordCl Wrote: Imagine that one thread calls a function that goes through the hook, in my proxy or sub-sequent calls you can make a call to some function of the system such as CreateFile, that call would pass right through NtCreateFile -> FS: [0xC0] -> My hook, proxy function -> and back to CreateFile, This would cause a infinite loop and in most cases, a Stack Overflow that is why I modify the pointer temporarily. You could easily avoid the infinite loop. C0h is a pointer to the function. Original: Nt->C0h->Switch Yours:Nt->C0h->Hook Another option:Nt->My Pointer to C0h->C0h->Switch Where My Pointer simply handles the stack before it reaches X86SwitchTo64BitMode. The first scenerio which you're doing is the more practical solution since you'd avoid having to replace the pointer in every thread's context. The second scenerio works just as well, where it's not a complete hook, you'd have to return tot he original x86switchto64bitmode once you've dealt with the argument. * - excr4sh - Jul 1, 2015 (Jul 1, 2015 08:59 AM)RISC Wrote: You could easily avoid the infinite loop.By "Nt->My Pointer to C0h->C0h->Switch" you mean to set a hook in the native function? In any case I am sure there are several workarounds for this issue. BTW, for those who want to download the project I'm currently having problems with my github account: [img]http://s29.postimg.org/pm3jixsbb/image.jpg[/img] Project: https://www.sendspace.com/file/ga7lm8 * - Mouse❤️ - Jul 1, 2015 I'd take that as a compliment that you're writing code that only robots could write. * - hezboula123 - Jul 1, 2015 Code mov dword ptr fs:[0xC0], ediSo let's get this straight, if you're going to use any functions such as createfile as you suggested earlier to prevent a catastrophic infinite loop you'd just temporarily switch the pointer then you'd call createfile under the mov dword ptr fs:[0xc0], edi Seems like a good solution but what happens if let's say another thread calls any function while your pointer is replaced, you won't get the call. while 0CH = your actual switch trampoline, it won't touch the hook. * - excr4sh - Jul 1, 2015 (Jul 1, 2015 11:24 AM)hezboula123 Wrote: Seems like a good solution but what happens if let's say another thread calls any function while your pointer is replaced, you won't get the call.Each thread has its own TEB: 0:012> ~ 0 Id: 668.20c Suspend: 1 Teb: 000000`7efdb000 Unfrozen 1 Id: 668.ea4 Suspend: 1 Teb: 000000`7efd8000 Unfrozen 2 Id: 668.df0 Suspend: 1 Teb: 000000`7efd5000 Unfrozen 3 Id: 668.f78 Suspend: 1 Teb: 000000`7efad000 Unfrozen 4 Id: 668.ac Suspend: 1 Teb: 000000`7efaa000 Unfrozen 5 Id: 668.69c Suspend: 1 Teb: 000000`7efa7000 Unfrozen 6 Id: 668.dbc Suspend: 1 Teb: 000000`7efa4000 Unfrozen 7 Id: 668.c94 Suspend: 1 Teb: 000000`7efa1000 Unfrozen 8 Id: 668.cc4 Suspend: 1 Teb: 000000`7ef9e000 Unfrozen 9 Id: 668.cec Suspend: 1 Teb: 000000`7ef9b000 Unfrozen 10 Id: 668.4b0 Suspend: 1 Teb: 000000`7ef98000 Unfrozen 11 Id: 668.8b8 Suspend: 1 Teb: 000000`7ef95000 Unfrozen . 12 Id: 668.f9c Suspend: 1 Teb: 000000`7ef92000 Unfrozen On WoW64 Processes, threads have two TEB: 0:012> !wow64exts.info PEB32: 0x7efde000 PEB64: 0x7efdf000 Wow64 information for current thread: TEB32: 0x7ef94000 TEB64: 0x7ef92000 32 bit, StackBase : 0x5110000 StackLimit : 0x510c000 Deallocation: 0x5010000 64 bit, StackBase : 0x464fd20 StackLimit : 0x464c000 Deallocation: 0x4610000 |