Archive for the ‘win32’ Category

# weakness of PAGE_GUARD or new Windows bug (XP/Vista 32/64 SP1)

simple, but effective system independent anti-debug trick based on well-documented APIs and does not involve assembly inline (means: it could be implemented in pure C). also it works as anti-dump sensor.

caution: I would recommend do _not_ use this thick in production code, because it’s based on the bug (two bugs actually: one in Windows, another in OllyDbg), which could be fixed at any moment. however, noting terrible happens if the bug would be fixed – the application just could not detect debugger/dumper.

in passing: I found this bug working on the project for a spectrography cherry group, well, not a cherry actually, but I prefer to keep the real name if it under the mat, anyway it’s all about Ciscar Fon – my first love, a gothic type, very kinky and yet creative.

in a nutshell: the whole idea based on PAGE_GUARD attribute. SDK says: “any attempt to access a guard page causes the system to raise a STATUS_GUARD_PAGE (80000001h) exception and turn off the guard page status… if a guard page exception occurs during a system service, the service typically returns a failure status indicator“. wow! how I like these words: “typically”, “usually”, “normally”… they say nothing, but at the same time they say everything!!! just read between the lines…

ReadProcessMemory: normally, /* I mean _normally_ */ ReadProcessMemory() returns error if it meet a page with PAGE_GUARD attribute. does it make sense? of course! but, _normally_ does not mean “every time”. Windows has a bug (I tested W2K SP4, XP SP3, Vista SP0 and Vista 64bit SP1 – they are all affected).

the bug: if PAGE_GUARD page is created by VirtualAlloc() call, ReadProcessMemory() turns off the guard page status without any exception and returns a failure status indicator. however, the second ReadProcessMemory() call returns a positive status (because PAGE_GUARD was turned off), so when the application will try to access to that page – there will be no exception (as it’s supposed to be), because there is no guard anymore.

the sensor: it’s easy to create a sensor to detect dumpers. allocate a page with PAGE_GUARD attribute and check it from time to time: just install SEH handler and read the content. no exception means we’re fucked, oh, sorry, dumped. I tested PE-TOOLS and other popular dumpers and they all were detected.

demo: to demonstrate the bug, I wrote two simple applications. one – “protected-like” application, another – dumper-like application. please download the sources and binaries.

“protected” application (PAGE_GUARD_BUG.c) is very simple, basically it just calls VirtualAlloc(,,,PAGE_READWRITE | PAGE_GUARD), displays the address/PID, waits for pressing ENTER and attempts to read the content of the allocated block. there is no SEH handler, so if an exception happens you will see the standard Windows message box.

p = VirtualAlloc(0, 0×1000, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD);
printf(“run turnoff.exe %d %d twice and press enter”, GetCurrentProcessId(), p);
gets(buf); printf(“result: %x\n”, *p);

and the “dumper” (turnoff.c ) just calls ReadProcessMemory() and displays the result:

h = OpenProcess(PROCESS_ALL_ACCESS, 0, atol(arg_id));
x = ReadProcessMemory(h, (void*)atol(arg_addr), &buf, 0×1, &n);

oh, here we go. follow me, please!

1) run the protected app (“$start PAGE_GUARD_BUG.exe“);
2) it displays ID/addr, like: id:1216 addr:4325376;
3) press right now;
4) ops! exception! this means: PAGE_GUARD works!!!
5) run the protected app again (“$start PAGE_GUARD_BUG.exe“);
6) it displays ID/addr, like: id:1212 addr:4325376;
7) run the dumper, passing ID and addr (“$turnoff.exe 1212 4325376“);
8) it says: “satus:0, bytes read: 0″ (means: ReadProcMem failed);
9) but! if you switch to PAGE_GUARD_BUG.exe and press ENTER you will see no exception (means: PAGE_GUARD was turned off);
10) if you run the dumper twice (of course without pressing ENTER) it will displays: “satus:1, bytes read: 1″ (means: there is no PAGE_GUARD anymore);

nice trick, it’s it? but actually it was just a little warming-up. the real tricks are coming.

NOTE: if PAGE_GUARD attribute is assigned by VirtualProtect(), Windows respects the attribute and ReadProcessMemory() fails, leaving PAGE_GUARD turned on.

debuggers: what happens if a debugger meet PAGE_GUARD page? the answer is: there will be no exception, the debugger just turns PAGE_GUARD off, processes the content and forgets to return PAGE_GUARD back.

