# 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 http://nezumi.org.ru/ida.full.zip.

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

# bug in Process Explorer (a gift for malware)

Posted in bugs on May 4, 2008 by souriz

years ago I found a bug in Process Explorer tool, written by Mark Russinovich. well, not a bug, just misfeature :) Process Explorer tries to determine the start address of a thread, but does this wrong and under certain conditions gives us an incorrect result. I sent a report to Mark, but had got no answer and the bug is still unfixed.

to demonstrate this bug (well, not a bug, just misfeature) I wrote a simple program http://nezumi.org.ru/souriz/va_thread.zip), creating two threads:
the first one – is a normal thread, created by CreateThread API call, the second one – is malware-like thread: program allocates memory on the heap, copies malicious code to the allocated block, and calls Create[Remote]Thread. to simplificate things va_thread.c uses CreateThread, creating a malware-like thread inside its own address space.
* * * va_thread.c doesn’t not inject code into any other process! * * *

thus, we have three threads:
1) main process-thread;
2) “fair” thread, created by CreateThread;
3) “malware-like” thread, created by Create[Remote]Thread on the heap;

Process Explorer correctly determines the start addresses of the two first threads, but stumbles over third, claims that the address is: KERNEL32.DLL+B700h, what is definitely wrong! actual start address should look like 003F0000h (the exact address depends on the heap
allocator behavior).

I don’t know how Process Explorer determines the start address of a thread, but I found my own simply and reliable way to do that. I discovered that the start address of any thread is stored at the bottom of the user stack in the second or third dword, followed by lpParameter. this trick works under Windows 2000 and Server 2003, I didn’t check it out under XP yet, but I hope, it’ll be the same (is there someone who wants to check it under XP? plz, tell me what
you’ll get).

I wrote quick-n-dirty utility proc_list.c correctly determines
the start addresses in the most cases and discovers malware, injecting shell-code into process by allocating memory via VirtualAllocEx, or loading malicious dll via creating remote thread and passing address of the LoadLibraryA/W with name of malicious dll in lpParameter.

* if malicious code is on the heap, the start address of the malware-thread belongs to MEM_PRIVATE block (instead of MEM_IMAGE like normal exe/dll does);

* if malicious code is injected via dll, the start address of the malware-thread matches the address of LoadLibraryA/W.

I checked this method on a quite big malware collection and got a good result.

$proc_list.exe > out.txt
* * * PROCESS INFO * * *
szExeFile : va_thread.exe
cntUsage : 0h
th32ProcessID : 58Ch ; <- we need to know ProcessID
th32DefaultHeapID : 0h
th32ModuleID : 0h
cntThreads : 3h
th32ParentProcessID : 668h
pcPriClassBase : 8h
dwFlags : 0h
cntUsage : 0h
th32ThreadID : 6B4h
th32OwnerProcessID : 58Ch ; <- va_thread.exe
tpBasePri : 8h
tpDeltaPri : 0h
dwFlags : 0h
handle : 3D8h
ESP : 0012FF84h
EIP : 77F883A3h
start address : 00401010h ; <- main thread
point to args : 00000000h
type : MEM_IMAGE ; <- normal thread
[0012FFF0h: 00000000 00000000 00401010 00000000]

cntUsage : 0h
th32ThreadID : 668h
th32OwnerProcessID : 58Ch ; <- va_thread.exe
tpBasePri : 8h
tpDeltaPri : 0h
dwFlags : 0h
handle : 3D8h
ESP : 003EFF80h
EIP : 77F883A3h
start address : 00401000h ; <- “fair” thread
point to args : 0012FFC8h
type : MEM_IMAGE ; <- normal thread
[003EFFF0h: 00000000 00401000 0012FFC8 00000000]

cntUsage : 0h
th32ThreadID : 764h
th32OwnerProcessID : 58Ch ; <- va_thread.exe
tpBasePri : 8h
tpDeltaPri : 0h
dwFlags : 0h
handle : 3D8h
ESP : 0050FF80h
EIP : 77F883A3h
start address : 003F0000h ; <- heap block
point to args : 0012FFC8h
type : MEM_PRIVATE ; <- malware thread
[0050FFF0h: 00000000 003F0000 0012FFC8 00000000]

# other solutions: how to load two or more files into the same IDA-Pro database

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

Ilfak describes three ways how to load several files in one IDB.

first solution: use pe_dlls.idc IDC-script, written by Atli Mar Gudmundsson (the original link is broken, was fixed, and then broken again. so, download it from OpenRCE). this is a really good script. guess what it does? well, it loads all dlls using by the main file and supporting recursive loading. wow! it’s easy-to-use and reliable. but… it works with PE files only and what if I want to load ELF or two NT-drivers or linux kernel modules?! my plug-in handles this, coz it uses IDA loaders, so it supports all formant supported by IDA. however, I recommend you pe_dlls.idc, since, I just love it.

second solution: Ilfak tell us: use the debugger and take the memory snapshot. very well! everyone knows about this trick and does it almost everyday. this is best way to analyze packed file – just run the program, dump it with your favorite dumper and disassemble the dump. don’t care about restoring import table or something like that. dumped program might be unable to run, but it’s quite enough to analyze it. however, this strategy doesn’t work with trickily protections as well as drivers

third solution: IDA Debugger are involved. what I can say?! theoretically, we can get accurate dump, including only those DLLs we need, however, IDA has _extremely_ “weak” debugger and almost any protection is able to defeat it. how we’re supposed to analyze malware packed with modern protectors?! I simple don’t know. this is not my way. this is very restricted way (is it possible to load drivers or something like that?!). the answer is no.

so, use my plug-in. it’s really simple, useful and supports every file-format, supported by IDA. it also allow to load user-land and kernel-land files at the same time

