Pancake Posted August 16, 2015 Posted August 16, 2015 (edited) Hello So today i decided to create own debugger for own use, everything works just fine btu as we all know the anti-debug tricks have to by bypassed. So i created my Fix.dll which fixes the peb and hooks far jump (currently only for wow64). It works like a charm and spoofs the Zw* functions output, but the problem is that the dll is loaded too late.. After receiving the first debug meesage which is obviously CREATE_PROCESS_DEBUG_EVENT i get the EIP, LoadLibraryA address and then inject payload which loads my Fix.dll (i coped the shellcode from StrongOD). So it calls LoadLibraryA for my dll and returns to the original EIP, continuing execution properly without any error. But DllMain (or DLL_PROCESS_ATTACH) isnt called at this time! Why? I receive many debug events about loading/unloading some DLLs, then one Memory Breakpoint exception, and after that my DLL finally ran. But its too late. Themida detects me before my DLL did anything BUT i load it with the very first CREATE_PROCESS_DEBUG_EVENT... Why is that? Is there something i miss? Or should i let the program Thanks in advance for help! Edited August 16, 2015 by Pancake
Aguila Posted August 16, 2015 Posted August 16, 2015 You should inject your dll at the first debugger breakpoint. Look at the source code of scyllahide for help.
Pancake Posted August 16, 2015 Author Posted August 16, 2015 (edited) How cool that you replied Aguila Thanks. Okay i got the system breakpoint thingy. But now i think i messed the far jump hook. Damn need to review the asm code of it, its much harder than it seemed! But im tryin very hard BY MYSELF Is it enough to set eax/ecx/edx for far jump? Or esp must also be set to edx + 8 (so edx contains params and esp is edx and return from far jump and return from Zw func)? The esp facks the simplicity of previous solution. i see that the syscalls which doesnt require to be modified are handled and returnin correctly, but when im tryin to fake the result i got some mess with registers on exit.. T_T Well there is no need to write all the anti anti from the scratch I will use your dll. But which files from the scyllahide pack should i load at system breakpoint? Injecting just hooklibraryx86.dll does not work and injector cli seems not to hook he far jump... Edited August 17, 2015 by Pancake
mrexodia Posted August 17, 2015 Posted August 17, 2015 (edited) The DLL entry point will only be called after some of the other DLLs are loaded (like kernel32, ntdll, etc.) The way you could go is manually loading your DLL and then setting the instruction pointer from the system breakpoint (before that you won't have any kernel functions to use). Like Aguila says, ScyllaHide handles this stuff. Just a quick thing that might help your development process (a lot!): 1. Set x64dbg as your JIT Debugger 2. When you need to see what is going on, manually push the current instruction pointer to the stack and then set the instruction pointer to a newly allocated page with the following code in it: int3ret3. Call DebugActiveProcessStop and let x64dbg catch the JIT event.4. Press Ctrl+F8 over the int3 instruction (completely skipping it), then step in the RET and you can debug wherever you left off Here is some code I wrote a time ago (TitanEngine specific, but should be easy to understand): void ArmaDebugger::DetachAndBreak(){ void* remote = VirtualAllocEx(fdProcessInfo->hProcess, 0, 0x1000, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE); if(!remote) { cbError("VirtualAllocEx failed!"); StopDebug(); return; } unsigned char code[] = {0xCC, 0xC3}; if(!WriteProcessMemory(fdProcessInfo->hProcess, remote, code, sizeof(code), 0)) { cbError("WriteProcessMemory failed!"); StopDebug(); return; } ULONG_PTR csp = GetContextData(UE_CSP); csp-=sizeof(ULONG_PTR); ULONG_PTR cip = GetContextData(UE_CIP); if(!WriteProcessMemory(fdProcessInfo->hProcess, (void*)csp, &cip, sizeof(remote), 0)) { cbError("WriteProcessMemory failed!"); StopDebug(); return; } SetContextData(UE_CSP, csp); SetContextData(UE_CIP, (ULONG_PTR)remote); if(!DetachDebuggerEx(fdProcessInfo->dwProcessId)) { cbError("DetachDebuggerEx failed!"); StopDebug(); return; } cbLog("Detached from process!");}Hope that helps,EDIT: With some plugin work it could also be done the other way around (from x64dbg to your debugger). Mr. eXoDia Edited August 17, 2015 by Mr. eXoDia
Aguila Posted August 17, 2015 Posted August 17, 2015 See here for timing:https://bitbucket.org/NtQuery/scyllahide/src/fca4927b641f5ff7680b47efda8db144bd12363c/ScyllaHideOlly1Plugin/ScyllaHideOlly1Plugin.cpp?at=master ScyllaHide does not use LoadLibrary for dll loading, because this is not stealth. It manually maps it to the process. The dll is seen as shellcode. For Themida you also need the special PEB handling, see documentation in section 4.2 Special PEB Fix Information
Pancake Posted August 17, 2015 Author Posted August 17, 2015 (edited) Okay but i already told that i wrote own debuger from scratch for own purpose, to easly add finctionality from c++ etc (and im NOT goin to use ollydbg here), but i wanted to use the scyllahide plugin for stealth, and thats the biggest problem. I know all the Zw functions antidebug, PEB etc, I dont really care how scyllahide works "under the hood" because im very happy with the plugin in olly, but right now i need to make it work with my own code, and neither hooklibraryx86 works or CLIInjector.exe also does not hook the far jumps. Dont ask me why im writing own debugger, i just felt like i need simple one of my own.. Edited August 17, 2015 by Pancake
mrexodia Posted August 17, 2015 Posted August 17, 2015 You can basically take the ScyllaHide loader, rip it out and use it in your own debugger.
Pancake Posted August 17, 2015 Author Posted August 17, 2015 (edited) i know the manual mapping, used it several times. This time tho i got to set EIP to the dllmain instead of creating a thread with it. Still i would like to make the syscall hooking by myself but the ammount of asm and little details here is overwhelming... Obviously im not goin to make inline hooks on the entry points of selected Zw functions because its detectable and checked by packers as far as i know so i gotta think of a solution similar to scyllahide. By the way i couldnt find the far jump hook ( i mean the asm code which is responsible for handling fs:[C0] call )in the scylla sources, where is it located? Edited August 17, 2015 by Pancake
Pancake Posted August 18, 2015 Author Posted August 18, 2015 (edited) I seem unable to set any HWBP in my target... So i tried to launch clean olly in my own debuger ( so i know there are no anti dbg tricks inside ), and when i receive memory breakpoint for the first time which is the system breakpoint i do CONTEXT ctx = { 0 }; ctx.ContextFlags = CONTEXT_FULL; if (!GetThreadContext(pi.hThread, &ctx)) printf("GTC FAIL %X\n", GetLastError()); DWORD old; LPVOID address = VirtualAllocEx(pi.hProcess, 0, sizeof(payload), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (!WriteProcessMemory(pi.hProcess, address, payload, sizeof(payload), &old) || sizeof(payload) != old) printf("WRITE FAIL %X\n", GetLastError()); ctx.Dr0 = 0x401000; //hardcoded EP of olly //ctx.EFlags |= 0x100; // i even tried trap flag which does not throw the exceptions... ctx.Dr7 = 0x55; // well 0x1 doesnt work too ctx.Dr6 = 0; if (!SetThreadContext(pi.hThread, &ctx)) printf("STC FAIL %X\n", GetLastError()); getchar(); // so i can see output in console return DBG_CONTINUE;And im NOT gettin ANY single step exception, i should be gettin at least the printf from OnSingleStep() function. DWORD OnDebugEvent(const LPDEBUG_EVENT de){ switch (de->u.Exception.ExceptionRecord.ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: return OnAccessViolation(de); case EXCEPTION_BREAKPOINT: return OnMemBp(de); case EXCEPTION_DATATYPE_MISALIGNMENT: return OnDatatypeMissalignment(de); case EXCEPTION_SINGLE_STEP: return OnSingleStep(de); default: return OnOtherException(de); } }I noticed that i can switch EIP easly with setthreadcontext, but debug registers seem not to work in my case... Why? Edited August 18, 2015 by Pancake
mrexodia Posted August 18, 2015 Posted August 18, 2015 This code sets the DR7 register based on the options you want. It might be you calculated it incorrectly. https://bitbucket.org/mrexodia/titanengine-update/src/51208e22f3354be8aa4f9926b22cb683b174e431/TitanEngine/Global.Breakpoints.cpp?at=master#Global.Breakpoints.cpp-7
Pancake Posted August 18, 2015 Author Posted August 18, 2015 (edited) Well i used debug registers many times and its always 0x55 for execute dr0-3. And here it does not work... and i got no damn idea why is that... Aha and it does not explain why EFlags also did not work OKAY i resolved it.Isnt it funny how MISLEADING name "CONTEXT_FULL" is? So it turns out that "FULL" isnt that full .... #define CONTEXT_CONTROL (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP#define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI#define CONTEXT_SEGMENTS (CONTEXT_i386 | 0x00000004L) // DS, ES, FS, GS#define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 0x00000008L) // 387 state#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L) // DB 0-3,6,7#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386 | 0x00000020L) // cpu specific extensions#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER |\ CONTEXT_SEGMENTS) So the answer is#define CONTEXT_FULLY_FULL CONTEXT_FULL | CONTEXT_DEBUG_REGISTERSworks, well "fully full" XD Edited August 18, 2015 by Pancake
Pancake Posted August 21, 2015 Author Posted August 21, 2015 (edited) Hello again. First of all huge thanks for Aguila who helped me to solve basic anti-anti problems. Now i can launch any file, or should i say ALMOST any file. I noticed something weird about one exe. Analyzin it in olly i noticed that it has encrypted DLL file in one section, which after being unpacked is fixed in memory (fixed i mean done relocations imports etc) and then LoadLibraryExA(dllname, 0, 0) is called. The file is NOT dumped in the folder and LoadLibrary loads it just fine, why is that? And back to debugger, olly properly displays that dll has been loaded and continues normal execution (olly shows path of dll as it would be in same folder as the exe) while my debugger does not get the LOAD_DLL_DEBUG_EVENT notifcation and soon gets the debugee termination message. I already checked that DLL is properly loaded when ran under by debugger, so why didnt i get notified? Did someone experience similar problem? http://i.imgur.com/uLDjRYl.pngLeft is output from my dbg and right is olly. U can see the exact same flow and then missing DLL notification which i think results in the termination.Thanks in advance Edited August 21, 2015 by Pancake
mrexodia Posted August 21, 2015 Posted August 21, 2015 Maybe the target hides the debug notifications using NtSetInformationThread.
Pancake Posted August 21, 2015 Author Posted August 21, 2015 Im using the same hide plugin in both cases, so i dont think thats the case
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