Log in

View Full Version : Help in reversing this function in a game


Technomancer
June 9th, 2006, 20:33
Hi guys. I am kind of lost here. I am reversing a game now and i am trying to print text in the game. I followed an example of a hacker who already successfully reversed that part i am stuck at.
This is how the hacker "emulated" the game's method of Printing text :
Code:

PUSHAD
MOV EDX,<own address pointing to a string>
PUSH 0Fh
POP ECX
CALL 43D064 ;Here is where he calls the TextPrinting function
POPAD
RETN


I will paste what is at the 43D064 and what happens prior to the call.

Here is what happened prior to the call to the TextPrinting Function :
Code:

* Possible StringData Ref from Data Obj ->"\Game.ini"
|
:00409B0D 685C444800 push 0048445C
:00409B12 50 push eax
:00409B13 E878020600 call 00469D90
:00409B18 59 pop ecx
:00409B19 8BC6 mov eax, esi
:00409B1B 59 pop ecx
:00409B1C 8D8DACFEFFFF lea ecx, dword ptr [ebp+FFFFFEAC]
:00409B22 51 push ecx
:00409B23 8D4DB0 lea ecx, dword ptr [ebp-50]
:00409B26 C1E002 shl eax, 02
:00409B29 6A50 push 00000050
:00409B2B 51 push ecx
:00409B2C FFB06C434800 push dword ptr [eax+0048436C]
:00409B32 FFB07C434800 push dword ptr [eax+0048437C]

* Possible StringData Ref from Data Obj ->"NetMsg"
|
:00409B38 6854444800 push 00484454

* Reference To: KERNEL32.GetPrivateProfileStringA, Ord:014Fh
|
:00409B3D FF1590914700 Call dword ptr [00479190]
:00409B43 8D55B0 lea edx, dword ptr [ebp-50]
:00409B46 83C9FF or ecx, FFFFFFFF
:00409B49 E816350300 call 0043D064


Here is what happens at 43D064 the text printing function itself :
Code:

:0043D064 55 push ebp
:0043D065 8BEC mov ebp, esp
:0043D067 83EC54 sub esp, 00000054
:0043D06A 53 push ebx
:0043D06B 56 push esi
:0043D06C 8BF2 mov esi, edx
:0043D06E 57 push edi
:0043D06F 56 push esi
:0043D070 8BF9 mov edi, ecx
:0043D072 E819C90200 call 00469990


Any greater minds here can offer help as i don't really understand the hacker's theory behind his "hook". Basically, i understand that arguments are moved into ecx and edx prior to the call to 43D064 (which will mean it is a fastcall probably?) @ 43D064 itself, what is stored in ecx and edx is passed to esi and edi ... probably for string-related activities.

What i am puzzled about is, how does the hacker determine from a whole chunk of code that there are only 2 arguments (stored in ecx and edx) required prior to the call to 43D064. Also, there was a part where "or ecx, FFFFFFFF" was used prior to the call. Usually, why is there a need to OR a register with all FFFFFFFF ? The hacker substituted that with PUSH 0Fh
POP ECX (which is essentially mov ecx,0Fh). Can anyone guess what is this for?

I am mainly confused because prior to the call to 43D064, there were so many registers and variables being moved around. How did the hacker smartly guessed that only ecx and edx are the important ones ? Also i assume the game used GetPrivateProfileString for a reason?

0xf001
June 9th, 2006, 20:56
hi,

look more at the code it will answer all your questions . the hacker was probably debugging the program or looking what registers the called function actually uses in its code. you can see this in the functions disassembly (effectively before the function calls 00469990 it uses the values from edx and ecx and pushes them onto the stack probably as parameters).

the code prior to the call reads a value from a config file, the or instruction just sets all bits and further only the lowest nibble of that value will be most probably used, when the hacker only pushes 0xf
another possibility is that those values have a meaning whereby 0xffffffff often stands for -1

regards, 0xf001

Technomancer
June 10th, 2006, 00:32
Some further questions.

Code:

:00409B43 8D55B0 lea edx, dword ptr [ebp-50]


[ebp-50] stores the pointer to the text buffer of the game which is the tutorial said is 004DA498. So, 004DA498 stores the text in a buffer that will be printed out in the game (eventually). Obviously it is a local variable since it is negative to EBP.

So if i actually want to find the address 004DA498 from scratch, i can't use a memory searcher since it is a local variable. I have to use a debugger. I am thinking of BPXing a string like <hello munchkins> and then typing and sending out "hello munchkins" text in the game to see if i get a break. But some questions here.

1. Is it possible to set a breakpoint for an entire string like "hello munchkins" using ollydbg ? What's the command?

