Vous êtes sur la page 1sur 10

C reating Load ers & D umpers - C rackers G uide to

Program F low C ontrol


______________________
B y [yAtE s]
June 26, 2004

[h ttp://w w w .yates2k.net] [h ttp://w w w .reteam.org]

If you did not find any files accompanying th is paper you can dow nload th em at:

h ttp://w w w .yates2k.net/lad_files.rar
or h ttp://w w w .w oodmann.net/yates/lad_files.rar

Introd uction

So you w ant to unpack a program, aspack? asprotect? even safedisc? To accomplish such a
task a degree of know ledge is needed in many, many different areas, over th e years I h ave
been w riting small tutorials on th ese areas b efore I ever w rite a compreh ensive tutorial on a
single sub ject.

Ok, so one th ing th at I’ve noticed is th at 'new bies' h ave no sense of h ow th ey're going to
carry out all th e tasks needed to repair a exe, most plan to just d ump an exe image and try
and fix bits as th ey go along, but a much more structured w ay can be taken and th is is to
create a 'dumper' w h ich effectively launch es your target exe and h alts it in certain places so
you can read some memory areas and save data, and eventually end up at OE P w h en you
can dump th e sections to disk and make your necessary ch anges.

Ok th is is common know ledge to 80% of crackers excluding th e ones th at message me ;-) so I


doubt many people w ill be reading th is paper, w ith th at let’s begin one of my rare essays
h eh e.

emon
H ow th e d emo n stration w ill h appen

F or th is example I’m going to take a U PX packed notepad and sh ow you h ow to code a


program to stop it at th e point w h ere th e imports are being resolved, th en I’m going to
output th e data to screen as th ey get resolved just as an example, at th is point really if you
w ere unpacking th e exe you w ould grab th e data and prod uce a fresh import table. After
outputting th e import data I’m going to th en let th e program continue to OE P, h alt it th ere
and sh ow a msgbox.

E xaming th e target

Ok before I explain th e process of controlling th e program flow let’s look at our target and
find w h at w e h ave to do. I've protected my notepad w ith upx and took 5mins to study h ow
it w orks. I'll now briefly explain:
U PX entry point looks like th is,

U PX 1:010 116 51 mov esi, offset dw ord_100D 000


U PX 1:010 116 56 lea edi, [esi-0C 00 0h ]
U PX 1:010 116 5C push edi
U PX 1:010 116 5D or ebp, 0F F F F F F F F h
U PX 1:010 116 60 jmp sh ort loc_101167 2

Now if you scroll d ow n 4 pages in ida you can clearly see th e OE P

U PX 1:010 117 9E loc_1 011 79E : ; C OD E X R E F : start+ 11 0_j


U PX 1:010 117 9E popa ; resore registers
U PX 1:010 117 9F jmp near ptr dw ord_10064 20
U PX 1:010 117 9F start endp

So 0101 179 F is our final destination.

Th e import load er code looks like th is

U PX 1:010 117 5C G E T_D LLNAM E _AND _TH U NK : ; C OD E X R E F : start+ 12E _j


U PX 1:010 117 5C mov eax, [edi] ; NO
U PX 1:010 117 5E or eax, eax
U PX 1:010 117 60 jz sh ort loc_10117 9E
U PX 1:010 117 62 mov ebx, [edi+ 4]
U PX 1:010 117 65 lea eax, [eax+ esi+ 11C F 4h ]
U PX 1:010 117 6C add ebx, esi
U PX 1:010 117 6E push eax ; D LL NAM E
U PX 1:010 117 6F add edi, 8
U PX 1:010 117 72 call dw ord ptr [esi+ 11 D A8h ] ; LOAD LIB R AR Y
U PX 1:010 117 78 xch g eax, ebp
U PX 1:010 117 79
U PX 1:010 117 79 B U ILD _TH U NK : ; C OD E X R E F : start+ 1 46_j
U PX 1:010 117 79 mov al, [edi]
U PX 1:010 117 7B inc edi
U PX 1:010 117 7C or al, al
U PX 1:010 117 7E jz sh ort G E T_D LLNAM E _AND _TH U NK ; NO
U PX 1:010 117 80 mov ecx, edi
U PX 1:010 117 82 push edi ; PTR ASC II NAM E
U PX 1:010 117 83 dec eax
U PX 1:010 117 84 repne scasb
U PX 1:010 117 86 push ebp
U PX 1:010 117 87 call dw ord ptr [esi+ 11 D AC h ] ; G E TPR OC AD D R E SS
U PX 1:010 117 8D or eax, eax ; AD D R E SS
U PX 1:010 117 8F jz sh ort loc_10117 98
U PX 1:010 117 91 mov [ebx], eax ; W R ITE TO TH U NK
U PX 1:010 117 93 add ebx, 4
U PX 1:010 117 96 jmp sh ort B U ILD _TH U NK