# how to load two or more files into single IDA Pro database

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

a man asked me: is it possible to load two or more files into the same single IDA Pro database. for example, we have NOTEPAD.EXE and want to load two additional files: KERNEL32.DLL and NTDLL.DLL to see how they interact with each other.

as an author of “thinking in IDA Pro“, knowing her internals like my own pocket (IDA Pro is a female name and, yep, I don’t know what I might find in my pocket next time), I said: yep, it’s simple. no problem, man!

IDA Pro has linear address space emulates x86 CPU flat memory model (well, not only x86, it works with other CPUs too). the loader loads a file into virtual memory and does everything has to be done.

there is two solutions to load more files

first: we load the next file as an additional binary file (menu File, Load file, Additional binary file…). IDA Pro does nothing, just load the file, leaves us to parse all internal PE/ELF structures (I saw some IDC-scripts, written by Symantec team, but don’t remember the link). this is tedious job, so, thanks, but no thanks!

second: we use IDA Pro function: bool ida_export load_nonbinary_file (const char *original_file_name, const char *real_file_name, const char *sysdlldir, ushort _neflags, load_info_t *loader), where “loader” – result returned by load_info_t *ida_export build_loaders_list( const char *filename), – see \IDA\SDK\include\ loader.hpp. of course, we have to free the pointer with qfree function (see file pro.h).

this is all. well… since we have linear address space, we must avoid file overlapping, that means all files are supposed to have different base addresses. if they are match – we must to re-base one of them before loading (if files have relocations it’s very simple, otherwise, extremely tricky, however, it’s possible).

so, we come to plug-in, looking like this one:

void idaapi run(int arg)
load_info_t *ld;
warning(“plugin \”dual-load\” is called!”);

/* NOTE: KERNEL32.DLL and NTDLL.DLL has to be in the current directory!!! */
ld = build_loaders_list(“KERNEL32.DLL”);
load_nonbinary_file(“KERNEL32.DLL”, “KERNEL32.DLL”, “.”, NEF_SEGS | NEF_RSCS | NEF_NAME | NEF_IMPS | NEF_CODE, ld);
/* qfree(ld);

ld = build_loaders_list(“NTDLL.DLL”); */
load_nonbinary_file(“NTDLL.DLL”, “NTDLL.DLL”, “.”, NEF_SEGS | NEF_RSCS | NEF_NAME | NEF_IMPS | NEF_CODE, ld);

ok, we load notepad.exe into IDA Pro, call our plug-in and… have a fun!!! notepad.exe, kernel32.dll and ntdll.dll are loaded into the same idb-database! the only problem is: IDA Pro doesn’t create cross-references between them. I mean, if you analyze notepad.exe, move the cursor to call ds:GetModuleHandleA, press “enter” and… nothing happens! you’re into the import table of notepad.exe. and where is the export? somewhere… but, this is not a problem, really, since, we can find GetModuleHandleA in the “Names Windows” (called by Shift-F4) or write a simple IDC-script to create cross-reference between import and export, it’s like to build a bridge :-]

I think, we all have to ask Ilfak for this feature, why just don’t add it to user menu? it would be _very_ usefully.

a new(?) bug in Olly [776]

Posted in bugs on April 23, 2008 by souriz

I’ve found a bug in Olly leading to crash SEH/VEH-based programs during tracing. (an example-pack could be found at: http://nezumi.org.ru/olly-bug-776.zip, it includes two SEH/VEH programs and requests XP or latter to run VEH, while SEH works everywhere).

Load an example into Olly and start tracing [F7] /* we can skip the first call by pressing [F8] (Step Over), since it has nothing interesting for us */

xor eax,eax/mov eax,[eax] generates an exceptions, catching by OS kernel. the kernel saves registry context (including TF-bit, set by Olly to “1”) and passes control to NTDLL.DLL!KiUserExceptionDispatcher function – the first user-land function executes after an exception. it calls SEH/VEH handler (if there is at lest one).

if the handler returns control to the code, where the exception was raised, registry context (including TF-bit) is restored by OS kernel. everything is fine, yes? hell, no!!!

Olly catches NTDLL.DLL!KiUserExceptionDispatcher and offers us to press Shift?F7/F8/F9. Olly allows to trace KiUserExceptionDispatcher, but totally forgets to clean TF-bit. as result – when control is passed the to original code (to the command follows mov eax,[eax] in our case, since handler adds 2 bytes /* size of mov eax,[eax] */ to EIP), TF-bit is set!!! so, a new exception occurs and SEH/VEH handler is called again and over again, coz, Olly passes this exception to the program, coz it forgets who “owns” this exception!!!

since, SEH/VEH handler doesn’t expect to handle trace exaction, we have an undefined behavior (a crash).


it’s definitely a bug!!! and how we can to fix it?!
well, it’s very simple. look at the prototype of KiUserExceptionDispatcher(EXCPT_REC *pExcptRec, CONTEXT *pContext). everything we need – is just to take pContext and clear TF-bit manually. pContext is the next DWORD on the stack and EFlags has C0h offset, while TF-bit is the first bit of the next word (1 << 8). just clean it and enjoy! press [F9] to Run the program or do whatever you want!

of course, we can create plug-in, doing it automatically, or set-up a conditional breakpoint on KiUserExceptionDispatcher.

I’ve checked the latest 2.00e version [April 19, 2008] and… the bug is still there, damn it!

I reported about this bug to the Olly creator and he admitted it, writing me back:

# Dear Kris,
# thank you for your bug report. I will try to remove it from v2.0 ASAP.
# Sincerely, Olly

Hello world!

Posted in Uncategorized on April 20, 2008 by souriz

Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!