Log in

View Full Version : Finding elusive constants


5aLIVE
January 16th, 2009, 11:03
I'm getting quite close reversing an app which uses MD5 as part of its key generation scheme.

All the 64 rounds constants and chaining variables are not modified in the MD5.
I know that the two strings of interest are being read from a file which are used in some way to change the digest output. They are not being passed as arguments to the MD5 algo.
One string has 8 digits and the other has 9.

I've created two run trace logs of the MD5 algo, I've entered the correct known password for each run.

One trace using the correct two string values and one where I have modified these values in the file. I've looked at the traces side by side and have been able to find where the registers values start to differ from one another.

Once I found this area, I ran the debugger again just before this code expecting to see a reference to at least one of the strings. I can't seem to find either of them.

Can anyone help suggest techniques or tips on how to take the pain out of this please?

I'm using OllDbg, is there a way log values loaded to memory in run trace or a plugin perhaps? Or maybe there is another more way I don't know of?

I've also tried searching for the binary string (Ctrl-B) which doesn't find it too.

vvw
January 17th, 2009, 19:15
Perhaps the strings are undergoing a transformation before entering the hashing routine?

I would place a breakpoint on CreateFileA/W when it opens your file, and then place a breakpoint on ReadFile (if they are using the CRT its ok because fopen, fread, end up calling CreateFile and Readfile under the hood) step over it until the contents of the file are read into the lpBuffer paramater. Once the ReadFile has completed (beware asynchronous reads!) place a read memory access breakpoint on the address within the buffer where your data resides. This will allow you to track the data throughout the system. In all liklihood that data will be copied out of the buffer into some other object or struct, (you will have to place another memory access breakpoint there and keep tracking it) if it undergoes some transformation you will be able to catch it.

-vvw

5aLIVE
January 18th, 2009, 12:59
Thankyou very much for the tips.

I have now beeen able to identify the read buffer which holds the two strings of interest. If I edit these values in the buffer and set a breakpoint (hardware or software) on access I can recreate the incorrect password error I saw when I edited the file contents directly. I am confused that this beak point isn't triggered to allow me to track the strings destination(s).

Actually, the only time the breakpoint is trigerred is when the buffer is emptied/closed.

Incidently, the APi I break on is _lread which is is much the same as ReadFile. What could I have overlooked?

blabberer
January 19th, 2009, 12:23
you can try searching the whole memory
alt+m -> right click -> search for text -> either ascii or unicode
and set breaks on all possible locations if it broke
take a look on call stack find some earlier function examine that function
break there and then trace maybe

referances can be obfuscated or might be generated during runtime and static searching wont reveal them

vvw
January 19th, 2009, 16:28
_lread is a very thin wrapper around ReadFile.

As for why your break on read access breakpoint didn't get hit.... Is your breakpoint on a DWORD aligned address? Memory could be getting read and/or subsequently copied out of the buffer by an optimized inline memcpy using a rep movsd instruction. More often than not, this is the case. For example, if lpBuffer lives at 0x12ff00 and you put the break on read access at 0x12ff01, your breakpoint wouldn't get hit because memory would only get accessed at addresses 0x12ff00, 0x12ff04, 0x12ff08, etc

Check that first. Also, do some static analysis with IDA. If your target is not packed or obfuscated, you can examine the code surrounding that call to _lread and see what he does with that buffer.

dELTA
January 23rd, 2009, 15:12
A little late, but still, for reference:

The following OllyDbg plugin (which is made by some really handsome guys btw ) does not trace any values, but it does help you to quickly track down any differences in the exact execution flow of two different executions of a (part of a) program, which I guess could also be of help in a situation like this:

http://www.woodmann.com/collaborative/tools/Conditional_Branch_Logger

Also, regarding tracing the contents of values, the following plugin would most likely only need some small changes to do what you were looking for:

http://www.woodmann.com/collaborative/tools/OllyStepNSearch

5aLIVE
January 24th, 2009, 11:58
Thanks to all for the advice, its helped me make a bit of progress with this.

I've found a function that asynchronously reads the string characters one by one from the 4KB _lread buffer which places a copy of the extracted
string on the stack and then accessed by another function.

Placing a memory-on-access BP on this new copy breaks as you would expect, however, it only breaks when it is being overwritten with another
string.

My next step is to determine what this function does to the string passed to it.

dELTA, thanks for suggesting these plugins to try. I'll give them a go and see if they help me in my quest.

<update>I tried the OllyStepNSearch plug which succesfully found all the references I found by hand but no additonal refs.
Still, its a handy tool to have, and one I'll use again I'm sure.

5aLIVE
January 25th, 2009, 08:55
Found them!. vvw your suggestion that it was being transformed before entering the hashing routine was correct.
Each string of numbers is converted to an integer before being passed to the handler. The function that uses these integer values is called just before the MD5 algo as expected.

All that remains is to analyse how this little function works and I'm done.