It starts off by reading a block of d ata stored in E D I, e.g.

U PX 1:010 100 00 dd 0F C h ; D LL NAM E POINTE R


U PX 1:010 100 04 dd 80h ; TH U NK STAR T
U PX 1:010 100 08 db 1
U PX 1:010 100 09 aLocalunlock db 'LocalU nlock',0
U PX 1:010 100 15 db 1
U PX 1:010 100 16 aG lobalunlock db 'G lobalU nlock',0
U PX 1:010 100 23 db 1
U PX 1:010 100 24 aG loballock db 'G lobalLock',0
U PX 1:010 100 2F db 1
U PX 1:010 100 30 aG etlasterror db 'G etLastE rror',0

As you can see by my comments th e structure is pointer to name, th unk location and th en a
list of functions for th at dll. Th e dll pointer is fixed up and read and U PX loads th e library
h ere,

U PX 1:010 117 6E push eax ; D LL NAM E


U PX 1:010 117 6F add edi, 8
U PX 1:010 117 72 call dw ord ptr [esi+ 11 D A8h ] ; LOAD LIB R AR Y

It th en reads th e 80h and add s th e section base to it and puts it in E B X th is w ill be th e th unk
for th e current dll and w h ere all th e resolved address for th e api list w ill be placed, if you
understand import tables th en you know th is is th e point you sh ould replace th e api address
w ith a pointer to th e name. Anyw ay, so th en furth er dow n it reads th e api name th en
performs getprocad dress

U PX 1:010 117 82 push edi ; PTR ASC II NAM E


U PX 1:010 117 83 dec eax
U PX 1:010 117 84 repne scasb
U PX 1:010 117 86 push ebp ; current dll base
U PX 1:010 117 87 call dw ord ptr [esi+ 11 D AC h ] ; G E TPR OC AD D R E SS
U PX 1:010 117 8D or eax, eax ; AD D R E SS
U PX 1:010 117 8F jz sh ort loc_10117 98
U PX 1:010 117 91 mov [ebx], eax ; W R ITE TO TH U NK

Ok so for fun w e w ill stop th e program at 010 117 82 , output th e current function th en
continue to 01011 78D and output th e api ad dress :-)

Ob jectives

Ok h ere is our mission plan:

* Start E xecutable
* place a stop point at oep - 010117 9E
* stop at 010 117 6C print th e dll name
* stop at 010 117 80 print th e ascii name
* stop at 010 117 96 print th e api address
* loop th ese stop points until w e get to oep

I’m going to be sh ow ing my examples in ASM using th e compiler TASM , I w ill also try and
include C + + source codes in th e final source for you new generation coders ;-)
Th eory

In order to control th e program th e idea is w e start th e application in a suspended mode


th en w e w rite into th e programs memory th e bytes 0E B h 0F E h w h ere w e w ant to stop,
th ese 2 bytes are th e opcodes for JM P -2 and since th e instruction is 2 bytes long th is
causes a constant loop and th e instruction keeps executing it self, so w e insert th ese w h ere
w e w ant to stop th en resume th e program, if w e w ait a few millisecond s th e program w ill
become trapped in th is loop, w e can ch eck w h at ad dress is currently b eing executed using
an API, so once w e detect w e've stopped at our target address w e can th en take action.

Th e APIs you need to know are th e follow ing:

C reateProcess - Load an external executable.


h ttp://msdn.microsoft.com/library/default.asp?url= /library/en-
us/dllproc/base/createprocess.asp

R esumeTh read / Suspend Th read - U sed to stop and start th e process th read in its current
state
h ttp://msdn.microsoft.com/library/default.asp?url= /library/en-
us/dllproc/base/resumeth read.asp
h ttp://msdn.microsoft.com/library/default.asp?url= /library/en-
us/dllproc/base/suspendth read.asp

W riteProcessM emory / R eadProcessM emory - U sed to insert our JM P -2 and read process
memory
h ttp://msdn.microsoft.com/library/default.asp?url= /library/en-
us/d ebug/b ase/w riteprocessmemory.asp
h ttp://msdn.microsoft.com/library/default.asp?url= /library/en-
us/d ebug/b ase/read processmemory.asp