2. Are there any better methods than what i mentioned in trying to find the address 004DA498 ?

Thanks in advance for helping.

LLXX
June 10th, 2006, 00:41
Do a bpx 409b43 in your program's execution context. You'll see the lea get executed and can find the address from there.

Technomancer
June 10th, 2006, 04:22
Quote:
[Originally Posted by LLXX]Do a bpx 409b43 in your program's execution context. You'll see the lea get executed and can find the address from there.


Thanks. But if i was starting from scratch, i won't even be able to reach that routine.

Basically what i want to know is, if there is a way to set a breakpoint to a string or search for a string in olly.

I want to find the address of the buffer storing the text_tobe_printed but yet it is a local variable. There must be a way around this using a debugger, i am just not sure how.

Admiral
June 10th, 2006, 08:07
The most effective (if somewhat slow) way to break when a register contains a value is to run a trace. 'Set Condition' to 'EAX == "hello munchkin"' (or use a disjunction on registers & strings to cover your bases) and hit 'Trace Into'. You're advised to start the trace as close to the event as possible, as tracing from the EP could take hours.

You ask why 'OR ECX, FFFFFFFF' was replaced by 'MOV ECX, 0F'. Although the opcodes are different, both instructions simply put a constant value into ECX. The former sets ECX = -1 (try it out) and the latter ECX = 10d. If I had to guess at whet this parameter was I'd compare it to the length of the string being printed. Many string processing functions accept 'length' as a parameter where -1 specifies the string is null-terminated.

If you're looking for a battle plan on how to locate this output function from scratch, here's how I would do it:
Play the game a little and find a default string which is printed regularly (or one that can be displayed at will). Now fire up your debugger, run to the point where the engine is up an running (so that any strings will present in memory) and perform a memory search for your target string in both Unicode and ASCII. Set a breakpoint on each instance of the string then run a few times to try and determine which instance is the original copy (noting that it may be copied around a bit before getting dumped to the screen). You may find it helpful to overwrite a part of the string and run further to see if the GUI output changes accordingly. Also, string resources tend to come in batches, so if the target string is surrounded by others that you recognise, you may well be in the right area.

Once you've found the location at which the string originates, remove all your memory breakpoints other than this one and run again. When your target breaks, it's up to you to do some creative manual tracing, making regular use of the call stack, keeping track of any copies (local or global) of the string until you find the point where it gets printed (being aware that this may be a long way from the loading instruction). Once you've found, analysed and understood the relevant function the rest should be history.

Regards
Admiral

0xf001
June 10th, 2006, 08:18
Admiral, 0xf == 15d btw (also theres push 0xf, not mov in the hackers disassembly)
the whole thing is not so complicated, please technomancer spend a bit of time looking at the disassembly, also use the new old ollydbg forums to get tips abt debugging, and the search button on top of the page. ida shows you string data references. we won't give you a pre baked solution

regards, 0xf001

VeeDub
June 11th, 2006, 20:43
Quote:
[Originally Posted by Technomancer]Basically what i want to know is, if there is a way to set a breakpoint to a string or search for a string in olly.


Hi,

I'm not sure if this is what you want to do, but ...

Once the target is loaded, you set a breakpoint just somewhere during it's processing, then

- select View / Memory
- Right click on the Memory Map and search for the string (could be ASCII or Unicode)

If you find the string:

- highlight the first byte of the string, right click and use 'Breakpoint, Memory on access'

Often this works, occassionally I have observed unusual behaviour, and have used 'Breakpoint, Hardware on access' instead.

VW

Technomancer
June 12th, 2006, 20:54
Quote:
[Originally Posted by "Admiral"]You ask why 'OR ECX, FFFFFFFF' was replaced by 'MOV ECX, 0F'. Although the opcodes are different, both instructions simply put a constant value into ECX. The former sets ECX = -1 (try it out) and the latter ECX = 10d. If I had to guess at whet this parameter was I'd compare it to the length of the string being printed. Many string processing functions accept 'length' as a parameter where -1 specifies the string is null-terminated


Admiral : Thanks. That explains everything. But one question, how does it work out such that -1 means the string is null terminated. I just want to know for knowledge purposes.

LLXX
June 12th, 2006, 22:57
It's because length-delimited and null-delimited strings are being used by the program, so instead of duplicating code for handling each version, a single function can be used. A simple strlen (inlined in many cases) is enough to interface, e.g.
Code:
inc ecx
jnz .is_ld
call strlen
mov ecx eax ; i've never seen a standard strlen return in ecx
db 168 ; skip over if got from strlen, else have to dec (compensate for inc)
:is_ld
dec ecx