demonstration: to demonstrate this nasty behavior I wrote a simple program PAGE_GUARD_DBG.c, download it, please. and follow me. the source code is easy to understand:

push 0×1000
push 0
call ds:[VirtualAlloc]
mov eax, [eax]

execute it step-by-step, make step over the VirtualAlloc() call and display the content of the allocated memory block (for example, in IDA-Pro press , eax, ENTER and to go back). continue tracing, and… ops! where is our exception?! there is no one!!!

OllyDbg is even worse. it automatically resolves memory references displaying the content in the right column, so we don’t need to go to the dump window nor pressing CTRL-G… just trace it and the debugger will be detected, since there will be no exception!!!

IDA-Pro: well, what about if we just run the program under debugger? just run, no trace! IDA-Pro triggers an exception: “401035: A page of memory that marks the end of a data structure such as a stack or an array has been accessed (exc. code 80000001, TID 1312)” and offers to pass the exception to the application. in this case the debugger will be _not_ detected.

OllyDbg: the standard de-facto debugger stops when the application accesses PAGE_GUARD, giving the message “Break-on-access when reading” in the status bar, but Olly does not offer us to pass the exception to the application. even we go to options->exceptions and add 0×80000001 (STATUS_GUARD_PAGE) exception to the list, Olly will ignore it! guess, PAGE_GUARD is just a part of “memory-breakpoint” engine, so no way to pass PAGE_GUARD exception to the application, so it’s easy to detect the debugger. (I tested OllyDbg 1.10).

Soft-Ice: it does not display the content of PAGE_GUARDED pages, so it could not be detected by this way. in other hand, keeping the impotent content under PAGE_GUARD makes debugging much harder. we can’t perform full memory search, we can’t find cross references… we’re blind.

the love triangle: PAGE_GUARD, Windows and OllyDbg: Windows has a bug, Olly has a bug, so... how were supposed to debug?!

the love triangle: PAGE_GUARD, Windows and OllyDbg: Windows has a bug, Olly has a bug, so... how we're supposed to debug?!


# die Vista, die or why DEADDEEF is alive?

intraarterial injection: fixing old bugs in Vista ms-guys inevitably add new ones. don’t ask me for proofs unless you want to hurt your face-painting wretched system. do you know the system I’m talking about? good! the following code has no impact on NT, W2K, XP, but… it freezes malformed Vista. it just hangs the system up! (I tested Vista SP0). download the binary or compile the file by yourself.


get off the subject: remember a simple anti-dbg trick with closing a non-existing handler? something like CloseHandle(0xBADC0DE) or CloseHandle(0xBADC0DE). if we’re under a debugger – OS generates C0000008h (INVALID HANDLE) exception. no debugger means no exception. the problem is: how to close an assuredly invalid handler? if you didn’t open it, any system DLL might opened it. of course, you can use GetHandleInformation() to check: if the handler has been opened, but… it’s too obvious (for hackers) and too trivial to be interested for us. there is another way — our way.

flowing well: has it never come in upon your mind how OS assigns handlers? a handler is DWORD, right? but it’s impossible to get all values busy. some values will be taken, but some of them should be free, because it’s impossible to open all of 4,294,967,296 possible handlers. it’s out of the limit! so, lets perform a fast research of system internals. what we’re going to do is: to consume all handlers until CreateFile() says: “no more handlers, I give up“. well, time to call GetHandleInformation() and check: is there any predictable template? which handlers are taken and which are not?