G etTh readC ontext / SetTh read C ontext - U sed to get th e R egister values from th e running
process.
h ttp://msdn.microsoft.com/library/default.asp?url= /library/en-
us/d ebug/b ase/getth readcontext.asp
h ttp://msdn.microsoft.com/library/default.asp?url= /library/en-
us/d ebug/b ase/setth readcontext.asp

Pratice

* place a stop point at oep - 010117 9E


* stop at 010 117 6C print th e dll name
* stop at 010 117 80 print th e ascii name
* stop at 010 117 96 print th e api address

So w e h ave 4 stop points, it important to plan w h en placing th ese, in a proper cracking


process you migh t perh aps inject a dll into th e process (see my h ooking import table tut) and
th en patch in jumps at th e h ook points so th e target jumps into your dll and performs some
operations and jumps back.

In th is case w e are inserting E B F E into th e exe, but w e are inserting th em inside a loop th at
resolves imports. W h en w e place th e E B F E w e are destroying data, so it’s a good idea to
find a suitable place to put th em. F or example, over a 2 byte instruction w e can emulate.
Let’s now look for good places to put our h ooks.
1 . OE P.

It doesnt matter w h ere w e place it since w e are terminating th e program w h en w e reach it


so let’s ch oose: 01 011 79E 61 popa

2 . D LLNAM E

U PX 1:010 117 6C 01 F 3 add ebx, esi


U PX 1:010 117 6E 5 0 push eax ; D LL NAM E

0101 176 C is a good place because w e can read E AX to get th e dll, and also grab ebx, esi
Ad d th em and insert th e result b ack into ebx, ok get th e idea?

3 . ASC II NAM E

U PX 1:010 117 80 89 F 9 mov ecx, edi


U PX 1:010 117 82 57 push edi ; PTR ASC II NAM E

Same again 010 117 80 w ill do, w e can emulate th is mov

4 . API AD D R E SS

U PX 1:010 117 87 F F 96 AC 1D 01+ call dw ord ptr [esi+ 11D AC h ] ;


G E TPR OC AD D R E SS
U PX 1:010 117 8D 09 C 0 or eax, eax ; AD D R E SS
U PX 1:010 117 8F 74 0 7 jz sh ort loc_1011 798
U PX 1:010 117 91 89 0 3 mov [ebx], eax ; W R ITE TO TH U NK
U PX 1:010 117 93 83 C 3 04 add ebx, 4
U PX 1:010 117 96 E B E 1 jmp sh ort B U ILD _TH U NK

Th e address goes into eax after getprocad dress so I’m going to ch oose
0101 179 6 E B E 1 jmp sh ort B U ILD _TH U NK for my h ook and update eip w ith th e
address of B U ILD _TH U NK to simulate th e jump w h en I’m done.

C od ing th e program

Ok I th ink th e important bit is over, now w e need to code th is idea, now I’m no coding
teach er, but perh aps for some of you coding is new , and it’s important to find a language
your going to be h appy learning and using, w h ilst coding th e program you w ould normally
code small sections first and test th em but since its going to be h ard to put th is dow n on
paper, I’m now going to paste my source cod e file in sections and explain it as much as I
can, you may learn to cod e in a similar style to try port th e idea to anoth er language, or
perh aps your an excellent coder anyw ay, b ut I never assume anyth ing :-)

Ok th e source file is upx_d ump.asm you sh ould open th is as I go th rough it, th e first top bit
is just th e defining of some APIS and C onstants, th en th e .data section sets up some
variables w e need, w e w ill see th em in use as w e go along.

Th e first part is th at w e Load th e notepad upx file b ut in suspended mod e, th is means th e


program isn’t running but all of its memory is mapped.
Now w e patch our E B F E into all th e addresses th at w e decided on earlier, take a look at th e
code below , if your new to using th ese apis you sh ould look at th e M SN links I provided
earlier w h ich sh ow w h at all th e parameters are, but it sh ould be fairly straigh t forw ard.

C all C reateProcessA,o progname,0,0,0,0,C R E ATE _SU SPE ND E D ,0,0,o tStartupInfo,o


tProcessInfo

mov eax, 01 011 79E h ; OE P


call W riteProcessM emory,[tProcessInfo],eax,o H ALT_C OD E ,H ALT_SIZ E ,0

mov eax, 01 011 76C h ; D LL NAM E H OOK


call W riteProcessM emory,[tProcessInfo],eax,o H ALT_C OD E ,H ALT_SIZ E ,0

mov eax, 01 011 780h ; ASC II NAM E H OOK


