Overview:
The Bat! uses a key/code registration procedure, which is NOT the target
of this crack. Instead, we are going to bypass the time-limitation by patching
the program. NOTE: this patch does not make the program think it's registered,
but since there's no difference between registered/not registered version (apart
from the time limit) we don't need to do it. Killing the nag and timelimit is
all we need to do.
This objective is not as easy as it looks like. First - The Bat! crashes w32dasm
so checking the dead-listing doesn't work here. Also, The Bat! is packed with a
compressor called UPX, which makes it unable to be patched directly. Imagine
that a small routine of UPX is in front of the actual application. Everytime
The Bat! is being loaded, this small routine unpacks the real program and
runs it after decompression. Normally, the unpacker is very fast, so you
won't notice anything at all.
This means, we need to patch The Bat! AFTER decompression, but BEFORE
actual execution. In other words: we need to find the jump that starts the
real program, redirect it to a small patch-routine and start the real
program after patching.
But first, let's find the nag-screen-call:
Start softice, run the symbol loader, load thebat.exe and wait until the
nag-screen is displayed. Don't close the nag-window. Switch to softice and
do a breakpoint on the closing of the window:
BPX destroywindow
Let softice run and press either the OK or Exit button of our nag-screen.
Softice will pop-up, disable the breakpoint (type BC *) and start a search
for the text that is displayed through the nag-window:
s 0 l 90000000 'This program is'
Softice will find a few locations somewhere in memory, but the one we need
is located in the TheBat!UPX0-part. Softice should find the text at the
address 6936C9. Now, set a memory access breakpoint at this address:
BPMB 6936C9
Let softice go, exit The Bat! and restart it right away (use the symbol
loader menu Module/Load). Softice will now stop at the first memory access
at our address. Ignore the first one - it's done by the UPX-unpacker, which
is decompressing our program. Press F5 to ignore this stop. Softice will
break once more at this position:
xxx:004016A3 F3A5 REPZ MOVSD
From now on, press F12 until the nag-screen appears (takes 19 keypresses).
Again, click OK or Exit and softice will break one last time at this position:
001B:0054803B 84C0 TEST AL,AL
which is part of this routine:
1 001B:00548029 8BD8 MOV EBX,EAX
2 001B:0054802B 803D0C275F0000 CMP BYTE PTR [005F270C],00
3 001B:00548032 751E JNZ 00548052 (NO JUMP)
4 001B:00548034 8BC3 MOV EAX,EBX
5 001B:00548036 E87575F9FF CALL 004DF5B0
6 001B:0054803B 84C0 TEST AL,AL
7 001B:0054803D 7413 JZ 00548052 (JUMP)
The CALL in line 5 is the window-popup. The TEST AL,AL in line 6 determines
whether we've presses OK or Exit. It will take the jump in line 7 if we've
pressed the OK-button. See line 3 ?
This one also jumps to the place where we would go when pressing OK. But in our
case the jump of line 3 did not seem to work. Let's display the byte at the position
accessed by line 2 (005F270C) - it contains a 0. If it would have been a 1, the jump
in line 3 would have worked, jumping over the nag-popup-call.
Disable all breakpoints (BC *) and set a breakpoint on memory access at address
005F270c and let softice run, exit The Bat (ignore all breaks by softice) and start
The Bat! once more. Softice will break 3 times because of the decompressor, ignore
them (F5) and the fourth stop will be at a line similiar to our line 2 from above:
1 001B:005433A0 803D0C275F0000 CMP BYTE PTR [005F270C],00
2 001B:005433A7 741D JZ 005433C6 (JUMP)
This is the first time The Bat! checks this byte and the 0 isn't what we like to see
there - so let's change line 1 using the "a" command of softice to:
MOV BYTE PTR [005F270C],01
Now the byte is a 1 and every other check coming later will find this 1 and work
like if this has ever been so. If you execute the line and disable all breakpoints
The Bat! will never show any nag-screen anymore. Cool eh? :)
Where does the real program start?
As I said above, we need to find the place where the decompression routine calls
the real program, to patch our program. We know that the whole program is decompressed
in memory and we even had some breakpoints breaking at memory access of the
decompressor. This means, the code of our line 1 from above is being written
into memory - so we try a breakpoint on memory access at this address:
BPMB 005433A0
Be sure you have only this breakpoint active, exit The Bat! and re-run it. Softice
will break at this line:
001B:006AD10B 83C704 ADD EDI,04
Notice that we are in a completely different part of the code, at address 6AD10B,
remember also that our program above was running at address 5xxxxx. If you press F10
now for a while and have your display set to the address 5433A0, you can watch
the decompressor generating the real program... instead, scroll the code-window
down looking for an address in the 5xxxxx-range. You will find these two lines:
001B:006AD1C6 61 POPAD
001B:006AD1C7 E93867F3FF JMP 005E3904
Yes! This is the jump to the real program, after the decompressor has done its
job. All we have to do now is: find a free part in thebat.exe, write the code
that patches our program into that part, let the jump at line 6AD1C7 jump to
this part and run the real program.
Patching The Bat!...
How do we find a free part in thebat.exe, which is part of the decompression
routine and NOT part of the (compressed) data?
Open thebat.exe in your favourite hex-editor and search for the code of the
jump from above (E93867F3FF) - you'll find it at position 24007 (decimal).
Hmm... doesn't look like there's free space, does it? Scroll to the beginning
of the file... hmmm... some strange ascii-art, right? Hmmm.... jump to the
beginning of thebat.exe - there it is:
UPX 0.60 Copyright (C) 1996-1999 Laszlo Molnar & Markus Oberhumer
Why not use the copyright of UPX as space for our patch-routine? Okay, let's
do it. All we need now is the position of this copyright-text in memory. I'll
use the 'L' of 'Laszlo' as my first byte of the patch-routine. Use softice to
locate this copyright-text in memory and write down the address (which is
00400296 in the case of the 'L').
We need 2 lines of code to patch the code at address 005433A0 which looks
like this:
1 001B:005433A0 803D0C275F0000 CMP BYTE PTR [005F270C],00
2 001B:005433A7 741D JZ 005433C6
but should look like this:
1 001B:005433A0 C6050C275F0001 MOV BYTE PTR [005F270C],01
2 001B:005433A7 741D JZ 005433C6
The 2 lines that do the patch plus the jump to the real program are these:
1 00400296 C705A0335400C6050C27 MOV DWORD PTR [005433A0],270C05C6
2 004002A0 C705A43354005F000174 MOV DWORD PTR [005433A4],7401005F
3 004002AA E955361E00 JMP 005E3904
Are we done? Not yet! We've got to redirect the jump from the decompressor
so it runs through our 3 new lines. Simply change the jump at 006AD1C7 to this one:
006AD1C7 E9CA30D5FF JMP 00400296
Congratulations! You've just patched The Bat! - I hope this little tutorial helps
to understand how to patch compressed programes. Even if they crash w32dasm. :)
Have fun!
varroa, 5/5/99