Archive for May, 2008

#773: bug in IDA-Pro [fails to debug zero-based PE]

Posted in bugs on May 14, 2008 by souriz

IDA-Pro embedded debugger doesn’t support PE files with zero image base.

the debugger says (I quote):
“IDA Pro couldn’t automatically determine if the program should be rebased in the database because the database format is too old and doesn’t contain enough information. Create a new database if you want automated rebasing to work properly. Notice you can always manually rebase the program by using the Edit, Segments, Rebase program command”.

I have checked 4.7 (standard) and 5.2 (advanced) versions – they are both buggy.

after pressing F9 debugger loses the control, ignores breakpoints (!!!) allowing to the process running on its own, breaking through the debugger!!! really bad news for malware researchers!

to know your enemy – write a simple “hello, world” application and build it as follows:

# ida-bug-773.c
ExitProcess (MessageBox (0, “after one bad thing another follows”, “sudah jatuh, ditimpa tangga”, 0));

# building ida-bug-773
cl.exe /c /Ox ida-bug-773.c
link.exe ida-bug-773.obj /FIXED:NO /BASE:0 USER32.LIB

ignore linker warning! (after all, it’s just a warning). the file has zero image base, but works fine, coz windows automatically rebases it to the appropriately place. IDA-Pro does rebases files by default, since she doesn’t reserve lowest part of address space like windows does.

to debug the file with IDA-Pro debugger we have to rebase it before debugging: /Edit/Segments/Rebase program/Target, where Target is 0x40000 or something like that. we can use ms editbin.exe tool (if IDA-Pro is unable to rebase the program, however, if the program checks PE-header, it definitely find out that the file was rebased).


# Syser causes BSOD

Posted in bugs on May 9, 2008 by souriz

a new bug in Syser was found. download this file, unpack it and run make-all-and-run.bat.
under XP SP2 with Syser we have BSOD:

# BugCheck 100000D1, {45b0, ff, 0, f580aa75}
# Probably caused by : Syser.sys ( Syser+aa75 )

this is _very_ strange, since the program causes crash – is a user-mode application, or, to be exactly, there are two programs – one traces another to find out NT bug: OS kernel doesn’t zero TF bit on faults (see this post for more detail), leading to crash OllyDbg, but OllyDbg just refuses to debug, while Syser causes BSOD. not good :=( excellent way to defeat Syser, although :=)

the bug was located
rebuild PeterFerrie.exe with following options and forgot about BSOD:

$link.exe PeterFerrie.obj /ENTRY:nezumi /SUBSYSTEM:CONSOLE KERNEL32.LIB

the previous ones were:

$link.exe PeterFerrie.obj /FIXED /ENTRY:nezumi /SUBSYSTEM:CONSOLE /ALIGN:16 /MERGE:.rdata=.text /STUB:stub KERNEL32.LIB

I’m too lazy to check every combination to find out which one triggers BSOD. it might be /ALIGN:16 or section merging or incorrect ms-dos stub (I just truncated file at the end of MZ-header without fixing size of the file – windows doesn’t check it).

I sent my report to Syser team, but got no answer. never mind. it’s probable nothing. however, the bug gives a great opportunity to malware-writers, so it has to be fixed.

# old CD 03 bug in windows

Posted in bugs on May 9, 2008 by souriz

coming soon!

# turbo-import [stealth anti-api-monitors style]

Posted in optimization on May 9, 2008 by souriz

coming soon!

# bug in Olly, Windows behavior and Peter Ferrie

Posted in bugs on May 9, 2008 by souriz

PeterFerrie strongly disagreed with me, pointed out, that this is not only the Olly bug.
The not a problem in OllyDbg, it’s a Windows behavior. Try it without any debuggers and you will see the same thing. I found the same while researching my new paper.
If you set the trap flag then cause an access exception, you’ll get a trap exception before the access exception. That’s the Windows behavior, even without a debugger. Interestingly, it doesn’t happen in a VM. OllyDbg is setting the trap flag before the exception occurs. That’s why you see the behavior. If something else set the flag, you’d still see the behavior.

ok, my bad, he won! I admit it.
to make long story short:
in general, TF-bit is zeroed automatically every time single step exception is generated, so to continue tracing you have to set it again. however, if CPU generates access violation exception, illegal instruction exception or any other fault like this, kernel doesn’t clean TF-bit and keeps it in registry context. after that, kernel cleans TF-bit and calls ntdll!KiUserExceptionDispatcher, KiUserExceptionDispatcher finds and calls SEH-handler(s), gets control back and calls ntdll!NtRaiseException, passing registry context (where TF bit is set!!) as an argument. NtRaiseException asks kernel for passing control to the current process. kernel begins to restore registry context, restoring TF-bit _before_ control is passed. as result – kernel generates single step exception and calls KiUserExceptionDispatcher again, keeping TF-bit unchanged (setting), so, CPU executes the first machine command of KiUserExceptionDispatcher and generates single step exception, passing it to kernel. wow! kernel catches single step exception, cleans TF-bit (wow!!! TF-bit finally is cleaned!) and calls KiUserExceptionDispatcher, passes exception record with context.Eip = (ntdll!KiUserExceptionDispatcher + 1). why plus one? due to single step exception is a trap, not a fault.