call W riteProcessM emory,[tProcessInfo],eax,o H ALT_C OD E ,H ALT_SIZ E ,0

mov eax, 01 011 796h ; API AD D R E SS H OOK


call W riteProcessM emory,[tProcessInfo],eax,o H ALT_C OD E ,H ALT_SIZ E ,0

Ok so now our process is loaded and w e our h ooks patch ed in. Th e next stage is let th e
process run, th en code a M AIN B OD Y w h ich w ill be a loop w h ere G etTh read C ontext is
constantly called, G etTh readC ontext w ill retrieve all th e running processes registers, so if w e
are calling th is in a loop w e can monitor w h en E IP h its one of our h ooks th en take action,
easy eh ? Ok h ere it is:

call R esumeTh read, [tProcessInfo+ 4]

C all Sleep, 100h


mov [my_context], 000 1000 0h + 1+ 2+ 4+ 8+ 1 0h ; SE T U P PE R M ISSIONS
C ontextLoop:
call G etTh readC ontext, [tProcessInfo+ 4], o my_context
test eax, eax
jz CERR
mov eax, [my_context+ R E G _E IP]

cmp eax, 01011 79 E h ; C H E C K ING E IP


jz OE P_R E AC H E D

cmp eax, 01011 76 C h


jz D LLNAM E _H OOK E D

cmp eax, 0101178 0h


jz ASC IINAM E _H OOK E D

cmp eax, 0101179 6h


jz APIAD D R _H OOK
jmp C ontextLoop
Pretty straigh t forw ard I th ink th at is, now someth ing to note is th at I’ve h ardcod ed th e
addresses, perh aps sometimes it is best to subtract th e imagebase th en get th e imagebase of
th e running program and add th em to our values just in case of relocation, th is w ould be
essential for example if w e h ad h ooked after some loadlibrary and got th e base address and
w ere planning to place more h ooks in th is dll, but anyw ay I kept it simple.

Now w e h ave a main bod y, now run th rough th e process in your h ead, th e first th ing th at
w ill h appen is w e w ill get a h ooked detected at th e D LLNAM E , since if you ch ecked th e upx
code snipped at th e start th e first th ing upx does is load a dll, so let’s cod e th e
D LLNAM E _H OOK E D procedure.

D LLNAM E _H OOK E D :

call SuspendTh read, [tProcessInfo+ 4 ]


call G etTh readC ontext, [tProcessInfo+ 4], o my_context

mov eax, [my_context+ R E G _E AX ] ; G E T TH E C ONTE NTS


OF E AX (PTR TO ASC II D LL)
call R eadProcessM emory,[tProcessInfo],eax,o myB uffer,30,0 ; R E AD D LL NAM E F R OM PTR

; emulate U PX 1:0 101 176 C add ebx, esi

mov ebx, [my_context+ R E G _E B X ]


mov esi, [my_context+ R E G _E SI]
add ebx, esi
mov [my_context+ R E G _E B X ], ebx

; skip instruction
mov eax, [my_context+ R E G _E IP]
add eax, 2
mov [my_context+ R E G _E IP], eax

; set context
call SetTh readC ontext, [tProcessInfo+ 4], o my_context

call R esumeTh read, [tProcessInfo+ 4]

call dll1
db 13,1 0,13,10,'-> Loading D LL ',0
dll1:
call dbg_string
call dbg_string, o myB uffer
call dbg_string, o new line
jmp C ontextLoop

U PX 1:010 117 6C 01 F 3 add ebx, esi


U PX 1:010 117 6E 5 0 push eax ; D LL NAM E

Ok h ere w e stop th e process w ith suspendth read so w e stop th e cpu going crazy, th en w e get
th e context so h ave all th e current registers, now th e dll name is stored in E AX , so w e read
th is value from th e context structure, now w e h ave a pointer to th e dllname in th e oth er
process, so w e read from th is address into a buffer.

Next w e need to fix th e instruction w e destroyed w h ich w as AD D E B X , E SI, now if you never
needed to h ook th is point again you could patch th e instruction back but since w e w ant to
break h ere again w e must emulate it, so I grab ebx and esi from th e context struct add th em
and insert it back into ebx, th en I also get th e eip value and ad d 2, th is is so w e skip th e E B
F E and start at th e PU SH , th en i use SetTh readC ontext to update th e process's memory,
R esumeTh read th en sets it back on its w ay, i've th en used my ow n internal functions dbg_xx
to w rite out text and th e contents of th e buffer into a file called deb ug.txt. Now w e jump back
to our main context ch ecking loop.

