|
( 'unpacking and patching' ) |
Win Code Reversing |
|
|
|
|
|
|
Program Name: apis32.zip Program Type: API utility Program Location: Here Program Size: 167kb |
||
Tools Used: Softice V3.25 - Win'95 Debugger W32Dasm V8.93 - Win'95 Dissembler ProcDump v1.5 - Unpacker |
||
|
|
|
The author of Apispy v2.4 says :
APIS32 ( API Spy
) - is the best tool to examine Windows API functions used by 32 bit
Windows
applications.
It allows to
examine any known API function`s calls that is resolved during the program
load time
and is given by APIS32. APIS32 will work with Windows95/98/NT and Windows
2000
applications
which will be executed on the any Win32 platforms.
Now APIS32 is
working perfectly under Windows NT5 and Windows 2000 !
|
This program was packed wih Petite
v1.2, so this tutorial will be in 2 parts :
part 1 - how to manually unpack
a program packed with Petite v1.2.
part 2 - how to crack apispy v2.4.
When i followed the code of the
protection routine, i saw how some of the program code changed in front
of my eyes. You will see what i
mean in the second part of this tutorial.
The program save it's registration
information in the registy file, not as string, but as binary value :
HKLM\Software\APIS32\UserKey
HKLM\Software\APIS32\UserName
|
PART ONE - how to manually unpack a program packed with Petite v1.2.
When i start following the program
with softice after i typed in my name and reg code, i found the place i
need
to patch the program in. So, i used
W32dasm to create a dead list, and surprise, i couln't see any "exports"
nor strings in the "string data
references". This makes me think that this program is packed. Now we need
to
know what packer used for it. My
chance was that some time ago i heard that it is "Petite 1.2".
We're going to follow the steps
to unpack it manually, because the option in ProcDump didn't unpacked it...
When we need unpacking, we use "Softice
Symbol loader" for it. So, load Softice symbol loader and in the
menu choose "file/open" and put
apis32.exe in it, now, choose "module/load". If you get a symbol/load
error, click on "yes", and
Softice breaks on this code :
:0041A000 ffff
invalid ; press F10 once and here is the
code :
:0041A002 60
pushad
:0041A003 E8CA000000
call 0041A0D2
; unpacking routine
:0041A008 0300
add eax, dword ptr [eax]
:0041A00A 0400
add al, 00
Keep press F10 until u land on the
call 0041A0D2,
now press F8 to trace into this
call, which is the unpacking
routine.
* Referenced by
a CALL at Address:
|:0041A003
|
:0041A0D2 58
pop eax ;
we land here
:0041A0D3 2C08
sub al, 08
:0041A0D5 50
push eax
:0041A0D6 8BC8
mov ecx, eax
:0041A0D8 8BD0
mov edx, eax
:0041A0DA 81C168D20000
add ecx, 0000D268
:0041A0E0 81C2DC150000
add edx, 000015DC
:0041A0E6 8920
mov dword ptr [eax], esp
:0041A0E8 8BE1
mov esp, ecx
:0041A0EA 50
push eax
:0041A0EB 812C2400A00100
sub dword ptr [esp], 0001A000
:0041A0F2 FF30
push dword ptr [eax]
:0041A0F4 50
push eax
:0041A0F5 80042408
add byte ptr [esp], 08
:0041A0F9 50
push eax
:0041A0FA 80042446
add byte ptr [esp], 46
:0041A0FE 50
push eax
:0041A0FF 80042465
add byte ptr [esp], 65
:0041A103 50
push eax
:0041A104 800424A1
add byte ptr [esp], A1
:0041A108 50
push eax
:0041A109 800424BF
add byte ptr [esp], BF
:0041A10D
833A00
cmp dword ptr [edx], 00000000
:0041A110
0F84A7140000
je 0041B5BD ; from here it's a loop
that executed 3 times
:0041A116
F70200000080
test dword ptr [edx], 80000000
:0041A11C
741B
je 0041A139
:0041A11E
FD
std
:0041A11F
8B0A
mov ecx, dword ptr [edx]
:0041A121
81E1FFFFFF7F
and ecx, 7FFFFFFF
:0041A127
8B742418
mov esi, dword ptr [esp+18]
:0041A12B
8BFE
mov edi, esi
:0041A12D
037204
add esi, dword ptr [edx+04]
:0041A130
037A08
add edi, dword ptr [edx+08]
:0041A133
F3
repz
:0041A134
A5
movsd
:0041A135
83C20C
add edx, 0000000C
:0041A138
FC
cld
:0041A139
52
push edx
:0041A13A
FF32
push dword ptr [edx]
:0041A13C
8B5A08
mov ebx, dword ptr [edx+08]
:0041A13F
035C2420
add ebx, dword ptr [esp+20] ; OEP in ebx
in first loop !!
:0041A143
53
push ebx
:0041A144
8B5A04
mov ebx, dword ptr [edx+04]
:0041A147
035C2424
add ebx, dword ptr [esp+24]
:0041A14B
53
push ebx
:0041A14C
E84A000000
call 0041A19B
:0041A151
85C0
test eax, eax
:0041A153
741F
je 0041A174
:0041A155
8B7C2404
mov edi, dword ptr [esp+04]
:0041A159
83C40C
add esp, 0000000C
:0041A15C
5A
pop edx
:0041A15D
8B4A0C
mov ecx, dword ptr [edx+0C]
:0041A160
C1F902
sar ecx, 02
:0041A163
33C0
xor eax, eax
:0041A165
F3
repz
:0041A166
AB
stosd
:0041A167
8B4A0C
mov ecx, dword ptr [edx+0C]
:0041A16A
83E103
and ecx, 00000003
:0041A16D
F3
repz
:0041A16E
AA
stosb
:0041A16F
83C210
add edx, 00000010
:0041A172
EB99
jmp 0041A10D ; don't keep F10 on third
time !!!!!!
Trace the code with F10, but pay
attention to the add
ebx, dword ptr [esp+20] at location
0041A13F,
when
you pass it the first time, type "d ebx" in SI, the value in EBX is the
Original
Entry
Point,
that we
will need
it later, so, note it done.
What we need
now is that the routine will finidh to unpack the program into the memory,
so keep F10 untill
you will
come to jmp 0041A10D
at location 0041A172
for the third time.
When you
do, we need ro freeze the program in memory, so we can use ProcDump to
dump it and to have
the full
program. This is done doing this steps :
type in Softice
"a eip" and
click "enter".
"jmp eip"
and click "enter"
click enter
The program
is in endless loop now in memory, and we will exit Softice now by typing
"x" and enter.
We are going
to use ProcDump now, you can go read the ProcDump setting page i wrote
here.
Run ProcDump
and look in the upper window for apis32.exe. Right click on it will open
window, choose the
"full dump"
option, and type the name you want to save it with. (i use apis23up.ex
up-unpacked).
look now
at the 2 files, do you see the different sizes ?
Run the unpacked
program... hey, it crashes, why ? the program is using the old Entry Point
of the packed
program.
We need to change that.
Open ProcDump
again, click on the "pe editor" button, and choose the unpacked executable
apis32up.exe.
You're looking
now at the "header infos" window. take the note that you wrote the OEP
and calculate the
entry point
this way : entry point = imagebase - OEP. In my case it was 00400000
- 00401000 = 00001000.
Take the
result of this calculation and write it in the Entry Point window, Push
"ok" and leave ProcDump.
That's it
!! go to w32dasm and create a "dead list", can you see the differences
??
Program unpacked.
PART TWO - how to crack apispy
v2.4.
Type in the registration window
your name and a registration key and click "ok". The error message pops.
Now, when we have a full list of
the prog, go the the "string data references" and look for the error message.
You will see it, and even the "good"
message :
"Thanks for Registering APIS32!"
"The registration information you
" double click on this message will take us to the location in the program
that we get this message :
:00401764
FF15F8024100
Call dword ptr [004102F8]
:0040176A
CC
int 03
; we want to break here !
:0040176B
312F
xor dword ptr [edi], ebp
:0040176D
0000
add byte ptr [eax], al
:0040176F
A374CE4000
mov dword ptr [0040CE74], eax
:00401774
EB01
jmp 00401777
:00401776
B8
BYTE B8
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401774(U)
|
:00401777
0AC0
or al, al
:00401779
7402
je 0040177D
:0040177B
EB2C
jmp 004017A9
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401779(C)
|
*
Possible StringData Ref from Data Obj ->"The registration information you
"
->"provided is incorrect. Please"
|
:0040177D
BFE8904000
mov edi, 004090E8
:00401782
BAE0D14000
mov edx, 0040D1E0
Type in the registration window your name
and a registration key and before click "ok", fire up Si (Ctrl+d)
and type in SI "bpx getdlgitemtexta"
and "x" to leave. Click on the "OK", and softice break. Press F11
once, and we're in apis32 code,
but we want to set a new BP before the message appears, so, type "bd *"
to disable the previous bpx, and
type "u 40176a" (enter) when this location shows at the top of the code
window, type "bpx 40176a" (enter)
and "x" to leave. Now we are here :
:00401764
FF15F8024100
Call dword ptr [004102F8]
:0040176A
E8312F0000
call 004046A0 ;
we break here !
:0040176F
A374CE400
mov [0040CE74],eax
:00401774
EB01
jmp 00401777
:00401776
B80AC07402
mov eax,0274C00A
:0040177B
EB2C
jmp 004017A9
Well.... take a closer look at this
code and at the one from the dead list. can you see the difference ?
But you didn't see nothing yet :) wait
until we start trace it... Here we go.
F10 once and we back from the call at
0040176a. register EAX is highlited and moved to location 40CE74.
BEFORE you F10 on :00401774
jmp 00401777, can you
see this location ?? no, so what will be here is
that the EB01 (jmp
00401777) is jumping over the first pair of bits of the next op code :
B80AC7402 (mov eax,0274C00), to see what's the point, press now F10, here is what we got :
:0040176A
E8312F0000
call 004046A0
:0040176F
A374CE400
mov [0040CE74],eax
:00401774
EB01
jmp 00401777 ;
now press F10 over this line !
:00401776
B80AC07402
mov eax,0274C00A
:00401777
0AC0
or al,al
:00401779
7402
jz 0040177D ;
go to "error message"
:0040177B
EB2C
jmp 004017A9 ;
go to "good message"
This set of 2 new instractions, is
our point of patch to register. As we saw, register EAX = 0 when we are
back from the call, and this value
is moved to location 40CE74, this location holds "0" or "1" to sighn if
the
prog is registered.. can we go
and try to change the code so eax will get the value of "1" ?
Enter your details again, and after
SI breaks, when you over 00401777
or al,al we will change the
content of
eax this way : type "r eax=1" and "x" to leave.
"thanks for
registering" is here, but if we close the program again, it's still unregistered.
There is other check
also. If
we look for the call
004046A0 we can see that it
get called from 4 locations :
*
Referenced by a CALL at Addresses:
|:004015CC
, :00401D1A , :00401F39 , :004025E6
|
:004046A0
51
push ecx
:004046A1
53
push ebx
:004046A2
55
push ebp
:004046A3
56
push esi
:004046A4
57
push edi
:004046A5
6A50
push 00000050
:004046A7
68A0C64000
push 0040C6A0
*
Possible StringData Ref from Data Obj ->"UserKey"
|
:004046AC
6808964000
push 00409608
:004046B1
E81A030000
call 004049D0
:004046B6
83C40C
add esp, 0000000C
:004046B9
83F810
cmp eax, 00000010 ;
UserKey need to be at least 10 hex
:004046BC
7D08
jge 004046C6
; 10h = 16 decimal
:004046BE
33C0
xor eax, eax
----
snip snip ----
:004046C6
6A2F
push 0000002F
:004046C8
6800CF4000
push 0040CF00
*
Possible StringData Ref from Data Obj ->"UserName"
|
:004046CD
68F8954000
push 004095F8
:004046D2
E8F9020000
call 004049D0
:004046D7
83C40C
add esp, 0000000C
:004046DA
83F805
cmp eax, 00000005
UserName need to be at least 5 hex
:004046DD
7D08
jge 004046E7
----
snip snip ----
:0040481D
5F
pop edi
:0040481E
85ED
test ebp, ebp
:00404820
5E
pop esi
:00404821
5D
pop ebp
:00404822
0F94C0
sete al
:00404825
5B
pop ebx
:00404826
59
pop ecx
:00404827
C3
ret
This locations
executed when loading the prog, when click on the "about" button and when
registering.
Looking deeper,
we can see some important notes about our reg info, but what interest us
is location
:00404822
sete al at this point we can
move "1" to eax to make the program think that it's registered.
The way i
decide to do it this time is to use the code "inc eax" because all times
i checked, eax was = 0
at this point.
The new code should look like this :
:00404820
5E
pop esi
:00404821
5D
pop ebp
:00404822
40
inc eax
:00404823
90
nop
:00404824
90
nop
:00404825
5B
pop ebx
:00404826
59
pop ecx
:00404827
C3
ret
From now, evry time the program gets
to this code eax will increase from "0" to "1" and act as registered.
|
Load up Spector.exe into your Hex-Editor ( I use hexWorkshop-32).
SEARCH FOR THE FOLLOWING BYTES
: 5E5D0F94C05B59C3
REPLACE WITH HIGHLIGHTED
BYTES : 5E5D4090905B59C3
REMEMBER, i'm
doing my cracks as a hobby and challenge, so please, if you
like this utility
and want to keep using it, support the author and pay for it.
|
I must admit, that all this unpacking
is very interesting to me, and i feel that there a lot to learn about it.
The way the code inside the program
executed, made all this experience even more interesting.
My thanks and gratitude goes to:-
The Sandman for all what he is doing for us, newbies.
Rhayader for helping me with Reverse Code Engineering and useful tips
Alpine, Lord Soth, Volatility and Torn@do for my basic knowledge in packed programs