dead marines: holly cow!!! just look at it!!! wow! this is the very template we looked for! handlers 0h .. 02h are taken, handler 07h is taken as well, but… the rest of them fits the following equation: (((h – 0×12) % 04). so, it’s easy to determine handlers that will be not taken whatever happens to them, thus these handlers will definitely raise an exception on the close attempt. the point is: closing a handler like 1Bh looks reasonable from hacker’ point of view, but it’s just a way to generate an exception under debugger.

HANDLE: 00h is invalid
HANDLE: 01h is invalid
HANDLE: 02h is invalid
HANDLE: 03h is valid
HANDLE: 04h is valid
HANDLE: 05h is valid
HANDLE: 06h is valid
HANDLE: 07h is invalid
HANDLE: 08h is valid
HANDLE: 09h is valid
HANDLE: 0Ah is valid
HANDLE: 0Bh is valid
HANDLE: 0Ch is valid
HANDLE: 0Dh is valid
HANDLE: 0Eh is valid
HANDLE: 0Fh is valid
HANDLE: 10h is valid
HANDLE: 11h is valid
HANDLE: 12h is valid
HANDLE: 13h is invalid
HANDLE: 14h is valid
HANDLE: 15h is valid
HANDLE: 16h is valid
HANDLE: 17h is invalid
HANDLE: 18h is valid
HANDLE: 19h is valid
HANDLE: 1Ah is valid
HANDLE: 1Bh is invalid
HANDLE: 1Ch is valid
HANDLE: 1Dh is valid
HANDLE: 1Eh is valid

Achilles’ spear: so, you got it! we have the magic formula allowing us to check any arbitrary value. take 0xBADC0DEh for example. download the sources of IsInvalid.c and call IsHandlerInvalid(0xBADC0DE) or simile run IsInvalid.exe. as you can see, 0xBADC0DE could not be taken, so it’s a good choice to cause an exception.

ok, another try — 0xDEADBEEF. just pass the value to our magic function and… ops! it says: “HANDLE: DEADBEEFh is possibly valid“, so it’s potentially unsafe to use CloseHanlde(0xDEADBEEF). oh, come on! fat chance to close a file, opened by system or custom DLL, but… it’s still possible. btw, VMProtect uses CloseHanle(0xBADC0DE), which is safe. coincidence? or… anyway, Dermatolog (Иван Пермяков, Екатеринбург –the geek who created it) is a very wise guy and his protector is one of the best. it’s stuffed by anti-dbg tricks and it was a pleasure for me to dig them up. what’s about you?

handler consuming leads to consume kernel memory as well (handler_explorer.exe is running), sorry for the Russian screen-shoot, will appreciate your help, if somebody send me eng one (info # re - lab . org )

handler consuming leads to consume kernel memory as well (handler_explorer.exe is running), sorry for the Russian screen-shoot, will appreciate your help, if somebody send me eng one (info # re - lab . org )


# IDA-Pro 5.5 has been updated, fixed — Bochs plug-in unaligned PE bug

in a nutshell: IDA-Pro has been updated on July-01/2009 in order to fix a bug in BOCHSDBG plug-in. from now on it supports unaligned PE files (see definition below). if you want to get the updated version, send your identification (the ida.key) to

nude statement: I don’t like IDA-Pro Debugger. it’s very limited, devilish uncomfortable and embarrassing. it has its own benefits, none the less, but for me OllyDbg is much better. every man has his taste – opinions differ.

death notice: OllyDbg/Soft-Ice (like any other x86 debugger) is very limited. it could be detected, it could be broken. it does not support tracing of a self-traced program and there is no workaround — no script nor plug-in to fix it. it’s nature of x86 CPU. the same story with DRx registers. virtualization and emulation is the only way to hack strong protections (oh, come on! as if you can’t break an emulator, whose behavior is pretty different from native CPU).

brutal facts: what do we have?! is there any decent emulator?! well, x86emu (plug-in for IDA-Pro) is extremely limited. BOCHSDBG is good enough to debug MBR or OS loader, but… how we’re supposed to debug applications/drivers, working _below_ the Operation System?! the same story with VMWare/WinDbg and QEMU/GDB. so, in essence there is no decent emulators, except for internal products like McAfee EDebug (very good tool, but only for home consumption, “home” means “McAfee”).

beam of hope: IDA-Pro debugger had been significantly improved since 5.4 and the most dramatical change is BOCHSDBG plug-in supporting win32 PE debugging. what does it mean and how it works? well, to answer the first question: we got what we were waiting for a looong time. yeah, there was BOCHS, but it’s impossible to debug code snippets directly into BOCHS. the only way to do it – create an image of a tiny operation system and put a snippet there. CPU starts in real 16 bits mode, while win32 programs expect to see 32-bit protected mode with flat address space – the minimum requirements to debug code snippets, but it’s not enough to hack real applications!

the next step is to create win32-like environment. at least we need to emulate fundamental system structures (like PEB) and engines (SEH for example) not mention basic API set. it has been hell of a job (or, may be, a job in hell). and this job has been done by Elias Bachaalany, he is our hell-guy – very talented brick from the eastern shore of the Mediterranean Sea. not wonder that he is a clever cat!

a mint of intrigue: it was excitement from the first sight when I read Ilfak’ post “Bochs Emulator and IDA?“. it was just awesome! at that moment my company provided me a license for IDA-Pro 5.3, but it was too old to be updated for a free, so I kicked up my heels. McAfee provided me a license as well (Danke schön to the director of IPS research of Avert Labs, it was very kind of him and maybe I will find myself in his team based in Santa-Clara). but… it was IDA-Pro 5.3 – the original CD, shipped to Moscow McAfee office, hosted in the biggest building in Europe – Naberezhnaya Towers, but I was unable to get the updates because of security policies of McAfee. I had no access to the internal network and the sardonic Firewall did not allow to go outside. what’s a piggishly! only when IDA-Pro 5.5 has been released, I got the updates directly from, sitting in Macrovision office and thinking that even in my village Internet is faster (I own 10 Mbytes link, but an average speed is 2 Mbytes, but it’s more that enough to fit my needs).

collapse of plans: I started testing the new plug-in, trying to debug programs (malware mostly) that I was unable to debug with OllyDbg and the old IDA-Pro debugger. the first impression was: wow! it’s cool! it’s easy to trace self-tracing code, “software” breakpoints do not changed the content… well, I felt like I reached the golden gates (or it was Golden Bridge?) and was about to dine with Mohammed, happy hunting ground – Elias made the best of both worlds, but… better to reign in hell than serve in heaven. BOCHSDBG plug-in is a great tool, yet it’s all wrong. the whole design is wrong. it’s easy to break the debugger.

for example: it traces programs by BOCHS virtual CPU engine. the very engine is used by the debugged program, so… no problem to detect the debugger, yet it’s harder than beat a non-virtual one. (now I’m working on anti-debugging tricks some of them will be posted here, some – for commercial purposes).

the facts: when you choose Loader Type -> PE in BOCHS configuration message box, the plug-in prepares a virtual image and loads PE file there. so, we should expect a lot of problems, because it’s almost impossible to design a decent 3rd party PE Loader. the problem is: MS PE Specification is not accurate and MS does not follow it. take Section Alignment for example. according to MS PE specification, the minimal Section Alignment == PAGE_SIZE, but win/32 supports much smaller values as well (win/64 does not) and the smallest alignment, supported by standard MS Linker, is 10h. lets come to terms to call these files “unaligned PE” – it’s not a good term, because the files are still aligned, yet the align value is much smaller than the specification requires, but it’s just a term :-)

IDA-Pro BOCHSDBG Plug-in does not support unaligned PE files, and generates an exception on any writing attempt, even if the section is writable (in fact, even the section is not writable, the system PE loader makes _all_ sections writable, regardless of the attributes – but I will keep this feature to another post). just a few people have a chance to meet an unaligned PE, because these files are not common for commercial applications, but malware use this trick quite often in order to be smaller, and I met the problem on the second day of using IDA-Pro BOCHSDBG Plug-in.

in the can: to demonstrate the problem I created a very simple file. download it or see the source below:

int mem; char *txt=”[OK]“;
__declspec(naked) nezumi()
__asm{ mov [mem], eax }
MessageBox(0, txt, txt, 0); ExitProcess(0);

to make it, run “nmake make” or use the following command lines:

$cl.exe /c /Ox ida-bug_bochsdbg-16.c
$Link.exe ida-bug_bochsdbg-16.obj /ALIGN:16 /ENTRY:nezumi /SUBSYSTEM:WINDOWS KERNEL32.lib USER32.lib

ignore the linker warning “LiLNK4108: /ALIGN specified without /DRIVER or /VXD; image may not run” — image works fine on 32-bits editions of NT, W2K, XP, S2K3/S2K8, Vista (64-bits editions probably will not run it, but I have not checked it by myself, if you have 64-bits editions of Windows under your hand, please test it and post your comment here, thanks!)

as you can see, unaligned exe works fine, OllyDbg and local IDA-Pro debugger have no problem with it, but… go to Debugger menu, click “Switch Debugger”, select “Local Bochs debugger” and run it by F9 or try to trace step-by-step.

ops!!! an exception on a write attempt (see the pic below), accessing “mem” variable, which belongs to .data section, which is writable. remove “/ALIGN:16” key from the linker arguments, rebuild the program and try to debug it again. now it works fine! but… we can’t rebuild closed source program!!! so, it’s a problem and now it’s fixed. just ask the support for the updated version.

updated on: Sun, July 05, 04:44: grammar fix

IDA-Pro, BOCHSDBG, unaligned pe, impact area

IDA-Pro, BOCHSDBG, unaligned pe, impact area


# a bomb from McAfee (a nasty one)

accidentally McAfee sent me a file-bomb and now I need to backup my NTFS volume, reformat it, and copy data back to recover internal NTFS structures. shit happens! will write more latter, stay tuned.


# Olly loads Olly to bypass anti-attach tricks /* Clerk’ trick */

the problem of anti-anti-attaching came up in conversation on the legendary site. Clerk (a very clever guy carring a heavy plasma gun, loaded with rounds of brilliant ideas) as always offered a very elegant, yet bizarre solution (ru). I wonder – what kind of Rasta stuff makes him so creative! well, stop to expatiate, back to business.

previous posts demonstrate numerous anti-attach tricks and most of them based on the system thread, creating by OS during attaching. here they are (the tricks): BaseThreadStartThunk => NO_ACCESS, NtRequestWaitReplyPort, DbgBreakPoint

the question is – how to ask OS do not create the system thread? to do it we should know OS internals. IDA-Pro/Soft-Ice shows us that KERNEL32!DebugActiveProcess comes to NTDLL!DbgUiDebugActiveProcess, who calls NTDLL!ZwDebugActiveProcess/ NTDLL!DbgUiIssueRemoteBreakin| NTDLL!DbgUiStopDebugging (just to dissemble NTDLL!DbgUiDebugActiveProcess to see it with your own eyes).

the point is – NTDLL!ZwDebugActiveProcess does all job, attaching a debugger to the process. . as soon as NTDLL!ZwDebugActiveProcess returns status ok, the process has been attached and can be debugger. but! operation system calls NTDLL!DbgUiIssueRemoteBreakin just to notify the debugger by generating breakpoint exception, however, we don’t need it!!!

so, what we’re going to do? I prefer to use old soft-ice with global breakpoints support. just set HW or software breakpoint on NTDLL!DbgUiDebugActiveProcess or NTDLL!ZwDebugActiveProcess and skip the rest of the function. it’s easy, but soft-ice does not work with newest operation system.

Clerk found the way how to do this with Olly. the idea is: load Olly into Olly. yeah! right!

1) load Olly into Olly /* to avoid a mess lets call the first Olly (I) and the loaded copy – Olly (II) */;
2) Olly (I): Set breakpoint on NTDLL!DbgUiDebugActiveProcess: View\Executable Modules\NTDLL.DLL, CTRL-N, “DbgUiDebugActiveProcess”, F2, ENTER;
3) Olly (I): run Olly (II): press F9 several times until right corner “paused” changed by “running” meaning that Olly (II) is still under debugging but it’s running now;
4) ALT-TAB to switch to Olly (II);
5) Olly (II): File\Attach\name_of_the_trickily_process to attach (for example: to_attach_36.exe);
6) Olly (I) pops up, the breakpoint has been triggered;
7) to_attach_36.exe is still running;
8) Olly (I): press F8 several time until NTDLL!ZwDebugActiveProcess is executed;
9) to_attach_36.exe has been stopped, Olly (II) has been attached to it, Olly (II) is stopped as well;
10) Olly (I): move cursor to the next command after NTDLL!DbgUiStopDebugging, right click to context menu and “new origin here” or simple press CTRL+Gray * (“gray” means small numeral keyboard);
11) Olly (I): press F9 to run Olly(II);
12) ALT-TAB to switch to Olly (II);
13) Olly (II) shows naked screen w/o any info, to_attach_36.exe is running;
14) Olly (II): View\Threads. do you see the only one thread? the main thread of the app?! wow!
15) Olly (II): press “pause” to stop to_attach_36.exe;
16) Olly (II) updates CPU window and from that moment we can trace to_attach_36.exe as usual;

