D4CrackMe.exe, how not to crack it...

Tutorial by : R!SC -- risc@notme.com
Date : 18th june 1999


finding the serial check routine was simple enough.. but god damn, is it hard to understand..

:00401228 6A09                    push 00000009 <-- maximum length of serial(-1) 
:0040122A 6814554000              push 00405514 <-- buffer to place entered code

* Possible Reference to Dialog: DialogID_0065, CONTROL_ID:03E8, ""
                                  |
:0040122F 68E8030000              push 000003E8 <-- identifier of control (window with the serial in)
:00401234 56                      push esi      <-- handle of the dialog box..

* Reference To: USER32.GetDlgItemTextA, Ord:0104h
                                  |
:00401235 FF15A0404000            Call dword ptr [004040A0] <-- getdlgitemtexta
:0040123B E894FEFFFF              call 004010D4 <-- real dodgy serial verification routine
:00401240 85C0                    test eax, eax <-- eax==1 if the correct serial
:00401242 7418                    je 0040125C   <-- jump to bad boy


is that what (Level:9) means?? is this the difficulty rating?? heh, who gives a f**k.. i doubt
it is reversable, but i had a naughty idea (well, two naughty ideas..)

rip the code at 4010D4, and use it in a brute forcer, passing every possible combination of
serials to it and seeing what it throws back, But, hmm, the code is a bit complicated.. and
from this idea, sprung another one.. just write the bruteforce code inside of the crackme,
inside of its own code, and call the serial verification routine.. heehee.. i am real naughty..
this is not a cracking, this is just a simple waiting game..

bpx getdlgitemtexta, F5, enter a number, click on try, F11 to reach the line after the
api call, then search memory for a nice place to code a simple brute forcer...

Break due to BPX USER32!GetDlgItemTextA  (ET=2.21 seconds)
Break due to G (ET=346.92 microseconds)
:bd*
:d 405514       <-- reveals the 8 digit code :)

hmm, after scrolling through the data window, i found a lot of space at address 405B00
si i decided to code a brute force algo here..


:a 405b00
015F:00405B00 call 4010d4                   <-- call the serial verification routine
015F:00405B05 test eax,eax
015F:00405B07 jne 405d00                    <-- if eax is not-equal, we have the right number
015F:00405B0D inc byte ptr [405514]
015F:00405B13 cmp byte ptr [405514], 3a     <-- compare current value, after the inc, with 3a 
015F:00405B1A jl 405b00                       - 39h=9 ascii, 3ah=too far
015F:00405B1C mov byte ptr [405514],30        - so reset it to 0 ascii
015F:00405B23 inc byte ptr [405515]           - and increase the next digit
015F:00405B29 cmp byte ptr [405515],3a      <-- if this one has gone past ascii 9
015F:00405B30 jl 405b00
015F:00405B32 mov byte ptr [405515],30        - do the bloody same..
015F:00405B39 inc byte ptr [405516]
015F:00405B3F cmp byte ptr [405516],3a
015F:00405B46 jl 405b00
015F:00405B48 mov byte ptr [405516],30
015F:00405B4F inc byte ptr [405517]
015F:00405B55 cmp byte ptr [405517],3a
015F:00405B5C jl 405b00
015F:00405B5E mov byte ptr [405517],30
015F:00405B65 inc byte ptr [405518]
015F:00405B6B cmp byte ptr [405518],3a
015F:00405B72 jl 405b00
015F:00405B74 mov byte ptr [405518],30
015F:00405B7B inc byte ptr [405519]
015F:00405B81 cmp byte ptr [405519],3a
015F:00405B88 jl 405b00
015F:00405B8E mov byte ptr [405519],30
015F:00405B95 inc byte ptr [40551a]
015F:00405B9B cmp byte ptr [40551a],3a
015F:00405BA2 jl 405b00
015F:00405BA8 mov byte ptr [40551a],30
015F:00405BAF inc byte ptr [40551b]
015F:00405BB5 cmp byte ptr [40551b],3a
015F:00405BBC jl 405b00
015F:00405BC2 int 03                    <-- friendly int 03, if this is reached, all 
015F:00405BC3                             - number combinations have been tried

:a 405d00
015F:00405D00 int 03                    <-- another friendly int 03, this one means we have the
015F:00405D01                             - right number
:d 405514           <-- erm, dump the serial, so i can manually set it to '00000000'


hoe hoe, what fun, theres 10 minutes coding off the top of my head :)

bpint 3 in softice or i3here on...