Th e next th ing th at w ill h appen is w e'll break on th e ASC IINAM E _H OOK E D , so let’s code
th at, you can almost copy paste th e ab ove function and make minor tw eaks.

ASC IINAM E _H OOK E D :


call SuspendTh read, [tProcessInfo+ 4 ]
call G etTh readC ontext, [tProcessInfo+ 4], o my_context

mov eax, [my_context+ R E G _E D I] ; G E T TH E C ONTE NTS


OF E D I(PTR TO ASC II API)
call R eadProcessM emory,[tProcessInfo],eax,o myB uffer,200,0 ; R E AD D LL NAM E
F R OM PTR

; emulate U U PX 1:010 117 80 89 F 9 mov ecx, edi

mov edi, [my_context+ R E G _E D I]


mov [my_context+ R E G _E C X ], edi

; skip instruction
mov eax, [my_context+ R E G _E IP]
add eax, 2
mov [my_context+ R E G _E IP], eax

; set context
call SetTh readC ontext, [tProcessInfo+ 4], o my_context

call R esumeTh read, [tProcessInfo+ 4]

call dll2
db ' F U NC : ',0
dll2:
call dbg_string
call dbg_string, o myB uffer
jmp C ontextLoop

U PX 1:010 117 80 89 F 9 mov ecx, edi


U PX 1:010 117 82 57 push edi ; PTR ASC II NAM E
Ok so th e same as before, stop th e process and th en get th e pointer to th e ascii name from
edi and read it into our buffer, now I emulate th e M OV E C X , E D I and update E IP

Next is th e API function address h ook APIAD D R _H OOK

APIAD D R _H OOK :
call SuspendTh read, [tProcessInfo+ 4 ]
call G etTh readC ontext, [tProcessInfo+ 4], o my_context

mov eax, [my_context+ R E G _E AX ] ; G E T TH E C ONTE NTS


OF E D I(PTR TO ASC II API)

call dll3
db 9,9,9,'AD D R : ',0
dll3:
call dbg_string
call dbg_dw ord,eax,0
call dbg_string, o new line

; emulate 01 011 796 E B E 1 jmp sh ort B U ILD _TH U NK

mov eax, 01 011 779h


mov [my_context+ R E G _E IP], eax

; set context
call SetTh readC ontext, [tProcessInfo+ 4], o my_context

call R esumeTh read, [tProcessInfo+ 4]


jmp C ontextLoop

U PX 1:010 117 87 F F 96 AC 1D 01+ call dw ord ptr [esi+ 11D AC h ] ;


G E TPR OC AD D R E SS
U PX 1:010 117 8D 09 C 0 or eax, eax ; AD D R E SS
U PX 1:010 117 8F 74 0 7 jz sh ort loc_1011 798
U PX 1:010 117 91 89 0 3 mov [ebx], eax ; W R ITE TO TH U NK
U PX 1:010 117 93 83 C 3 04 add ebx, 4
U PX 1:010 117 96 E B E 1 jmp sh ort B U ILD _TH U NK

Since th e api address is E AX all I need do is get th e value from th e context structure, th en
w e h ad our h ook at 0101 1796, so I emulate th e 'jmp sh ort B U ILD _TH U NK ' by placing th e
address of B U ILD _TH U NK into E IP and continue.

Last of all w e need some code for OE P_R E AC H E D

OE P_R E AC H E D :

call M essageB oxA,0,o msgOE P,o msgok, 0

call TerminateProcess, [tProcessInfo]


jmp E nd_Process

Just a simple messagebox to say h ello :) and th e end of th e code looks like,

CE RR:
call M essageB oxA,0,o msgcontext,o msgerr, 0

E nd_Process:
call exitprocess, 0

end main

Ta da! Th at’s it, now since w e are messing around w ith a program during a small loop th at
resolves th e imports it considerably slow s th e app d ow n, if you test th e example it w ill take
about 1 minute until th e message b ox appears, click ok th en view debug.txt

I've provided ASM and C PP code, and b oth compiled exes for you to test, th e C PP one seems
to run much faster, it also screen output, reading th e C PP code is probably easier to
understand th an th e ASM as you can see th e program structure much b etter.

Now don’t take th is tutorial as a literal w ay of cracking someth ing, it merely d escribes a
common tech nique used my dumpers, you sh ould reverse your target application and find
good h ook points, like after some decryption, th en make use of your d umper to run th rough
th e target collecting information needed for a final unpacked target, so h ave fun and w atch
out for C R C s ;-)

regards,

yates.

yates@ reverse-engineering.info

Vous aimerez peut-être aussi