well, you got it. a nice trick to bypass anti-attaches. it’s very powerful and universal, but does not work with PEB=>LdrData . um, every technique has its own limitations.

meanwhile, you probably know, if the process is already attached to another process, we can’t attach our debugger to it. many protections use this trick – they create a child process (packed), attaches to it for dynamic unpacking. but there is a loophole. we can attach to the parent process unless the child not attached to the father. yes!!! a debugged process can attach to the debugger!!! it looks like (parent <== attach ==> child)

I’ll write about it latter, showing you how to break this chain. for now, you can play with Clerk’s trick!

Olly loaded into Olly attached to to_attach_36.exe

Olly loaded into Olly attached to to_attach_36.exe


# anti-attach: BaseThreadStartThunk => NO_ACCESS

another anti-attach trick. during attaching to the process, operation system creates a thread inside it and as far as we know, every thread has the start address. the address of the system thread is BaseThreadStartThunk. it calls BaseAttachComplete, who calls DbgBreakPoint in order to raise the breakpoint exception to pass control back to debugger. so, if we block BaseThreadStartThunk somehow, DbgBreakPoint will be never called and a debugger will never get control. theoretically…

…practically, operation system notifies a debugger when a new thread is about to be created, thus a debugger does not need in DbgBreakPoint at all!!! just set Option\Debugger option\Events\Break on new thread in Olly or Debug\Debugger options\Stop on thread start/exit in IDA-Pro and enjoy!!!