well, alls left to do now, is point the eip to my code, and wait.. r eip=405b00, F5...
this lame code will cycle through every possible combination of decimal values, thats er, quite
a lot of values, 99,999,999, nearly 100 million, but the code verification routine is very fast,
would be nicer if it was a bit faster, but, anyway, 10 minutes later, and 100 million numbers
crunched, hmm!!! no damn result.. :(

perhaps its a hexadecimal serial, quick hack to change the brute force code to include letters
A..F

:d eip      <-- i just search for the '3A' and change it to '47' :)
:?'F'
00000046  0000000070  "F"
:u eip l 100
015F:00405B00  E8CFB5FFFF          CALL    004010D4
015F:00405B05  85C0                TEST    EAX,EAX
015F:00405B07  0F85F3010000        JNZ     00405D00
015F:00405B0D  FE0514554000        INC     BYTE PTR [00405514]
015F:00405B13  803D1455400047      CMP     BYTE PTR [00405514],47   <-- ascii G, means gone too far
015F:00405B1A  7CE4                JL      00405B00
015F:00405B1C  C6051455400030      MOV     BYTE PTR [00405514],30   <-- reset it to ascii 0
015F:00405B23  FE0515554000        INC     BYTE PTR [00405515]
015F:00405B29  803D1555400047      CMP     BYTE PTR [00405515],47
015F:00405B30  7CCE                JL      00405B00
015F:00405B32  C6051555400030      MOV     BYTE PTR [00405515],30
015F:00405B39  FE0516554000        INC     BYTE PTR [00405516]
015F:00405B3F  803D1655400047      CMP     BYTE PTR [00405516],47
015F:00405B46  7CB8                JL      00405B00
015F:00405B48  C6051655400030      MOV     BYTE PTR [00405516],30
015F:00405B4F  FE0517554000        INC     BYTE PTR [00405517]
015F:00405B55  803D1755400047      CMP     BYTE PTR [00405517],47
015F:00405B5C  7CA2                JL      00405B00
015F:00405B5E  C6051755400030      MOV     BYTE PTR [00405517],30
015F:00405B65  FE0518554000        INC     BYTE PTR [00405518]
015F:00405B6B  803D1855400047      CMP     BYTE PTR [00405518],47
015F:00405B72  7C8C                JL      00405B00
015F:00405B74  C6051855400030      MOV     BYTE PTR [00405518],30
015F:00405B7B  FE0519554000        INC     BYTE PTR [00405519]
015F:00405B81  803D1955400047      CMP     BYTE PTR [00405519],47
015F:00405B88  0F8C72FFFFFF        JL      00405B00
015F:00405B8E  C6051955400030      MOV     BYTE PTR [00405519],30
015F:00405B95  FE051A554000        INC     BYTE PTR [0040551A]
015F:00405B9B  803D1A55400047      CMP     BYTE PTR [0040551A],47
015F:00405BA2  0F8C58FFFFFF        JL      00405B00
015F:00405BA8  C6051A55400030      MOV     BYTE PTR [0040551A],30
015F:00405BAF  FE051B554000        INC     BYTE PTR [0040551B]
015F:00405BB5  803D1B55400047      CMP     BYTE PTR [0040551B],47
015F:00405BBC  0F8C3EFFFFFF        JL      00405B00
015F:00405BC2  CC                  INT     3

:d 405514       <-- reset it to '00000000' again..


well, i go ahead and try this new brute algo, but, not much luck, its not very good code, and
trys the ascii between 3A--40 ':;<=>?@', 7 extra characters, which really slow it down..

hmm, decide to code one in a proper language, and just copy & paste the code into the the exe..
see hmm.asm, i compiled it, then copy&paste the code into D4CrackMe.exe, where i located some
free space..(see new_d4crackme.exe, file offset 3b60)

run the new crackme, with superduper bruteforcer(tm) coded inside of it..

bpx getdlgitemtexta, enter fake code and hit try...

Break due to BPX USER32!GetDlgItemTextA  (ET=1.68 seconds)
Break due to G (ET=180.81 microseconds) <-- here after hitting F11...
:s 0 l ffffffff 'sometext'              <-- search for the new code ('sometext' is at the start of it)
Pattern found at 0030:00403B60 (00403B60)   <-- found it :)
:r eip=403b60                           <-- point the eip to it..
:.                                      <-- '.' updates the code window
:r eip=403b70                           <-- whoops, wrong place, skip past 'sometext',90,90,90,90....
:e 405514 '00000000'                    <-- 'e' = edit memory, address, new contents (change serial to 00000000)
:a 403B7C
015F:00403B7C call 4010d4               <-- where the nop's are, place our call..
015F:00403B81
:bl
00)   BPX USER32!GetDlgItemTextA
01) * BPX USER32!GetWindowTextA
02) * BPX USER32!MessageBoxA
03) * BPX USER32!DialogBoxParamA
04) * BPINT 03
:be 04              <-- enable my bpint 03
:bd 00              <-- disable the bpx getdlgitemtexta
:x


and just wait... almost every time you 'ctrl-d' to enter soft-ice, you should be in d4crackme
code, and you can check memory, d 405514, to see what serial your on...

one problem though, instead of cycling through 100 million numbers
10^8=10*10*10*10*10*10*10*10=100,000,000
it has to do 
16^8=16*16*16*16*16*16*16*16=4,294,967,296 (4.2 billion....)

okay, 4.2 billion / 100 million = 42...42*10(10 minutes per 100 million)=420 minutes
420/60=7.1582788... hours...

heh, and its a total waste of time..either something wrong with my approach, or the serial is
a 8 letter word, instead of a 8 letter number, DnNuke, the crack lies in your hands now, i have
tried, and i have failed..

well, the first tutorial on how not to crack a crackme, hopefully will save anyone trying 
wasting there time :)  but i wanna be shown the light, show me how to reverse the code, tell me
the answer..  and i pray it is not a hexadecimal serial....



R!SC -- risc@notme.com -- http://csir.cjb.net  :~~(

greets to uncrackable crackme coders, especially Duelist & d4eMoN (maybe one day...)
also to : Eternal Bliss, ACiD BuRN, DnNuke, Wizzkid, ChoJin, Magic Mike, Dead-Mike :P

etc...

remember, in the real world, we would be allowed to patch, and if that failed aswell, please
say hello to Mr. Credit Card, who can crack faster & more reliably than anyone..





all my love, R!SC ?
