- The goal of this tutorial is to give you a short introduction
to unpacking using a method that is famous as the "MIZ method" in
+Sandman's forum. MIZ is the guy that presented us this valuable knowledge.
Thanx MIZ. Thanx to alpine, too for writing a tut about this CrackMe
that helped me to overcome the problems I had with unpacking.
-
I. Unpacking the EXE file
To explain MIZ way of unpacking shortly: Start the EXE with SICE
loader and then trace through the code until you come to some "suspicious"
passages, that show the end of the unpacking routine. Then the file
is unpacked in memory. Dump it to disk, rebuild the header and then
you have it.
OK, load the program into SICE loader and execute it. SICE should
break and you should be at the program entry point. The entry point
should be :00419319 (as ProcDump reveals (PE Editor)).
Now the important part: Step through all instructions (F10) until
you reach a POP followed by a jump to a register (eax, ebx...). I
tell you now, that TORN@DO has used several packers, so we have to
do this several times.
Tracing a little through the code, you will see:
XXXX:0041374 popad ;; pop all 32bit
registers
XXXX:0041375 popfd ;; pops all 32bit
flags
XXXX:0041376 mov ebx, [edx+00402709] ;;
ebx=real entry point
XXXX:004137C mov [edx+00402709], ecx ;;
???
XXXX:0041382 jmp ebx ;; jump to real entry
point
What does that mean? That means that the
program is unpacked in memory and you can dump it to disk. Better:
It would be unpacked, if TORN@DO had used only one packer. Then ebx
would contain the entry point (00419000)of the unpacked program. In
this CrackMe ebx contains the entry point of the next unpacking routine.
So don't hesitate and go on :)
(BTW: To know if we already left the unpacking
routine you can dump the proc now. If you can disassemble it with
W32Dasm correctly, we have a fully unpacked file. If we get garbage,
one more unpack is to be done. Dumping after every unpacking routine
gives you several unpack states. To learn how to dump see the end
of this essay.)
The next time you will see a structure
like this:
XXXX:004190BE pop esi ;;
load esi from stack
XXXX:004190BF pop edi ;;
load edi from stack
XXXX:004190C0 pop ebp ;;
load ebp from stack
XXXX:004190C1 jmp eax ;;
jump to next "entry point"
The same procedure as above: The second
unpacking routine is finished and eax contains the entry point of
the next unpacking routine (00418000). Let's go on tracing:
The next important jump will be:
XXXX:004190BE pop esi ;;
load esi from stack
XXXX:004190BF pop edi ;;
load edi from stack
XXXX:004190C0 pop ebp ;;
load ebp from stack
XXXX:004190C1 jmp eax ;;
jump to next "entry point"
-
And once again the same procedure: The third
unpacking routine is finished and eax contains the entry point of the
next unpacking routine (00417000). Let's go on:
-
- If you trace on you will come to completely the same again:
The only difference is, that eax contains 00416000 now. Jump and trace
on: You can do that for several more times: eax will be 00414319,
00414000, 00413000 and then the end is near :)
- The last time you come to this eax is when eax contain 004011CB.
Trace until you reach this code:
-
XXXX:004130BE pop esi ;;
load esi from stack
XXXX:004130BF pop edi ;;
load edi from stack
XXXX:004130C0 pop ebp ;;
load ebp from stack
XXXX:004130C1 jmp eax ;;
jump to next "entry point"
-
- Eax contains 004011CB. This is - finally - the real entry point.
(To know that dump the program after every finished unpacking routine.)
So what's dumping. Dumping is just saving contents of the memory to
the harddrive. We use ProcDump for it. First we have the CrackMe to
"freeze". That means it shouldn't go on with executing instructions.
The easiest way to do this is to change the last "jmp eax" instruction
to "jmp eip". (Eip is the register that contains the address of the
next instruction to execute. So a "jmp eip" will create an infinite
loop.) To patch the line in SICE, trace until the last jmp eax is
highlighted and then enter:
-
-
a eip ;; SICE command
to edit current instruction
- jmp eip ;; create endless
loop
-
-
Then leave SICE and start ProcDump. In the listbox that contains
the current tasks idcrkme60.exe should appear. If not something went
wrong and you have to start again :( Rightclick on the CrackMe task
and select "Dump (full)". Enter a name and the unpacked program will
be saved. Now run it. A wondeful error message appears. Guess why:
We changed the entry point of the program by unpacking, but the EXE
header still contains the entry point of the packed EXE file (00419319).
We can change this in ProcDump, too. Choose "PE Editor" and then change
the entry point to 000011CB (that is the last value of eax - 00400000;
that is 004011CB - 00400000).
-
- II. The (easy) crack
As TORN@DO said, the crack will be very easy. Just enable
one button, click it and a window will appear saying you cracked it.
The function that enables windows (and buttons which are only "special"
windows) is EnableWindow. So breakpoint on EnableWindow (bpx enablewindow).
Now something for you alpine: I learned so much from you, today. Now
I give you something back :) You wrote that now you have to hit F11
until you come to the instruction that calls the EnableWindow. It
can be done easier. Just hit F12 one time :) Then you should be here:
:004012E9 837DFC00 cmp dword ptr [ebp-04], 00000000
;; compare something
:004012ED 7515 jne 00401304 ;;
if not the same jump
:004012EF 682E040000 push 0000042E ;; else set
a flag
:004012F4 FF7508 push [ebp+08]
:004012F7 E8EC050000 call 004018E8
:004012FC 6A00 push 00000000
:004012FE 50 push
eax
:004012FF E8C0050000 call 004018C4 ;; and
disable
the button
...