but, there is something else. first of all – these options are not set by default. second of all – if the system thread issues an exception – we can’t just continue execution! we need to kill the system thread to suppress the exception – not every hacker knows it and not every debugger allows us to do it (IDA-Pro does not).

well, guess, “Break on new thread” is set. this means our debugger stops _before_ executing the first command of BaseThreadStartThunk. how we’re going to generate an exception?! it’s easy! page of BaseThreadStartThunk => NO_ACCESS! of course, operation system will send exception notification to the debugger, allowing us to kill the system thread and continue executing/tracing the main one, but as it was said above not every hacker are ready to handle this situation.

ok, lets play with this trick. be warned: it’s not safe. we can’t set no access only for BaseThreadStartThunk, it affects the whole memory page where might be essential functions, but… for W2K/XP/S2K3 it works well. just… BaseThreadStartThunk is not an exported function. so, how we’re going to find where it’s located in memory? guess, the most universal way is to create a child process, attach to it, get CREATE_THREAD_DEBUG_EVENT notification and memorize u.CreateThread.lpStartAddress.

download the sources and binary of the POC to play with.

Olly fails to attach and the only way to continue debugging is to kill the system thread

Olly fails to attach and the only way to continue debugging is to kill the system thread


# Process Explorer – bloody hell of indefinite waiting bugs

