[MSLRH] v0.2 - manually unpacking tutorial

Monday, September 05 2005 @ 12:02 AM CEST

MSLRH 0.2 is quite simple protector with one interesting function. It has option to
emulate Entry Point of SFX code with signature bytes from others protectors/packers
to fool PEiD. This tutorial will try to descrybe this protector.

1. Tools and requirements>

- OllyDbg 1.10
- LordPE
- ImpREC
- Target and packer itself is here in this archive [bin]
- Tutorial was written on windows XP, don't know will it work on other systems.

2. Studing protector

First, uncheck all exceptions in olly debug options except those in kernel32.

Open our target file keygebme1.exe in Olly and take look at next picture. Ups, before
that scan file with PEiD to see what PEiD will sad about packer. PEiD gives "SVKP 1.11 ->
Pavol Cerven". PEiD is wrong. Problem is that PEiD has small signature for SVKP so it can
be very easy emulated by another packer or even you can throw it in some of yours programs.
And this is just what this packer is doing. It can emulate couple well known packers /
protectors to confuse some unexperienced cracker. But it is not hard to find that MSLRH
is what we have under our hands. Lets see how it looks:

I think that comments on the picture are enough to understand. Tracing and examing is
hard with all this junk and I wrote simple script that will remove most of junk. Run that
script (but when you are asked to use second part of the script, select NO) and then we
will go to examne code. Now is code really easy to read and you can see that this packer
doesn't have much of it's code. First thing that we will meet is RTDSC check. After using
script, there will be lot of NOP's around here so I didn't paste whole code fom olly. Here
is interesting part:

RDTSC returns number of clock cyles to EAX (that is some number of instructions that has been
passed until that moment in whole system), then that value is pushed to stack and again is
called RDTSC which gives to EAX new value. Then those values are substracted. If you trace
trough program slowly, that difference will be much bigger and packer will assume that it has
been debugged. But if you just place bp on good spot and run it, that difference will be below
FFF and packer will not notice us. Not something that will slow us. Ok, there is nothing
interesting now for a while so scroll all way down up to this place:

First packer prepares for exception handling. Ok, you may ask, what the hell I'm talking about now.
This is not tutorial about exceptions so here is a quick and short info:

"The idea of exception handling (often called "Structured Exception Handling") is that your
application installs one or more callback routines called "exception handlers" at run-time and
then, if an exception occurs, the system will call the routine to let the application deal with
the exception. The hope would be that the exception handler may be able to repair the exception
and continue running either from the same area of code where the exception occurred, or from a
"safe place" in the code as if nothing had happened."

Our packer has installed exception handler here

004089BD PUSH DWORD PTR FS:[0]
004089C4 MOV DWORD PTR FS:[0],ESP

and then it will make one exception, INT 3.
If we don't understand how to manually deal with this or any kind of exceptions, we will make
something wrong and crush our program. But we can pass this in a such way that we left program
and windows to deal with exception as they do it without presence of debugger. We can do that by
simoly pressing Shift+F9. But there we have one problem - we don't know from which point after
exception program will continue it's normall work further. Well, I know from which point it will
continue, but that is very hard to find in obfuscated programs and also, that point can be anywhere
in the code. But this packer is after removing junk really easy to follow and we can find our
point after scrolling down:

This works something like PUSH-POP. Maybe I'm not quite right, but newer mind that. Below this you
will see one JB and lot of some junky code below. Take look at picture and you'll get clear all.
Code below JB is encrypted and this small loop wil just decrypt it. Do it and there you will find
procedure that will get address of GetProcAddress API, then check is it breakpoint placed on it, and
then it will enter in second decryptor loop which will decrypt another part of code below it:

After code below is decrypted, trace to there. This code is little obfuscated but you will
see that it's purpose is to get some API addresses using GetProcAddress and that it checks
for bp on every API and then it calls it. Example:

Does that look familiar? Yes, it is again those macro junk code, use script for cleaning
again (and again chose NO for second part). Good, everything is clear now. Again, we have
same RDTSC checks and one INT 3, just ignore all because this decrypted code there is nothing
new or interesting. Scroll down to the this place which was not encrypted from the very beggining
of protectors code:

0040C735 CALL keygenme.0040C73A

That pice of code which is little obfuscated hides procedure that decrypts original code
section of packed program. Now is time to use second part of my de-junk script. After usage
(I removed NOP's to reduce size of text) you will get picture like below. This part calculate
some CRC walue from protectors code and then it decrypts code section of packed program with
that value. It also holds some stolen bytes. Check my comments:

Protector has decrypted code section, but with bad CRC value because we have remove junk
code so code section is destroyed and not decrypted. Also, this last PUSH 6262C0 holds value
that subtracted with CRC value gives OEP address of packed program.
This SUB DWORD PTR DS:[ECX+15],EBX will subtract it and we should get OEP to which will last
RETN throw. But again, because we modified code, that value is incorrect and our program will
crush just for that. Also that is not quite correct OEP because we have couple stolen opcodes
from OEP, but that is not problem. How to fix that? Read next chapter.

3. Unpacking

This is really easy job now when we know what we have to do. Restart target in olly and use
IsDebuggerPresent plugin to hide olly. Then set in the command line hardware breakpoint on
execution on OutputDebugStringA API (hardware because normal-software protector can find). It
goes like this "he OutputDebugStringA" and hit ENTER button. In Olly debug options IGNORE ALL
exceptions this time, we don't need them anymore. Run target and you should break in kernel
to our debug string API:

>
Those POP EAX are junk and there you need to place stolen bytes. Then dump file with LordPE.
When you try to dump with LordPE, it will tell you that it can't grab process memory. Right
click in LordPE on our process, select "active dump engine", than "intelliDump" and "select".
Now dump it. You will get message that not all bytes could be dumped and that hey will be
substituted with zeros. Ok, save dump and open ImpREC. Reall OEP is 004013FB so write 13FB and
fix dump. And that's all!

4. Final words

It was not hard to unpack this version. I'm planing to write tutorial about MSLRH v0.32a which is
harder, but all in time. In the archive you will find script for de-junking and one for unpacking
this protector. Also you will find protector itself, packed target and unpacked target, and this
tutorial too.

Sorry for grammar mistakes and other errors.

Big greets to all folks on BIW and we gona see you in the next tutorial. Bye!