ScareByte's CrackMe #7
Delphi Cracking
Written by Sphinx
Introduction |
Tools required |
Target's URL |
http://crackmes.cjb.net
Essay |
Ok. As usual, let's snoop! And from the looks of things this app is packed.
And I could tell from experience that it's Aspacked by an older version
coz it doesn't have it's own ".aspack" section like the newer ones.
Ok, since it's packed
and there are alot of nifty unpackers available, I
used UnAspack (subtle isn't it?). After that, we continue to snoop. And
we notice it's coded in Delphi (again, from experience :) So we might as
well use DeDe to decompile it for a "better" view. Ok, after
processing it with DeDe, we goto the "DCU" tab coz there's where
the most useful infos are located. And from
my view, I could see
the "crack" unit name. So click it and lo! We can see the events
used! There'll be some other events,
but the most important ones are
those with SpeedButton?Click (where ? is a # from 1 to 4).
And getting add-on infos,
you'll know that they're the "Check"
buttons. Anywho, let's go on with our first task.
Task 1: Nag
Ok. We're not yet interested with the above infos (yet), coz the nag ain't
got one. So we'll try this instead:
- In SoftICE, type: bpx MessageBoxA [enter]
- Run it then break! We should press F12 to let the nag to be
completely drawn (sux!). Then click "Ok" and break!
You see: (as exported from SoftICE with "CODE OFF")
...(some crap)....
0137:00441CCB CALL 00440D3C
0137:00441CD0 TEST AL,AL
0137:00441CD2 JZ 00441CDA ; we'll patch this...
0137:00441CD4 OR EBX,00100000
0137:00441CDA XOR ECX,ECX
0137:00441CDC PUSH EBP
0137:00441CDD PUSH 00441D59
0137:00441CE2 PUSH DWORD PTR FS:[ECX]
0137:00441CE5 MOV FS:[ECX],ESP
0137:00441CE8 PUSH EBX
0137:00441CE9 PUSH EDI
0137:00441CEA PUSH ESI
0137:00441CEB MOV EAX,[EBP-04]
0137:00441CEE MOV EAX,[EAX+24]
0137:00441CF1 PUSH EAX
0137:00441CF2 CALL USER32!MessageBoxA ; Yep!
0137:00441CF7 MOV [EBP-08],EAX
0137:00441CFA XOR EAX,EAX ; ...to let it jump here!
So what I did was I changed that conditional jump at :00441CD2 from a
jz 00441CDA to a jmp 00441CFA and voila!
The
nag's gone! hehe.. So to make it permanent, we'll patch it in Hiew. Anyway,
here's it:
Comparing files CRACKME.BAK and CRACKME.EXE
000410D2: 74 EB
000410D3: 06 26
Task 2: Password
Ok. We'll go back to the SpeedButtons we saw earlier in DeDe. So we should
pick one then. But (most) probably,
it's the first one we're after.
So we disassemble it. And as I was looking at the snippet, it reminded me of
HellForge's W32Dasm CrackMe. Anywho, it just compares the chars of our input
to some constants. And I won't include the entire snippet here, coz it's
too long. So I'll just present here the ones we're after (and note
that the hexcodes were all ripped!)
* Possible Reference to Control 'Edit1:TEdit' ; yep, the password edit field
|
0044C3C7 mov eax, [ebx+$02E8]
0044C3CD call 00425824
0044C3D2 mov eax, [ebp-$04]
0044C3D5 call 00403A74
0044C3DA cmp eax, +$0C
These (probably) just checks the length. If it is, the password then
must be 12 chars long...
Continuing, we then notice that the next ones are the real compares!
Why so? coz by merely looking at the entire
deadlisting (not shown). All
of what we're after, have a check before a conditional jump. And here's
the summary:
0044C3F4 cmp byte ptr [eax], $43 ; ("C")
0044C40E cmp byte ptr [eax+$03], $6F ; ("o")
0044C429 cmp byte ptr [eax+$08], $6F ; ("o")
0044C444 cmp byte ptr [eax+$01], $6C ; ("l")
0044C45F cmp byte ptr [eax+$04], $20 ; (" ")
0044C47A cmp byte ptr [eax+$0A], $52 ; ("R")
0044C495 cmp byte ptr [eax+$07], $75 ; ("u")
0044C4B0 cmp byte ptr [eax+$09], $6E ; ("n")
0044C4C7 cmp byte ptr [eax+$02], $6E ; ("n")
0044C4DE cmp byte ptr [eax+$05], $69 ; ("i")
0044C4F5 cmp byte ptr [eax+$0B], $6E ; ("n")
0044C50C cmp byte ptr [eax+$06], $67 ; ("g")
Ok. Reading this way spelled Cool Running. But it's not the final code
yet. Why? coz it checks for these characters at different locations. But at
first, I assumed that [eax] points to the first char, the
[eax+$03] to the 4th char and so on. And doing that, we then come up
with the (presumably) real password which reads Clno_iguonRn (note
that the "_" is really
a space, just to
avoid confusion). And now enter that and it'll work! Now onto task 3.
Task 3: Serial
Ok. Let's first see that. Hey! It has an anti-SoftICE trick (coz it says so ;)
and notice that the "Check" button has also been
disabled! So we have to "fix" this one first. How? Hmmm.. I've a
hunch that it's just like MeltICE only. So first, switch to
any tab
other than this.
- In SoftICE, type: bpx CreateFileA [enter]
- Goto the Serial tab then break! Mash F12 first so
we'll return to the program's code.
You see:
...(some crap)....
0137:0044BFB0 PUSH EAX ; before, eax points to "\\.\SICE"
0137:0044BFB1 CALL KERNEL32!CreateFileA ; check if the VxD is loaded
0137:0044BFB6 CMP EAX,-01 ; found? (eax is -01 if not, else eax = handle)
0137:0044BFB9 JNZ 0044BFBF ; yes? jump, else..
0137:0044BFBB XOR EBX,EBX ; ebx=0 (goodflag)
0137:0044BFBD JMP 0044BFC1 ; jump to close (why?)
0137:0044BFBF MOV BL,01 ; ebx=1 (badflag)
0137:0044BFC1 PUSH EAX ; save handle then..
0137:0044BFC2 CALL KERNEL32!CloseHandle ; close it
0137:0044BFC7 XOR EAX,EAX ; clean-up
So what should we do? We could make that only conditional jump to
an unconditional jump. But hey! There's one more better thing.
Since it opened it, I want it to close it but I also want it to eat a
goodflag. But how? We could patch that
mov bl, 1 at :0044BFBF
to xor ebx, ebx (goodflag) then close the file afterwards. More elegant?
Maybe? Maybe not :)
But since the code is like messed up, so... anyway,
here's it:
Comparing files CRACKME.BAK and CRACKME.EXE
0004B3BF: B3 33
0004B3C0: 01 DB
Ok. Back in DeDe and diassemble that SpeedButton2Click. And again,
no full snippet here. Now we need to break at
those relevant memory
locations. We could use the int3 move or for an easier way,
we could use Symbol Loader (yep!).
Ok. On the first break, press
F10 just to be sure ;-) Then...
- In SoftICE, type: bpx cs:44C66A [enter]
- Goto the Serial Tab. I registered with Sphinx as name,
TRES2000 as the company and 12345 as the serial and hit
"Check" then break!. And yeah, no
need for F12 :-)
0044C66A mov eax, dword ptr [$44F880] ; after, eax = name offset
0044C66F call 00403A74 ; strlen(name)
0044C674 cmp eax, +$06 ; is it <= 6?
0044C677 jle 0044C76D ; yes? jump badboy, else...
Hey! I'm a badboy coz mine's only six (sux!). So I changed it to
Sphinxter (heh!) then...
0044C67D mov eax, dword ptr [$44F880] ; name again
0044C682 call 00403A74 ; strlen again
0044C687 cmp eax, +$14 ; is it >= 14 (20)?
0044C68A jnl 0044C76D ; yes? jump, else...
So we now know that name should be > 6 and < 20 chars...
0044C690 mov eax, dword ptr [$44F880] ; Deja Vu ;)
0044C695 call 00403A74 ; mine's eax = 9
0044C69A test eax, eax ; 0 bah? (what for?)
0044C69C jle 0044C6B5 ; yes? jump, else...
0044C69E mov edx, $00000001 ; edx = 1 (initial)
0044C6A3 mov ecx, [$44F880] ; ecx = name
0044C6A9 movzx ecx, byte ptr [ecx+edx-$01] ; ecx = 53 ("S")
0044C6AE add [ebp-$04], ecx ; 1st, [ebp-04] = 0, so now it's 53 (duh!)
0044C6B1 inc edx ; inc name ptr
0044C6B2 dec eax ; dec namelen
0044C6B3 jnz 0044C6A3 ; while eax != 0 loop
This routine just adds the oridinal values of the name_chars. And
mine's 3C5, so [ebp-04] = 3C5
0044C6B5 mov eax, dword ptr [$44F884] ; after, eax = company
0044C6BA call 00403A74 ; strlen(company)
0044C6BF cmp eax, +$02 ; is it <= 2?
0044C6C2 jle 0044C6DC ; yes? jump, else...
0044C6C4 mov eax, dword ptr [$44F884] ; same
0044C6C9 call 00403A74 ; same
0044C6CE cmp eax, +$08 ; is it >= 8 then?
0044C6D1 jnl 0044C6DC ; yes? jump, else...
So we now know that company should be > 2 and < 8 chars. So I change
mine to TRES2K.
0044C6D3 mov eax, [ebp-$04] ; eax = 3C5 (see :0044C6AE)
0044C6D6 imul eax, eax, $02 ; eax = eax * 2, so eax = 78A (1930 in dec)
0044C6D9 mov [ebp-$04], eax ; [ebp-04]
Ok. Too long to explain further, so I'll stop here. But to give a hint, my
real serial's I Love Cracking and 1930 Girls ;)
D'you dig it?
It generates a number from the name only then inserts it between the
magic words. And it's case senstive
and that ;)
is really included. Yep, task done so onto the next.
Task 4: CheckBoxes
Ok. Back to DeDe. Disassemble the SpeedButton3Click. Btw, this ain't
that difficult at all with DeDe's help. Anyway,
just by merely looking
at the control names, you'll immediately know what should be checked.
And here they are:
* Possible Reference to Control 'cb3:TCheckBox'; #3
* Possible Reference to Control 'cb5:TCheckBox'; #5
* Possible Reference to Control 'cb6:TCheckBox'; #6
* Possible Reference to Control 'cb12:TCheckBox'; #12
* Possible Reference to Control 'cb15:TCheckBox'; #15
* Possible Reference to Control 'cb20:TCheckBox'; #20
* Possible Reference to Control 'cb9:TCheckBox' ; #9
* Possible Reference to Control 'cb11:TCheckBox' ; #11
* Possible Reference to Control 'cb13:TCheckBox' ; #13
* Possible Reference to Control 'cb19:TCheckBox' ; #19
Ok. Now we know what boxes. But to check which one is which, I had to use
SoftICE. So again, break anywhere
near these lines using Symbol Loader.
Anyway, here's my snapshot:
Final Notes |