long time ago I found a bug in Process Explorer pointing out that it uses wrong algorithm of retrieving Thread Start Address. all threads created with CreateRemoteThread has Thread Start Address pointing to KERNEL32.DLL. it’s true, but help- and sense-less. I sent my bug report to Mark, but got no answer and posted it on my old blog: “bug in Process Explorer (a gift for malware)

it means that Process Explorer is not reliable enough, we can’t trust it anymore and yesterday I found more bugs. they’re very common and almost _every_ application has numerous bugs like this. are you intrigued? well, lets begin!!!

download to_attach_ldr.exe (anti-attach trick, based on damaged PEB=>PPEB_LDR_DATA – read this post for more info), run it and… ask Process Explorer to display properties of “to_attach_ldr.ex” process (yeah! “ex”, not “exe” – another bug?!). now, go to “Threads” tab and…

ops!!! Process Explorer freezes falling into infinitive loop with 100% CPU load. ~60% is to_attach_ldr.exe and ~40% is CSRSS.EXE. ok, close to_attach_ldr.exe and Process Explorer immediately wakes up. this means it just was waiting the even that was not going to happen.

ok, another example. download to_attach_33.exe (anti-attach based on intercepted NtRequestWaitReplyPort, described here ). run it and ask Process Explorer to show properties, go to “Threads” tab and… you know what will happens in the next moment. freezing!!!

freezing Process Explorer

freezing Process Explorer

we just found out how buggy Process Explorer is. but why? what’s the issue? the answer: NT has numerous functions like WaitForSingleObject, WaitForDebugEvent, etc. they all take dwMilliseconds argument specifies time to wait for an event. if the parameter is INFINITE, the function does not return until an event has occurred. the problem is – almost every programmer uses INFINITE and does not handles time out error. admit, you did this too?

Ilfak does for sure and I pointed out it before (“another EnableTracing() bug“).

ok, we got two points. first – never use INFINITE unless you’re 100% sure it works. the second point: if malware creates a malicious thread inside a trusted application – anti-attach tricks help it to survive. many anti-viruses are unable to enumerate threads in this case and some of them just freezes. very effective DoS attack against pro-active protections!!!

