Flag: Tornado!
Hurricane!
|
|
Topic created on: May 15, 2008 09:04 CDT by nezumi .
before go to sleep I wrote a simple, but quite funny crack-me. try to debug it with your favorite debugger and see what happens. sources come soon. yeah, this is a very old trick, but even modern debuggers lost control.
note:
this is a console app, so run it from cmd.exe or FAR.
neat. :-)
Imagebase+loader play. loader lets execution after loading all dependent dlls.
qux.exe - entry point RVA = 11000, with imagebase 400000, VA becomes 411000.
dll.dll - this gets loaded at 410000.
so after loading dll.dll entry point of qux.exe becomes perfectly valid, which is 411000 (where you have code to print messages).
As you rightly said, many debuggers and emulators which i tried fails.
|
Way to spoil it for EVERYONE ;-P
|
I have a different workaround to debug dll.
Here is what i did.
Loaded dll.dll to PEEditor and modified characteristics from 210F to 10F, so that debugger would think dll as an exe and loaded it with debugger, changed entrypoint to EBFE and saved modification and later changed characteristics to its original value.When I load the executable (qux.exe). I stopped at EBFE , later I changed dll's patched code to it's original value, Thus I can clearly debug this application.
|
neoxfx:
you missed the point. dll.dll patches EntryPoint:
*((unsigned char*)0x411000) = 0x90; to remove software breakpoint (CCh), installed by a debugger. this is the reasons why almost every debugger loses control. soft-ice allows you to set a hardware breakpoint on execution and keeps it even process dies. also, we can force OllyDdg to set hardware breakpoint on the EntryPoint, by writing a plug-in.
arjuns:
too long way :=) break on GetVersion or GetCommandLineA and soft-ice pops-up in DllMain (well, not DllMain actually, rather the start-up CRT code, calling DllMain). btw, qux.exe might me empty: just place all essential code into DllMain and have fun. OllyDbg doesn't stop at DllMain.
all:
I used direct address of EntryPoint just to point out the trick. I used exe and dll without relocation. I demonstrably gave Writeable attribute to .text section. however, crack-me might be more trickly.
* EntryPoint of .exe is within the file;
* DllMain calls GetModuleHandle(.exe) to determine the base address;
* DllMain finds address of EntryPoint of .exe in memory;
* DllMain calls VirtualProtect to make EP page writable;
* DllMain removes CCh breakpoint, installed by debugger;
this is more complicate, but absolute reliable way.
|
It doesn't load at all on my Vista system. I suspect that the entrypoint outside the image is not allowed.
Pre-XP systems won't load it either because DLLs must have a relocation table (even if it's empty).
It's a nice idea, though.
|
I just was too lazy to do it properly like I described above. the point is: removing software breakpoint from EntryPoint we can escape from the debugger immediately after loading application. I'm going to rewrite crack-me to make it compatible with Vista and XP (I tested it on Server 2003 SP1 and it works fine).
thanks for your comment!!!
|
Yes, I overlooked the entrypoint patching thingy :-D
thanks nezumi.
|
this is improved and fixed version of qux-crack-me, it defeats Soft-Ice now!
try to _debug_ it with your favorite debugger and see what happens.
* added:
- GDI interface;
- Soft-Ice bypassing;
* fixed:
- XP/Vista incompatible;
tested OS:
W2K SP4 - OK;
Server 2003 SP1 - OK;
tested debugger:
Olly -> refuses to load the app;
Syser -> refuses to load the app;
Soft-Ice -> skips the EP, loses control;
IDA-Pro -> depends on your hands...
|
Just a little trick... I use Olly and have a permanent BP on kernel32.BaseProcessStart() (among others ;P). This way I always stop an step before EP.
I single-stepped though the crackme-EP without problems with Olly using this trick. In order to use it, you only have to put the BP while debugging anything, and then everytime Olly loads kernel32 it will put the BP for you and break before EP.
Hope it helps,
Tora
|
excellent! but you missed the point. quux.dll finds EP of the process in the user stack and change it. so EP in PE-header has nothing to do with real (changed on the fly) EP. so, break point on EP, taken from PE header gives you nothing. very simple, but quite effective.
see the code:
DllMain()
{
...
GetModuleFileName(0,buf,_MAX_PATH);
base_x = (BYTE*) GetModuleHandle(buf);
pe_off = *((DWORD*)(base_x + PE_off));
ep_off = *((DWORD*)(base_x + pe_off + EP_off));
ep_adr = base_x + ep_off;
if (*ep_adr == 0xCC) return 0;
VirtualQuery((LPCVOID)&hinstDLL, &lpBuffer, sizeof(lpBuffer));
BaseAddress = ((BYTE*)lpBuffer.BaseAddress);
RegionSize = lpBuffer.RegionSize-sizeof(DWORD);;
for(RegionSize;RegionSize>0;RegionSize-=sizeof(DWORD))
if (((DWORD)ep_adr)==( *(DWORD*)(BaseAddress+RegionSize)))
(*(DWORD*)(BaseAddress+RegionSize)) +=0xD; // change EP
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return 1;
}
|
Now it works. It's like an external TLS callback. :-)
The DLL could make other changes to the EXE when it loads. Something less obvious, perhaps, but it's not often that you'll get an unknown DLL packaged with an unknown EXE.
|
I don't see the difficulty with debugging either of these two programs. With PEBrowse Interactive, set the Tools/Configure Debug tabsheet setting to "Break on process intialization?" and then just step through the process load. Or, if one is lazy, set a breakpoint inside of _LdrpInitializeProcess on the call to _LdrpRunInitializeRoutines and step through each DLL's initialization code from _LdrpCallInitRoutine. The debugger has full control to observe any weird behavior and to change anything in the process you want. Where's the "DEADBEEF"?
|
well, in general, using ms debugging api, debugger gets notification on LOAD_DLL_DEBUG_EVENT, so intercepting Dll EntryPoint isn't a problem, but... quux.dll change the start address of main thread, so, if a debugger set a break-point on Entry-Point, it loses the control. of course, analyzing DllMain of every non-system dll, you may notice that start address is changed, but... do you really know where the start address is stored?! well, maybe you know it, but you're not everybody and _any_ debugger (configuration by default) skips Entry-Point and loses control. don't you think that this is a problem? don't you think that placing CCh in EntryPoint is a bad idea. of course, there are a lot of plug-ins for Olly fixing this (Olly Advanced for example), but we're talking about default configuration.
|
You can set a breakpoint on LdrpInitialize or LdrpInitializeProcess inside of NTDLL. Now, you can step through the loader code and watch or debug the startup code of any binary. This works with my debugger, WinDbg, and any other debugger where you can set pending breakpoints. Setting breakpoints on the entry-point misses a whole lot of action while the program gets started. The only way this technique can be broken is if a driver has modified the loader code or the debugging APIs to prevent setting breakpoints inside of NTDLL.
|
NTDLL!DbgBreakPoint is enough.system passes it to the debugger. at this moment the process and all statically linked dlls are loaded into address space, but neither dllmain, nor EntryPoint, not TLS-callbacks not executed yet.
my solution: we get EXCEPTION_DEBUG_EVENT/BREAKPOINT debugging event and turn all pages of exe and dlls to NO_ACCESS. this help us to defeat _any_ anti-dbg tricks. simple, reliable, effective way. just a dozen lines in C.
|
The trick is cool but can't be used as image base address of dll can chnage in case of multiple dll.
Baibhav singh
|
see quux-crackme, it works everywhere, since it supports relocations, it finds the base exe-module in memory, checks if EP is break-pointed or not and changed the start address of the main thread. as result a debugger loses control, since OS takes address of EP from the user stack (and this address is changed by DLL, but a debugger doesn't know about that!).
|
Note: Registration is required to post to the forums.
|
|
|
There are 31,312 total registered users.
|
|