how KiUserExceptionDispatcher is supposed to handle this?! well, it just try to find SEH-handler(s), ready to accept this exception and passes control to them. since, expectations are reenterable, everything works fine (of course, if SEH handler is able to handle the unexpected exception of ntdll!KiUserExceptionDispatcher, the best strategy – just ignore it)

but Olly is unable to do this!!! try to trace the program we’re talking about with Olly, trace it until ntdll!KiUserExceptionDispatcher –} ntdll!NtRaiseException and… ops!!! Olly tells you that “debugged program was unable to process exception“.

I recalled that I discovered this windows bug years ago, when I was working on my debugger, but… I just cleaned up TF-bit in the EXCEPTION_DEBUG_EVENT handler and totally forgot about it. and besides, any other debugger does the same – take Soft-Ice for example! (btw, right now I’m porting soft-ice to Vista and Server 2008, making a special bit-hacking patch)

P.S. in few day I’m going to publish more detailed post.

# eternal life, ammo, scores in games

Posted in Soft-Ice tips-n-tricks on May 7, 2008 by souriz

a man asked me how to find where games keep scores, eternal life or ammo. the answer is simple and I doubt is it worth to be published here or not. well, let’s try and see.

as a general rule, scores are stored “as is”, I mean: if you have 666 scores, some memory cells keep 9Ah 02h (dec2hex, and remember the byte order, the less significant byte comes first).

you don’t need IDA Pro to do that. use any memory dumper. personally, I prefer soft-ice (dumping memory via history; another way to do that is using extensions like IceExt), but there is a lot of dumpers anyway.

ok. check your safety belts, we’re blasting off:
1) dump the process when you have the certain score;
2) dump the process again with the same score, but something different (move player to the next place for example, open a door, etc);
3) do something to change the score and dump the process once more;

ok, you have three dumps with two different scores.

1) compare first two dumps to find unmatched bytes – they are definitely not the score (since, first and second dumps have the same score);
2) delete the unmatched bytes out of the dumps;
3) compare first and third dumps to find unmatched bytes – some of them definitely keep the score;
4) find the best candidates for “scores”. if you’re lucky, you have only one hit equaling to scores, which you got in the game. but quite often you have two or more locations, keeping the scores (or something looks like). some of them – is nothing just false positives (more dumps – less false positives), but some of them are natural “copies” of “original” score. the program can store the score-value in the global variable, passing it to many functions, so you have to find out which one is genuine. it’s simple. just change the memory cell with your favorite debugger return to the game. if the score-window doesn’t react, you’re dealing with “forgery”. try the next one. however, score-windows might accept your value, entered in the debugger, leaving the actual score unchanged. this is because of using local copy of original score variable for score-window;

5) ok. you have found the exactly memory location of the original score variable – set hardware breakpoint on access and debugger helps you to discover the code reading or writing it;

6) modify the code as you wish, for example, if it adds 10 points, you might change 10 to 100;

btw, to compare dumps, I wrote quick-n-dirty utility. yeah, it’s a very silly tool, so feel free to rewrite it.

// usage: fck.exe dump_1 dump_2 dump_3 ... dump_n
// note: find the "hot" bytes.
// dump_1 and dump_2 are supposed to have matched "hot"-bytes,
// while the other dump are supposed to have unmatched "hot"-bytes.

#define MAX_DUMPS 0x10
main(int c, char **v)
int pos=0;
int a,b,flag;
unsigned char ch[MAX_DUMPS];

if (c-- < 4) return printf("-err: need more files\n");

for (a=0;a<c;a++)
if (!(f[a]=fopen(v[a+1],"rb"))) return printf("-err: cant open %s\n",v[a+1]);
printf("raw offset");for (a=1;a<c;a++) printf("\t%s",v[a+1]);

for(a=0;a<c;a++) if (!fread(&ch[a],1,1,f[a])) return 0; pos++;
if (ch[0] - ch[1]) continue;
for(a=flag=1;a<c;a++) for(b=a;b<c;b++) if ((a-b) && (ch[a]==ch[b])) flag=0;
if (flag) for (printf("\n%08Xh:",pos-1),a=1;a<c;a++) printf("\t%02Xh",ch[a]);
} printf("\n");

# thinking in IDA Pro – how to obtain a copy

Posted in IDA-Pro tips-n-tricks on May 5, 2008 by souriz

wow! I see some ppl ask google for “thinking in IDA Pro” and feel obligations to say: this book was written in rus and never translated to eng. the exactly name is “образ мышления – IDA” (obraz mishleniya – IDA). it’s quite obsolete now, however, if you know rus and don’t mind to download less than a megabyte – welcome to

I’m going to write the new one, so… follow the news!