note: I tested Process Explorer 11.4 under W2K SP4, not tested other versions yet, but guess the bug is there.


# NtRequestWaitReplyPort abuses IDA-Pro

good news first. my simple anti-anti-attaching plug-in is coming soon and it works very well. meanwhile, I’m experimenting with different anti-attaching technologies and wish to share a few new (old?) tricks with you.

well, the method based on NTDLL!DbgBreakPoint (see “try to attach to me: if you can!” ) is not good enough to hurt IDA-Pro. like Ilfak said – just set “Stop on debugging start” checkbox in the debugger options to stop IDA-Pro _before_ NTDLL!DbgBreakPoint. how it’s going to help?! nothing! but we will try. press F7 several times. go to Debug\Open subviews\Open threads. do you see two threads there? one is the main thread of the app, another – the system tread, created by DebugActiveProcess() API. the point is – we don’t need the system thread anymore. we should kill it. why? the debugged application might inject bad code into it. but IDA-Pro does not allow us to kill treats.

OllyDbg does. ok, run Olly, go to Options\Debugging options\Events\Break on new thread [x]. Attach to the to_attach_31.exe. ok, OllyDbg has been stopped. now, View\Threads. do you see two threads there? current thread is the system thread. kill it! (context menu\kill thread). um, the thread does not want to die. don’t worry it’s almost dead. now, click another thread (the main), context menu, actualize it and start tracing the main thread step-by-step or just press F9 to run. the system thread is disappeared. there was injected code displaying “shit happens”, but since the thread has been killed – no shit!!! everything is just fine!!!

this is universal technology. I tested it on large malware/protectors collection and it works well! at least for Olly. for IDA-Pro we need to write a script or plug-in, killing unwanted threads.

ok, forget about NTDLL!DbgBreakPoint. back to IDA-Pro. “Stop on debugging start” is set, IDA-Pro attaches to the process (any process you want) and stops. where it stops? let me see…

NTDLL!77F88B6C ZwRequestWaitReplyPort proc near
NTDLL!77F88B6C mov eax, 0B0h ; NtRequestWaitReplyPort
NTDLL!77F88B71 lea edx, [esp+arg_0]
NTDLL!77F88B75 int 2Eh
NTDLL!77F88B77 retn 0Ch ; << here NTDLL!77F88B77 ZwRequestWaitReplyPort endp

so, IDA-Pro stops at NTDLL!77F88B77, when NtRequestWaitReplyPort NTCALL has been executed, so NtRequestWaitReplyPort (called by CsrClientCallServer) is executed _before_ stop. thus, if we intercept NtRequestWaitReplyPort – it will be easy for us to abuse IDA-Pro or do something unexpected. and IDA-Pro has nothing to do this it.

the problem is: NtRequestWaitReplyPort is very popular function and it’s used not only by debugger. so, we can’t just intercept it. we have to check the caller – the thread ID.

for example:

mov eax, fs:[18h] ; // *TIB
mov eax, [eax+24h] ; // CurrentThreadId
sub eax, [our_tid] ; // ?another Thread
jz to_old ; // => no dbg

; // perform stack overflow
die: push eax
jmp die

; // all ok, passing control to the old func
to_old: jmp ds:[old_NtRequestWaitReplyPort]

I wrote a simple POC, abusing IDA-Pro and OllyDbg. download it, run exe. do you see message – “attach to me”? well, ask Olly to attach. Olly attaches without any problems, but… the string changes to “debugger is detected” and the process is still running. wow!!! of course, we can stop the process and continue tracing, but… the point is – the debugger has been detected. how? I just injected my code into NtRequestWaitReplyPort to set global flag if we’re under debugger. the main thread checks this flag and changes its behavior if we’re under debugger. of course, in this simple case we can fix it after attaching, but imagine what happens if the injected code will wipe out all code of the app or destroy the critical structures or just free a few memory blocks cause random crashes?

OllyDbg stops too late. our code injected into NtRequestWaitReplyPort executes before, and debugger has no control under it. what’s about IDA-Pro? try to attach to to_attach_33.exe (all check box in debug options are set). what do we see? the protection tell us “debugger is detected”, the process is running, but IDA-Pro… freezes. what she is waiting for? and how to save our database? we don’t want to kill IDA-Pro, don’t we? right! kill to_attach_33.exe with Process Explorer. IDA-Pro will return from dead to alive.

IDA-Pro 5.3 fails to attach

IDA-Pro 5.3 fails to attach

well, who will break this simple crack me? who will find the way how to attach to the process do not disturbing the protection?


# attach to me… if you can (part II)

the previous post describes how to intercept attaching, but that way does not prevent attaching itself. as it happens there is a simple and elegant way to block any attaching attempts. just wipe out PEB=>PPEB_LDR_DATA field. the application is running well, the process is present in the processes list of Task Manager/Process Explore, but… it’s not listed in the Olly 1.10/Olly 2.00i attach windows!!!

to_attach_ldr.exe is not present in the attach windows!

to_attach_ldr.exe is not present in the attach windows!

ok, guys another plan! load the file directly into OllyDbg 1.10 in order to debug it. can we debug it? well, yes, but… no. OllyDbg 1.10 does not show us the module list (so, how we’re supposed to set breakpoints on API?) and the map window is empty as well. OllyDbg 2.00i and IDA-Pro 5.3 have no such problem.

IDA-Pro 5.3 can’t attach to the process as well, she just freezes!!! and there is nothing to do but terminate IDA-Pro with all changes we have made. a very nasty bug!

the source code is extreme simple. see it bellow or download.

mov eax, fs:[30h] ; // PEB
mov [eax + 0xC], eax ; // damage LdrData to prevent attaching
// do something
while(1) printf(“\rattach to me [%c]“,x[++a % (sizeof(x)-1)]), Sleep(100);

so, you get it. any ideas how to hack it? does anybody know the way how to attach to the process?

note: Elias Bachaalany checked IDA-Pro 5.4 (both with WinDbg plug-in and build-in win32 debugger). it does not freeze, but attached is code crashed inside NTDLL.DLL and IDA catches a lot of exceptions, so this trick works for IDA-Pro 5.4 as well. it’s not IDA-Pro bug! and IDA-Pro has nothing to do to fix it.


# try to attach to me… if you can!

why we might want to attach to active process? there are zillion reasons to do it. for example, the file is packed and stuffed with many adbg tricks. or, maybe, we found a suspicious process in memory and want to analyze it. maybe something else…

there many ways to prevent attaching: self-replicated and self-debugged processes do it very well, but there is another way. please, download the crack-me (with sources) and try to handle it by yourself.

  • 1) run to_attach_31.exe;
  • 2) run OllyDbg or IDA-Pro;
  • 3) try to attach the debugger to the process;
  • 4.1) in Olly: File => Attach => to_attach_31.exe;
  • 4.2) in IDA: Debug => Attach to process => to_attach_31.exe;
  • 5) see “shit happens” messages;
  • 6) the process is still running and the debugger has no control;
Olly is unable to attach to the process

Olly is unable to attach to the process

well, how it worked? when debugger is attaching to process, a new thread is created. NTDLL!DbgBreakPoint function is called and it’s called by not-exported KERNEL32!_BaseAttachComplete@4. the problem is that the thread is created inside the debugged process, so the debugged process can change NTDLL!DbgBreakPoint. for example, intercept it and terminate the system thread preventing attaching. or… abuse the debugger! why not?! we can do almost everything, including creating a faked thread and attaching the debugger to it!
see the source code.

p = (DWORD) GetProcAddress(LoadLibrary(“NTDLL.DLL”), “DbgBreakPoint”);

// nasty dirty trick – we just overwrite the code of DbgBreakPoint
VirtualProtect(p, 1024, PAGE_EXECUTE_READWRITE, &old);
jmp inject
x_code: mov eax, offset souriz
jmp eax
inject: mov esi, offset x_code
mov edi, p
mov ecx, 2

the code above patches NTDLL!DbgBreakPoint, injecting mov eax, offset souriz/jmp eax code over it. not good! but it’s just a POC after all, so feel free to improve it. anyway it woks!

I tested it under: W2K SP4, XP SP3, S2K3 SP1. please, test the crack-me under other systems. a few people reported that MsgBox, called by souriz() function not appears on the screen. it’s strange. I have no idea why – need more info to find out.

the last question is: how to bypass this trick? I think, the best strategy – just to check NTDLL/KERNEL32 before attaching (via ReadProcessMemory) and restore them if it’s necessary, but… it’s possible to prevent attaching, changing only data and the second problem: in real life we want to know what the program changed exactly. will think how to handle it.

P.S. see comments for more details.