GenoCide Trial Crackme 2 [Gandalf/Falcon]

by

{Cronos}

Intro

GenoCide seem to like packing their crackmes with UPX it appears, I can't think why personally. Why do they want to hide the code ? So you just unpack it..... Anyway, it's a Delphi program swollen beyond all proportions :) and 90% of the code that is there is ignorable. It is full of bloat for class type initialisation and type and error checking and it's easy to get lost in a debugger tracing through seemingly endless calls to a library stringlength type function. After a while cracking Delphi apps you become familiar and learn to ignore it for the best part. Delphi however does leave some nice remnants in memory which enable you to start cracking Delphi apps faster :).

Target

This crackme consists of two parts. First we have Gandalfs challenge which is a picture and the statement 'click on the certain places in the picture'. The second challenge is Falcons challenge and offers a traditional name and serial to crack.

Analysis

The approach I took, as usual with these crackmes was to disassemble and look back through the program, find some interesting messages and some interesting routines and track back from there, occasionally using Soft-Ice to verify conjectures and check things and to gain a broader understanding of subroutines. First I will show the attack of Gandalfs challenge which turns out to be relatively straightforward and then Falcons challenge which is longer, but not too difficult for us :)

;*****************************************************************************
; locating this piece of code comes from playing around and
; receiving the start again message after clicking about a bit,
; we soon find that we need to click on the letters of 'genocide crew'
; to get something to happen. After that we can breakpoint in the routine
; below and trace it through, or just analyse the short routine anyway
;*****************************************************************************

;                                                 XREFS First: 1000:0042f2cd Number : 6
1000:0042ef48 55                   push   ebp
1000:0042ef49 8bec                 mov    ebp, esp
1000:0042ef4b 6a00                 push   00h
1000:0042ef4d 53                   push   ebx
1000:0042ef4e bb18174300           mov    ebx, offset 431718h
1000:0042ef53 33c0                 xor    eax, eax
1000:0042ef55 55                   push   ebp
1000:0042ef56 68e0ef4200           push   offset 42efe0h
1000:0042ef5b 64ff30               push   dword ptr fs:[eax]
1000:0042ef5e 648920               mov    fs:[eax], esp
1000:0042ef61 833b0a               cmp    dword ptr [ebx], 0ah
1000:0042ef64 7e0a                 jle    42ef70h
1000:0042ef66 b8f4ef4200           mov    eax, offset s_Start_again_
1000:0042ef6b e80cfaffff           call   42e97ch
;                                                 XREFS First: 1000:0042ef64 Number : 1
1000:0042ef70 8d45fc               lea    eax, [ebp-04h]
1000:0042ef73 8b13                 mov    edx, [ebx]
1000:0042ef75 8a920f174300         mov    dl, [edx+43170fh]
1000:0042ef7b e86847fdff           call   4036e8h
1000:0042ef80 8b55fc               mov    edx, [ebp-04h]
1000:0042ef83 b820174300           mov    eax, offset 431720h
1000:0042ef88 e83b48fdff           call   4037c8h
1000:0042ef8d 8b03                 mov    eax, [ebx]
1000:0042ef8f 85c0                 test   eax, eax
1000:0042ef91 7e18                 jle    42efabh

;*****************************************************************************
; note that 43171ch is reset elsewhere in the program, so that
; in here we accumulate a value, which must get to 2511h
; it consists of sum((string ascii chars * length of string)xor 47)
; so on the first loop (with one char in the string) it is
; (c1 * 1) xor 47
; when there are two chars we add
; (c1 * 2) xor 47 + (c2 * 2) xor 47 to the value we already have
; and so on.............................
;*****************************************************************************

;                                                 XREFS First: 1000:0042efa9 Number : 1
1000:0042ef93 8b13                 mov    edx, [ebx]
1000:0042ef95 0fb6920f174300       movzx  edx, [edx+43170fh]
1000:0042ef9c 0faf13               imul   edx, [ebx]
1000:0042ef9f 83f247               xor    edx, 47h
1000:0042efa2 01151c174300         add    [43171ch], edx
1000:0042efa8 48                   dec    eax
1000:0042efa9 75e8                 jnz    42ef93h
;                                                 XREFS First: 1000:0042ef91 Number : 1
1000:0042efab 813d1c17430011250000 cmp    dword ptr [43171ch], 2511h
1000:0042efb5 7513                 jnz    42efcah

;*****************************************************************************
; the magic value of 2511h actually tells us that the length of the
; string is to be 6, since if it is smaller we cannot get a number
; this large, and if it is larger we easily overshoot this value
; (try a sample string).
;*****************************************************************************

1000:0042efb7 6a00                 push   00h
1000:0042efb9 6804f04200           push   offset s_Congratulations_
1000:0042efbe 6818f04200           push   offset s_Wow__you_did_it__Now_write_a_tut_and
1000:0042efc3 6a00                 push   00h
1000:0042efc5 e84266fdff           call   _MessageBoxA
;                                                 XREFS First: 1000:0042efb5 Number : 1
1000:0042efca 33c0                 xor    eax, eax
1000:0042efcc 5a                   pop    edx
1000:0042efcd 59                   pop    ecx
1000:0042efce 59                   pop    ecx
1000:0042efcf 648910               mov    fs:[eax], edx
1000:0042efd2 68e7ef4200           push   42efe7h
;                                                 XREFS First: 1000:0042efe5 Number : 1
1000:0042efd7 8d45fc               lea    eax, [ebp-04h]
1000:0042efda e86545fdff           call   403544h
1000:0042efdf c3                   ret    
;                                                 XREFS First: 1000:0042ef56 Number : 1
1000:0042efe0 e90340fdff           jmp    402fe8h
1000:0042efe5 ebf0                 jmp    42efd7h
1000:0042efe7 5b                   pop    ebx
1000:0042efe8 59                   pop    ecx
1000:0042efe9 5d                   pop    ebp
1000:0042efea c3                   ret    
1000:0042efeb 00                   db     00
1000:0042efec ff                   db     ff
1000:0042efed ff                   db     ff
1000:0042efee ff                   db     ff
1000:0042efef ff                   db     ff
1000:0042eff0 0c                   db     0c
1000:0042eff1 00                   db     00
1000:0042eff2 00                   db     00
1000:0042eff3 00                   db     00
s_Start_again_:
;                                                 XREFS First: 1000:0042ef66 Number : 1
1000:0042eff4 537461727420616761.. ds     "Start again!"
1000:0042f001 00                   db     00
1000:0042f002 00                   db     00
1000:0042f003 00                   db     00
s_Congratulations_:
;                                                 XREFS First: 1000:0042efb9 Number : 1
1000:0042f004 436f6e67726174756c.. ds     "Congratulations!"
1000:0042f015 00                   db     00
1000:0042f016 00                   db     00
1000:0042f017 00                   db     00
s_Wow__you_did_it__Now_write_a_tut_and:
;                                                 XREFS First: 1000:0042efbe Number : 1
1000:0042f018 576f772c20796f7520.. ds     "Wow, you did it! Now write a tut and
						with explanation on how you've cracked it."

;*****************************************************************************
; a short gap in code until we find.........
;*****************************************************************************


;*****************************************************************************
; here we find some values which can be added, and the routine above
; is called each time. It remains to find a combination which
; gives the magic value. This could be brute forced, but luckily
; these are in reverse order! The answer = "gnwcre". It remains to
; locate these values in the picture, we have the g,n,c and e from
; genocide and the w,r from crew in the picture.
;*****************************************************************************

1000:0042f2c0 ff0518174300         inc    dword ptr [431718h]
1000:0042f2c6 c6051017430065       mov    byte ptr [431710h], "e"
1000:0042f2cd e876fcffff           call   42ef48h
1000:0042f2d2 c3                   ret    
1000:0042f2d3 90                   db     90
1000:0042f2d4 ff0518174300         inc    dword ptr [431718h]
1000:0042f2da c6051117430072       mov    byte ptr [431711h], "r"
1000:0042f2e1 e862fcffff           call   42ef48h
1000:0042f2e6 c3                   ret    
1000:0042f2e7 90                   db     90
1000:0042f2e8 ff0518174300         inc    dword ptr [431718h]
1000:0042f2ee c6051217430063       mov    byte ptr [431712h], "c"
1000:0042f2f5 e84efcffff           call   42ef48h
1000:0042f2fa c3                   ret    
1000:0042f2fb 90                   db     90
1000:0042f2fc ff0518174300         inc    dword ptr [431718h]
1000:0042f302 c6051317430077       mov    byte ptr [431713h], "w"
1000:0042f309 e83afcffff           call   42ef48h
1000:0042f30e c3                   ret    
1000:0042f30f 90                   db     90
1000:0042f310 ff0518174300         inc    dword ptr [431718h]
1000:0042f316 c605141743006e       mov    byte ptr [431714h], "n"
1000:0042f31d e826fcffff           call   42ef48h
1000:0042f322 c3                   ret    
1000:0042f323 90                   db     90
1000:0042f324 ff0518174300         inc    dword ptr [431718h]
1000:0042f32a c6051517430067       mov    byte ptr [431715h], "g"
1000:0042f331 e812fcffff           call   42ef48h
1000:0042f336 c3                   ret    

;*****************************************************************************
; so thats it for Gandalfs challenge..............................
;*****************************************************************************

Now we will move on to Falcons challenge, which turns out to be longer and will take us longer to analyse. This involves the input of a name and serial and we pick it up on the disassembly of the checking routines, which is not too difficult to track down, especially in amongst the Delphi bloat.

;*****************************************************************************
; Falcons challenge is laid out below. It's really no different to locating
; Gandalfs challenge, and so we just get on with the analysis here. Let's
; skip most of the Delphi intro code which you are probably familiar with
; and get into the code of interest to us
;*****************************************************************************

1000:0042f418 55                   push   ebp
1000:0042f419 8bec                 mov    ebp, esp
1000:0042f41b 81c4a0feffff         add    esp, fffffea0h
1000:0042f421 53                   push   ebx
1000:0042f422 56                   push   esi
1000:0042f423 57                   push   edi
1000:0042f424 33c9                 xor    ecx, ecx
1000:0042f426 898da0feffff         mov    [ebp-160h], ecx
1000:0042f42c 894dfc               mov    [ebp-04h], ecx
1000:0042f42f 894df8               mov    [ebp-08h], ecx
1000:0042f432 894df4               mov    [ebp-0ch], ecx
1000:0042f435 894df0               mov    [ebp-10h], ecx
1000:0042f438 894dec               mov    [ebp-14h], ecx
1000:0042f43b 894de8               mov    [ebp-18h], ecx
1000:0042f43e 33c0                 xor    eax, eax
1000:0042f440 55                   push   ebp
1000:0042f441 6805fa4200           push   offset 42fa05h
1000:0042f446 64ff30               push   dword ptr fs:[eax]
1000:0042f449 648920               mov    fs:[eax], esp
1000:0042f44c 8d55fc               lea    edx, [ebp-04h]
1000:0042f44f a10c174300           mov    eax, [43170ch]
1000:0042f454 8b80f4010000         mov    eax, [eax+1f4h]
1000:0042f45a e815abfeff           call   419f74h
1000:0042f45f 8d55f8               lea    edx, [ebp-08h]
1000:0042f462 a10c174300           mov    eax, [43170ch]
1000:0042f467 8b80fc010000         mov    eax, [eax+1fch]
1000:0042f46d e802abfeff           call   419f74h
1000:0042f472 c645d300             mov    byte ptr [ebp-2dh], 00h
1000:0042f476 8d45f4               lea    eax, [ebp-0ch]
1000:0042f479 e8c640fdff           call   403544h
1000:0042f47e 8d45f0               lea    eax, [ebp-10h]
1000:0042f481 e8be40fdff           call   403544h
1000:0042f486 8b45fc               mov    eax, [ebp-04h]
1000:0042f489 e83243fdff           call   4037c0h
1000:0042f48e 83f803               cmp    eax, 03h
1000:0042f491 0f8e48050000         jle    42f9dfh
1000:0042f497 8b45f8               mov    eax, [ebp-08h]
1000:0042f49a e82143fdff           call   4037c0h
1000:0042f49f 84c0                 test   al, al
1000:0042f4a1 7628                 jbe    42f4cbh

;*****************************************************************************
; It often helps to be able to break the code up into small chunks. Take a
; look at the code below. We definitely do not want to end up at the location
; that i called finished_checkfail, which is way down the code and will mean
; a fail at this point in time. Above this we have one loop, from 1 to 
; [ebp-30h], which indexes a string the typical Delphi way by [ecx-01+edx].
; So this is simply looping through the string, in fact our serial we entered.
; A flag is set if we find a '-' in the string, and this must be present for
; us to get past the jump out. So we know the serial must contain at least one
; '-' in it somewhere.
;*****************************************************************************

1000:0042f4a3 8845d0               mov    [ebp-30h], al
1000:0042f4a6 b301                 mov    bl, 01h
1000:0042f4a8 8d4594               lea    eax, [ebp-6ch]
;                                                 XREFS First: 1000:0042f4c9 Number : 1
1000:0042f4ab 33d2                 xor    edx, edx
1000:0042f4ad 8ad3                 mov    dl, bl
1000:0042f4af 8b4df8               mov    ecx, [ebp-08h]
1000:0042f4b2 0fb65411ff           movzx  edx, [ecx-01h+edx]
1000:0042f4b7 8910                 mov    [eax], edx
1000:0042f4b9 83fa2d               cmp    edx, "-"
1000:0042f4bc 7504                 jnz    42f4c2h
1000:0042f4be c645d201             mov    byte ptr [ebp-2eh], 01h
;                                                 XREFS First: 1000:0042f4bc Number : 1
1000:0042f4c2 43                   inc    ebx
1000:0042f4c3 83c004               add    eax, 04h
1000:0042f4c6 fe4dd0               dec    byte ptr [ebp-30h]
1000:0042f4c9 75e0                 jnz    42f4abh
;                                                 XREFS First: 1000:0042f4a1 Number : 1
1000:0042f4cb 807dd201             cmp    byte ptr [ebp-2eh], 01h
1000:0042f4cf 0f85d9040000         jnz    finished_checkfail

;*****************************************************************************
; You can see 4037c0 above the last piece of code, as well as below here. It
; is obviously a stringlength routine......... in fact the code below looks
; very similar
;*****************************************************************************

1000:0042f4d5 c645d101             mov    byte ptr [ebp-2fh], 01h
1000:0042f4d9 8b45f8               mov    eax, [ebp-08h]
1000:0042f4dc e8df42fdff           call   4037c0h
1000:0042f4e1 84c0                 test   al, al
1000:0042f4e3 7622                 jbe    42f507h

;*****************************************************************************
; This time we are simply copying the serial, although we are moving from
; bytes to dwords in doing so. Note that the code does not check the buffer
; and you can enter a long serial with a '-' in it and get the reward of
; an access violation! Hehe, thats how buffer exploits work in hacking...
;*****************************************************************************

1000:0042f4e5 8845d0               mov    [ebp-30h], al
1000:0042f4e8 b301                 mov    bl, 01h
1000:0042f4ea 8db558ffffff         lea    esi, [ebp-a8h]
;                                                 XREFS First: 1000:0042f505 Number : 1
1000:0042f4f0 33c0                 xor    eax, eax
1000:0042f4f2 8ac3                 mov    al, bl
1000:0042f4f4 8b55f8               mov    edx, [ebp-08h]
1000:0042f4f7 0fb64402ff           movzx  eax, [edx-01h+eax]
1000:0042f4fc 8906                 mov    [esi], eax
1000:0042f4fe 43                   inc    ebx
1000:0042f4ff 83c604               add    esi, 04h
1000:0042f502 fe4dd0               dec    byte ptr [ebp-30h]
1000:0042f505 75e9                 jnz    42f4f0h
;                                                 XREFS First: 1000:0042f4e3 Number : 1

;*****************************************************************************
; now take a look at the next little bit of code. Beginning to look familiar
; yet ? yup, stringlength again.........
;*****************************************************************************

1000:0042f507 8b45f8               mov    eax, [ebp-08h]
1000:0042f50a e8b142fdff           call   4037c0h
1000:0042f50f 84c0                 test   al, al
1000:0042f511 7632                 jbe    42f545h

;*****************************************************************************
; this piece of code is the start of a loop. the first thing we do is
; call an inner loop. When we exit the inner loop the inner loop is not 
; called again
;*****************************************************************************

1000:0042f513 8845d0               mov    [ebp-30h], al
1000:0042f516 b301                 mov    bl, 01h
;                                                 XREFS First: 1000:0042f543 Number : 1
1000:0042f518 80fb01               cmp    bl, 01h
1000:0042f51b 7522                 jnz    42f53fh
1000:0042f51d eb11                 jmp    42f530h

;*****************************************************************************
; our inner loop. it counts in three locations the number of characters
; until we find a '-' in the serial we entered
;*****************************************************************************

;                                                 XREFS First: 1000:0042f53d Number : 1
1000:0042f51f fe45d3               inc    byte ptr [ebp-2dh]
1000:0042f522 33c0                 xor    eax, eax
1000:0042f524 8a45d3               mov    al, [ebp-2dh]
1000:0042f527 8985e0feffff         mov    [ebp-120h], eax
1000:0042f52d fe45d1               inc    byte ptr [ebp-2fh]
;                                                 XREFS First: 1000:0042f51d Number : 1
1000:0042f530 33c0                 xor    eax, eax
1000:0042f532 8a45d1               mov    al, [ebp-2fh]
1000:0042f535 83bc8554ffffff2d     cmp    dword ptr [ebp-ach+eax*4], "-"
1000:0042f53d 75e0                 jnz    42f51fh

;*****************************************************************************
; end of loop is below. note this uses a separate counter to the main loop
; at [ebp-2fh]
;*****************************************************************************

;                                                 XREFS First: 1000:0042f51b Number : 1
1000:0042f53f 43                   inc    ebx
1000:0042f540 fe4dd0               dec    byte ptr [ebp-30h]
1000:0042f543 75d3                 jnz    42f518h

;*****************************************************************************
; and the next chunk of code begins with...... guess what, another call
; to the stringlength thing........
;*****************************************************************************

;                                                 XREFS First: 1000:0042f511 Number : 1
1000:0042f545 8b45f8               mov    eax, [ebp-08h]
1000:0042f548 e87342fdff           call   4037c0h
1000:0042f54d 84c0                 test   al, al
1000:0042f54f 767c                 jbe    42f5cdh

;*****************************************************************************
; lets just take a look at the ingredients of the code below.......
; we have a counter [ebp-120h] which contains the number of characters in the
; first part of the serial, which is being used as a branch to split the
; serial in two. if the character is in the first part we do [part1] and if 
; is in the second part we do [part2]
;*****************************************************************************

1000:0042f551 8845d0               mov    [ebp-30h], al
1000:0042f554 b301                 mov    bl, 01h
1000:0042f556 8db51cffffff         lea    esi, [ebp-e4h]
;                                                 XREFS First: 1000:0042f5cb Number : 1
1000:0042f55c 8bfb                 mov    edi, ebx
1000:0042f55e 81e7ff000000         and    edi, ffh
1000:0042f564 3bbde0feffff         cmp    edi, [ebp-120h]
1000:0042f56a 7f28                 jg     42f594h

;*****************************************************************************
; [part1]
; we clearly see the get character and subtract '0' from it, so we
; expecting a number looking at this. if you trace into 40662ch you won't
; get far before you come across a '%d' which is for printing digits,
; probably into a string, (or scanning digits)
;*****************************************************************************

1000:0042f56c 8b45f8               mov    eax, [ebp-08h]
1000:0042f56f 0fb64438ff           movzx  eax, [eax-01h+edi]
1000:0042f574 8906                 mov    [esi], eax
1000:0042f576 832e30               sub    dword ptr [esi], "0"
1000:0042f579 8d95a0feffff         lea    edx, [ebp-160h]
1000:0042f57f 8b06                 mov    eax, [esi]
1000:0042f581 e8a670fdff           call   40662ch
1000:0042f586 8b95a0feffff         mov    edx, [ebp-160h]
1000:0042f58c 8d45f4               lea    eax, [ebp-0ch]
1000:0042f58f e83442fdff           call   4037c8h

;*****************************************************************************
; part of loop/branch
;*****************************************************************************

;                                                 XREFS First: 1000:0042f56a Number : 1
1000:0042f594 8b85e0feffff         mov    eax, [ebp-120h]
1000:0042f59a 40                   inc    eax
1000:0042f59b 3bf8                 cmp    edi, eax
1000:0042f59d 7e25                 jle    42f5c4h

;*****************************************************************************
; [part2]
; the second part of the serial could be anything at the moment.
;*****************************************************************************

1000:0042f59f 8b45f8               mov    eax, [ebp-08h]
1000:0042f5a2 0fb64438ff           movzx  eax, [eax-01h+edi]
1000:0042f5a7 8906                 mov    [esi], eax
1000:0042f5a9 8d85a0feffff         lea    eax, [ebp-160h]
1000:0042f5af 8b16                 mov    edx, [esi]
1000:0042f5b1 e83241fdff           call   4036e8h
1000:0042f5b6 8b95a0feffff         mov    edx, [ebp-160h]
1000:0042f5bc 8d45f0               lea    eax, [ebp-10h]
1000:0042f5bf e80442fdff           call   4037c8h

;*****************************************************************************
; end of loop
;*****************************************************************************

;                                                 XREFS First: 1000:0042f59d Number : 1
1000:0042f5c4 43                   inc    ebx
1000:0042f5c5 83c604               add    esi, 04h
1000:0042f5c8 fe4dd0               dec    byte ptr [ebp-30h]
1000:0042f5cb 758f                 jnz    42f55ch

;*****************************************************************************
; now check if [part2] has length 0, in which case we'll fail, note the use
; of [ebp-10h], which we relate with [part2] from the code above, and 4037c0h
; which we have seen everywhere, and which I really should have named ;)
;*****************************************************************************

;                                                 XREFS First: 1000:0042f54f Number : 1
1000:0042f5cd 8b45f0               mov    eax, [ebp-10h]
1000:0042f5d0 e8eb41fdff           call   4037c0h
1000:0042f5d5 85c0                 test   eax, eax
1000:0042f5d7 0f84d1030000         jz     finished_checkfail

;*****************************************************************************
; this next piece of code is quite simple. we call 40665ch with one parameter
; and tracing this (dont trace into the call, its Delphi crap.........)
; reveals that eax returns with the value of the number the string points to
; so string '1234' gets converted to 4d2h in eax. The next somewhat convoluted
; piece of code multiplies it by 4 and checks it comes to 1185648
; so our serial must begin with '296412-' note that this check is actually 
; repeated near the end of the routine too
;*****************************************************************************

1000:0042f5dd 8b45f4               mov    eax, [ebp-0ch]
1000:0042f5e0 e87770fdff           call   40665ch
1000:0042f5e5 8985e4feffff         mov    [ebp-11ch], eax
1000:0042f5eb 8b45f4               mov    eax, [ebp-0ch]
1000:0042f5ee e86970fdff           call   40665ch
1000:0042f5f3 03c0                 add    eax, eax
1000:0042f5f5 8985e0feffff         mov    [ebp-120h], eax
1000:0042f5fb 8b85e4feffff         mov    eax, [ebp-11ch]
1000:0042f601 0185e0feffff         add    [ebp-120h], eax
1000:0042f607 8b85e4feffff         mov    eax, [ebp-11ch]
1000:0042f60d 0185e0feffff         add    [ebp-120h], eax
1000:0042f613 81bde0feffff70171200 cmp    dword ptr [ebp-120h], 1185648
1000:0042f61d 0f858b030000         jnz    finished_checkfail

;*****************************************************************************
; so ends [part1], hehe
;*****************************************************************************

1000:0042f623 33c0                 xor    eax, eax
1000:0042f625 8945e4               mov    [ebp-1ch], eax
1000:0042f628 b301                 mov    bl, 01h
1000:0042f62a 8d7594               lea    esi, [ebp-6ch]
1000:0042f62d 8d8554ffffff         lea    eax, [ebp-ach]
1000:0042f633 8d9514ffffff         lea    edx, [ebp-ech]

;*****************************************************************************
; if you look carefully at the code (preferably without these comments in it)
; then you might notice we are now looking at several blocks of code of the
; form:
; [block1a]
; [block1b]
; [block2a]
; [block2b]
; one block is working on [ebp-4] (our name) and the other on [ebp-10] (the
; part 2 string)
;*****************************************************************************
; first the name loop, we loop for bl=1 to 4 and the following is executed on
; each loop, along with some conditions described below
; [esi]    =name[bl];
; [ebp-1c]+=name[bl]<<24;
;*****************************************************************************

;                                                 XREFS First: 1000:0042f69b Number : 1
1000:0042f639 33c9                 xor    ecx, ecx
1000:0042f63b 8acb                 mov    cl, bl
1000:0042f63d 8b7dfc               mov    edi, [ebp-04h]
1000:0042f640 0fb64c0fff           movzx  ecx, [edi-01h+ecx]
1000:0042f645 890e                 mov    [esi], ecx
1000:0042f647 8b0e                 mov    ecx, [esi]
1000:0042f649 c1e108               shl    ecx, 08h
1000:0042f64c c1e108               shl    ecx, 08h
1000:0042f64f c1e108               shl    ecx, 08h
1000:0042f652 014de4               add    [ebp-1ch], ecx

;*****************************************************************************
; now, if bl>1, we have
; [eax]    =name[bl-1];
; [ebp-1c]+=name[bl]<<16;
;*****************************************************************************

1000:0042f655 80fb01               cmp    bl, 01h
1000:0042f658 7619                 jbe    42f673h
1000:0042f65a 33c9                 xor    ecx, ecx
1000:0042f65c 8acb                 mov    cl, bl
1000:0042f65e 8b7dfc               mov    edi, [ebp-04h]
1000:0042f661 0fb64c0ffe           movzx  ecx, [edi-02h+ecx]
1000:0042f666 8908                 mov    [eax], ecx
1000:0042f668 8b08                 mov    ecx, [eax]
1000:0042f66a c1e108               shl    ecx, 08h
1000:0042f66d c1e108               shl    ecx, 08h
1000:0042f670 014de4               add    [ebp-1ch], ecx

;*****************************************************************************
; now, if bl>2, we have
; [edx]    =name[bl-2];
; [ebp-1c]+=name[bl]<<8;
;*****************************************************************************

;                                                 XREFS First: 1000:0042f658 Number : 1
1000:0042f673 80fb02               cmp    bl, 02h
1000:0042f676 7616                 jbe    42f68eh
1000:0042f678 33c9                 xor    ecx, ecx
1000:0042f67a 8acb                 mov    cl, bl
1000:0042f67c 8b7dfc               mov    edi, [ebp-04h]
1000:0042f67f 0fb64c0ffd           movzx  ecx, [edi-03h+ecx]
1000:0042f684 890a                 mov    [edx], ecx
1000:0042f686 8b0a                 mov    ecx, [edx]
1000:0042f688 c1e108               shl    ecx, 08h
1000:0042f68b 014de4               add    [ebp-1ch], ecx
;                                                 XREFS First: 1000:0042f676 Number : 1
1000:0042f68e 43                   inc    ebx
1000:0042f68f 83c204               add    edx, 04h
1000:0042f692 83c004               add    eax, 04h
1000:0042f695 83c604               add    esi, 04h
1000:0042f698 80fb05               cmp    bl, 05h
1000:0042f69b 759c                 jnz    42f639h

;*****************************************************************************
; finally, with the loop finished we do
; [ebp-1c]+=name[0]
; and then we just check that this is positive, using signed addition
; and losing any overflow, so [ebp-1c] is a kind of checksum for our name
; using 4-character ascii to represent 32 bits, we would have for 'Cronos',
; C000+rC00+orC0+norC
;*****************************************************************************

1000:0042f69d 8b45fc               mov    eax, [ebp-04h]
1000:0042f6a0 0fb600               movzx  eax, [eax]
1000:0042f6a3 0145e4               add    [ebp-1ch], eax
1000:0042f6a6 837de400             cmp    dword ptr [ebp-1ch], 00h
1000:0042f6aa 7d0c                 jge    42f6b8h
1000:0042f6ac 8b45e4               mov    eax, [ebp-1ch]
1000:0042f6af 05ffffff7f           add    eax, 7fffffffh
1000:0042f6b4 40                   inc    eax
1000:0042f6b5 8945e4               mov    [ebp-1ch], eax

;*****************************************************************************
; now we just reset a few of the variables we were using
;*****************************************************************************

;                                                 XREFS First: 1000:0042f6aa Number : 1
1000:0042f6b8 33c0                 xor    eax, eax
1000:0042f6ba 8945e0               mov    [ebp-20h], eax
1000:0042f6bd 33c0                 xor    eax, eax
1000:0042f6bf 89851cffffff         mov    [ebp-e4h], eax
1000:0042f6c5 33c0                 xor    eax, eax
1000:0042f6c7 898520ffffff         mov    [ebp-e0h], eax
1000:0042f6cd b301                 mov    bl, 01h
1000:0042f6cf 8d5594               lea    edx, [ebp-6ch]
1000:0042f6d2 8d8554ffffff         lea    eax, [ebp-ach]
1000:0042f6d8 8db514ffffff         lea    esi, [ebp-ech]

;*****************************************************************************
; now the code for the part2 serial code
; we loop for bl=1 to 4 and the following is executed on
; each loop, along with some conditions described below
; [edx]    =part2[bl];
; [ebp-20]+=part2[bl]<<8;
;*****************************************************************************

;                                                 XREFS First: 1000:0042f740 Number : 1
1000:0042f6de 33c9                 xor    ecx, ecx
1000:0042f6e0 8acb                 mov    cl, bl
1000:0042f6e2 8b7df0               mov    edi, [ebp-10h]
1000:0042f6e5 0fb64c0fff           movzx  ecx, [edi-01h+ecx]
1000:0042f6ea 890a                 mov    [edx], ecx
1000:0042f6ec 8b0a                 mov    ecx, [edx]
1000:0042f6ee c1e108               shl    ecx, 08h
1000:0042f6f1 014de0               add    [ebp-20h], ecx

;*****************************************************************************
; now, if bl>1, we have
; [eax]    =part2[bl-1];
; [ebp-20]+=part2[bl]<<16;
;*****************************************************************************

1000:0042f6f4 80fb01               cmp    bl, 01h
1000:0042f6f7 7619                 jbe    42f712h
1000:0042f6f9 33c9                 xor    ecx, ecx
1000:0042f6fb 8acb                 mov    cl, bl
1000:0042f6fd 8b7df0               mov    edi, [ebp-10h]
1000:0042f700 0fb64c0ffe           movzx  ecx, [edi-02h+ecx]
1000:0042f705 8908                 mov    [eax], ecx
1000:0042f707 8b08                 mov    ecx, [eax]
1000:0042f709 c1e108               shl    ecx, 08h
1000:0042f70c c1e108               shl    ecx, 08h
1000:0042f70f 014de0               add    [ebp-20h], ecx

;*****************************************************************************
; now, if bl>2, we have
; [esi]    =part2[bl-2];
; [ebp-20]+=part2[bl]<<24;
;*****************************************************************************

;                                                 XREFS First: 1000:0042f6f7 Number : 1
1000:0042f712 80fb02               cmp    bl, 02h
1000:0042f715 761c                 jbe    42f733h
1000:0042f717 33c9                 xor    ecx, ecx
1000:0042f719 8acb                 mov    cl, bl
1000:0042f71b 8b7df0               mov    edi, [ebp-10h]
1000:0042f71e 0fb64c0ffd           movzx  ecx, [edi-03h+ecx]
1000:0042f723 890e                 mov    [esi], ecx
1000:0042f725 8b0e                 mov    ecx, [esi]
1000:0042f727 c1e108               shl    ecx, 08h
1000:0042f72a c1e108               shl    ecx, 08h
1000:0042f72d c1e108               shl    ecx, 08h
1000:0042f730 014de0               add    [ebp-20h], ecx
;                                                 XREFS First: 1000:0042f715 Number : 1
1000:0042f733 43                   inc    ebx
1000:0042f734 83c604               add    esi, 04h
1000:0042f737 83c004               add    eax, 04h
1000:0042f73a 83c204               add    edx, 04h
1000:0042f73d 80fb05               cmp    bl, 05h
1000:0042f740 759c                 jnz    42f6deh

;*****************************************************************************
; finally, with the loop finished we do
; [ebp-20]+=part2[0]
;  so [ebp-20] is a kind of checksum for our serial part [2]
; using 4-character ascii to represent 32 bits, we would have for 'abcd',
; 00a0+0ab0+abc0+bcda
;*****************************************************************************

1000:0042f742 8b45f0               mov    eax, [ebp-10h]
1000:0042f745 0fb600               movzx  eax, [eax]
1000:0042f748 0145e0               add    [ebp-20h], eax

;*****************************************************************************
; if you take a quick glance towards the end then you will see that [ebp-14h]
; and [ebp-18h] will eventually hold two strings to be compared. this bit
; is just their initialisation
;*****************************************************************************

1000:0042f74b 8d45ec               lea    eax, [ebp-14h]
1000:0042f74e e8f13dfdff           call   403544h
1000:0042f753 8d45e8               lea    eax, [ebp-18h]
1000:0042f756 e8e93dfdff           call   403544h
1000:0042f75b b301                 mov    bl, 01h
1000:0042f75d 8d7594               lea    esi, [ebp-6ch]

;*****************************************************************************
; now this longer part is simply taking our first checksum, [ebp-1ch]
; and converting it into a string of hex digits at [ebp-14h]
;*****************************************************************************

;                                                 XREFS First: 1000:0042f852 Number : 1
1000:0042f760 8b45e4               mov    eax, [ebp-1ch]
1000:0042f763 250f000080           and    eax, 8000000fh
1000:0042f768 7905                 jns    42f76fh
1000:0042f76a 48                   dec    eax
1000:0042f76b 83c8f0               or     eax, -10h
1000:0042f76e 40                   inc    eax

;*****************************************************************************
; now the next block of code simply takes a look at [esi] and converts it
; from a 0h-0fh value into a '0'-'f' string.........
;*****************************************************************************

;                                                 XREFS First: 1000:0042f768 Number : 1
1000:0042f76f 8906                 mov    [esi], eax
1000:0042f771 85c0                 test   eax, eax
1000:0042f773 7506                 jnz    42f77bh
1000:0042f775 c70630000000         mov    dword ptr [esi], "0"
;                                                 XREFS First: 1000:0042f773 Number : 1
1000:0042f77b 833e01               cmp    dword ptr [esi], 01h
1000:0042f77e 7506                 jnz    42f786h
1000:0042f780 c70631000000         mov    dword ptr [esi], "1"
;                                                 XREFS First: 1000:0042f77e Number : 1
1000:0042f786 833e02               cmp    dword ptr [esi], 02h
1000:0042f789 7506                 jnz    42f791h
1000:0042f78b c70632000000         mov    dword ptr [esi], 32h
;                                                 XREFS First: 1000:0042f789 Number : 1
1000:0042f791 833e03               cmp    dword ptr [esi], 03h
1000:0042f794 7506                 jnz    42f79ch
1000:0042f796 c70633000000         mov    dword ptr [esi], 33h
;                                                 XREFS First: 1000:0042f794 Number : 1
1000:0042f79c 833e04               cmp    dword ptr [esi], 04h
1000:0042f79f 7506                 jnz    42f7a7h
1000:0042f7a1 c70634000000         mov    dword ptr [esi], 34h
;                                                 XREFS First: 1000:0042f79f Number : 1
1000:0042f7a7 833e05               cmp    dword ptr [esi], 05h
1000:0042f7aa 7506                 jnz    42f7b2h
1000:0042f7ac c70635000000         mov    dword ptr [esi], 35h
;                                                 XREFS First: 1000:0042f7aa Number : 1
1000:0042f7b2 833e06               cmp    dword ptr [esi], 06h
1000:0042f7b5 7506                 jnz    42f7bdh
1000:0042f7b7 c70636000000         mov    dword ptr [esi], 36h
;                                                 XREFS First: 1000:0042f7b5 Number : 1
1000:0042f7bd 833e07               cmp    dword ptr [esi], 07h
1000:0042f7c0 7506                 jnz    42f7c8h
1000:0042f7c2 c70637000000         mov    dword ptr [esi], 37h
;                                                 XREFS First: 1000:0042f7c0 Number : 1
1000:0042f7c8 833e08               cmp    dword ptr [esi], 08h
1000:0042f7cb 7506                 jnz    42f7d3h
1000:0042f7cd c70638000000         mov    dword ptr [esi], 38h
;                                                 XREFS First: 1000:0042f7cb Number : 1
1000:0042f7d3 833e09               cmp    dword ptr [esi], 09h
1000:0042f7d6 7506                 jnz    42f7deh
1000:0042f7d8 c70639000000         mov    dword ptr [esi], 39h
;                                                 XREFS First: 1000:0042f7d6 Number : 1
1000:0042f7de 833e0a               cmp    dword ptr [esi], 0ah
1000:0042f7e1 7506                 jnz    42f7e9h
1000:0042f7e3 c70641000000         mov    dword ptr [esi], 41h
;                                                 XREFS First: 1000:0042f7e1 Number : 1
1000:0042f7e9 833e0b               cmp    dword ptr [esi], 0bh
1000:0042f7ec 7506                 jnz    42f7f4h
1000:0042f7ee c70642000000         mov    dword ptr [esi], 42h
;                                                 XREFS First: 1000:0042f7ec Number : 1
1000:0042f7f4 833e0c               cmp    dword ptr [esi], 0ch
1000:0042f7f7 7506                 jnz    42f7ffh
1000:0042f7f9 c70643000000         mov    dword ptr [esi], 43h
;                                                 XREFS First: 1000:0042f7f7 Number : 1
1000:0042f7ff 833e0d               cmp    dword ptr [esi], 0dh
1000:0042f802 7506                 jnz    42f80ah
1000:0042f804 c70644000000         mov    dword ptr [esi], 44h
;                                                 XREFS First: 1000:0042f802 Number : 1
1000:0042f80a 833e0e               cmp    dword ptr [esi], 0eh
1000:0042f80d 7506                 jnz    42f815h
1000:0042f80f c70645000000         mov    dword ptr [esi], 45h
;                                                 XREFS First: 1000:0042f80d Number : 1
1000:0042f815 833e0f               cmp    dword ptr [esi], 0fh
1000:0042f818 7506                 jnz    42f820h
1000:0042f81a c70646000000         mov    dword ptr [esi], 46h
;                                                 XREFS First: 1000:0042f818 Number : 1
1000:0042f820 8d85a0feffff         lea    eax, [ebp-160h]
1000:0042f826 8b16                 mov    edx, [esi]
1000:0042f828 e8bb3efdff           call   4036e8h
1000:0042f82d 8b95a0feffff         mov    edx, [ebp-160h]
1000:0042f833 8d45ec               lea    eax, [ebp-14h]
1000:0042f836 e88d3ffdff           call   4037c8h
1000:0042f83b 8b45e4               mov    eax, [ebp-1ch]
1000:0042f83e 85c0                 test   eax, eax
1000:0042f840 7903                 jns    42f845h
1000:0042f842 83c00f               add    eax, 0fh
;                                                 XREFS First: 1000:0042f840 Number : 1
1000:0042f845 c1f804               sar    eax, 04h
1000:0042f848 8945e4               mov    [ebp-1ch], eax
1000:0042f84b 43                   inc    ebx
1000:0042f84c 83c604               add    esi, 04h
1000:0042f84f 80fb05               cmp    bl, 05h
1000:0042f852 0f8508ffffff         jnz    42f760h

;*****************************************************************************
; thats it for that part, on to the next....., first just make sure [ebp-20h]
; is signed, as for [ebp-1ch] earlier.
;*****************************************************************************

1000:0042f858 837de000             cmp    dword ptr [ebp-20h], 00h
1000:0042f85c 7d0c                 jge    42f86ah
1000:0042f85e 8b45e0               mov    eax, [ebp-20h]
1000:0042f861 05ffffff7f           add    eax, 7fffffffh
1000:0042f866 40                   inc    eax
1000:0042f867 8945e0               mov    [ebp-20h], eax
;                                                 XREFS First: 1000:0042f85c Number : 1
1000:0042f86a c645d301             mov    byte ptr [ebp-2dh], 01h
1000:0042f86e 8db5a4feffff         lea    esi, [ebp-15ch]

;*****************************************************************************
; and this longer part is simply taking our first checksum, [ebp-20h]
; and converting it into a string of hex digits at [ebp-18h] in the same
; was that the other string was converted.
;*****************************************************************************

;                                                 XREFS First: 1000:0042f968 Number : 1
1000:0042f874 8b45e0               mov    eax, [ebp-20h]
1000:0042f877 83e00f               and    eax, 0fh

;*****************************************************************************
; now the next block of code simply takes a look at [esi] and converts it
; from a 0h-0fh value into a '0'-'f' string.........
;*****************************************************************************

1000:0042f87a 8906                 mov    [esi], eax
1000:0042f87c 85c0                 test   eax, eax
1000:0042f87e 7506                 jnz    42f886h
1000:0042f880 c70630000000         mov    dword ptr [esi], 30h
;                                                 XREFS First: 1000:0042f87e Number : 1
1000:0042f886 833e01               cmp    dword ptr [esi], 01h
1000:0042f889 7506                 jnz    42f891h
1000:0042f88b c70631000000         mov    dword ptr [esi], 31h
;                                                 XREFS First: 1000:0042f889 Number : 1
1000:0042f891 833e02               cmp    dword ptr [esi], 02h
1000:0042f894 7506                 jnz    42f89ch
1000:0042f896 c70632000000         mov    dword ptr [esi], 32h
;                                                 XREFS First: 1000:0042f894 Number : 1
1000:0042f89c 833e03               cmp    dword ptr [esi], 03h
1000:0042f89f 7506                 jnz    42f8a7h
1000:0042f8a1 c70633000000         mov    dword ptr [esi], 33h
;                                                 XREFS First: 1000:0042f89f Number : 1
1000:0042f8a7 833e04               cmp    dword ptr [esi], 04h
1000:0042f8aa 7506                 jnz    42f8b2h
1000:0042f8ac c70634000000         mov    dword ptr [esi], 34h
;                                                 XREFS First: 1000:0042f8aa Number : 1
1000:0042f8b2 833e05               cmp    dword ptr [esi], 05h
1000:0042f8b5 7506                 jnz    42f8bdh
1000:0042f8b7 c70635000000         mov    dword ptr [esi], 35h
;                                                 XREFS First: 1000:0042f8b5 Number : 1
1000:0042f8bd 833e06               cmp    dword ptr [esi], 06h
1000:0042f8c0 7506                 jnz    42f8c8h
1000:0042f8c2 c70636000000         mov    dword ptr [esi], 36h
;                                                 XREFS First: 1000:0042f8c0 Number : 1
1000:0042f8c8 833e07               cmp    dword ptr [esi], 07h
1000:0042f8cb 7506                 jnz    42f8d3h
1000:0042f8cd c70637000000         mov    dword ptr [esi], 37h
;                                                 XREFS First: 1000:0042f8cb Number : 1
1000:0042f8d3 833e08               cmp    dword ptr [esi], 08h
1000:0042f8d6 7506                 jnz    42f8deh
1000:0042f8d8 c70638000000         mov    dword ptr [esi], 38h
;                                                 XREFS First: 1000:0042f8d6 Number : 1
1000:0042f8de 833e09               cmp    dword ptr [esi], 09h
1000:0042f8e1 7506                 jnz    42f8e9h
1000:0042f8e3 c70639000000         mov    dword ptr [esi], 39h
;                                                 XREFS First: 1000:0042f8e1 Number : 1
1000:0042f8e9 833e0a               cmp    dword ptr [esi], 0ah
1000:0042f8ec 7506                 jnz    42f8f4h
1000:0042f8ee c70641000000         mov    dword ptr [esi], 41h
;                                                 XREFS First: 1000:0042f8ec Number : 1
1000:0042f8f4 833e0b               cmp    dword ptr [esi], 0bh
1000:0042f8f7 7506                 jnz    42f8ffh
1000:0042f8f9 c70642000000         mov    dword ptr [esi], 42h
;                                                 XREFS First: 1000:0042f8f7 Number : 1
1000:0042f8ff 833e0c               cmp    dword ptr [esi], 0ch
1000:0042f902 7506                 jnz    42f90ah
1000:0042f904 c70643000000         mov    dword ptr [esi], 43h
;                                                 XREFS First: 1000:0042f902 Number : 1
1000:0042f90a 833e0d               cmp    dword ptr [esi], 0dh
1000:0042f90d 7506                 jnz    42f915h
1000:0042f90f c70644000000         mov    dword ptr [esi], 44h
;                                                 XREFS First: 1000:0042f90d Number : 1
1000:0042f915 833e0e               cmp    dword ptr [esi], 0eh
1000:0042f918 7506                 jnz    42f920h
1000:0042f91a c70645000000         mov    dword ptr [esi], 45h
;                                                 XREFS First: 1000:0042f918 Number : 1
1000:0042f920 833e0f               cmp    dword ptr [esi], 0fh
1000:0042f923 7506                 jnz    42f92bh
1000:0042f925 c70646000000         mov    dword ptr [esi], 46h
;                                                 XREFS First: 1000:0042f923 Number : 1
1000:0042f92b 8d85a0feffff         lea    eax, [ebp-160h]
1000:0042f931 8b16                 mov    edx, [esi]
1000:0042f933 e8b03dfdff           call   4036e8h
1000:0042f938 8b95a0feffff         mov    edx, [ebp-160h]
1000:0042f93e 8d45e8               lea    eax, [ebp-18h]
1000:0042f941 e8823efdff           call   4037c8h
1000:0042f946 b301                 mov    bl, 01h
;                                                 XREFS First: 1000:0042f95c Number : 1
1000:0042f948 8b45e0               mov    eax, [ebp-20h]
1000:0042f94b 85c0                 test   eax, eax
1000:0042f94d 7903                 jns    42f952h
1000:0042f94f 83c00f               add    eax, 0fh
;                                                 XREFS First: 1000:0042f94d Number : 1
1000:0042f952 c1f804               sar    eax, 04h
1000:0042f955 8945e0               mov    [ebp-20h], eax
1000:0042f958 43                   inc    ebx
1000:0042f959 80fb02               cmp    bl, 02h
1000:0042f95c 75ea                 jnz    42f948h
1000:0042f95e fe45d3               inc    byte ptr [ebp-2dh]
1000:0042f961 83c604               add    esi, 04h
1000:0042f964 807dd305             cmp    byte ptr [ebp-2dh], 05h
1000:0042f968 0f8506ffffff         jnz    42f874h

;*****************************************************************************
; the only part which can fail us in the checking of [part2] is here. it's
; a string comparison between those two converted checksums. So we can forget 
; most of the last bit, with all the conversion to hex digits going on, and 
; just concentrate on solving:
; C000+rC00+orC0+norC=00a0+0ab0+abc0+bcda
; you should see immediately from this that if a=C and b=r then we have
; C000+rC00+orC0+norC=00C0+0Cr0+Crc0+rcdC
; which we can simplify to
; 0000+r000+or00+nor0=0000+00r0+0rc0+rcd0
; by cancelling C's, giving
; r000+or00+nor0=00r0+0rc0+rcd0
; then, cancelling r's,
; 0000+o000+no00=0000+00c0+0cd0
; so we have
; o000+no00=00c0+0cd0
; now this doesnt look possible, but here we have an idea. The strings being
; compared are based on the last two digits only........ so if c and d are 
; zero then we do not need to worry about the rest......
; So, name 'Cronos', serial 296412-Cr, try it.......it works.... :)
;*****************************************************************************

1000:0042f96e 8b45ec               mov    eax, [ebp-14h]
1000:0042f971 8b55e8               mov    edx, [ebp-18h]
1000:0042f974 e8573ffdff           call   4038d0h
1000:0042f979 7513                 jnz    42f98eh

;*****************************************************************************
; success!!!!!!!!!!
;*****************************************************************************

1000:0042f97b 6a00                 push   00h
1000:0042f97d 6814fa4200           push   offset s_Success
1000:0042f982 681cfa4200           push   offset s_Yeah__you_did_it__cracker__Now_you_a
1000:0042f987 6a00                 push   00h
1000:0042f989 e87e5cfdff           call   _MessageBoxA

;*****************************************************************************
; if we jump past here then we've failed, forget the rest of the checks.
;*****************************************************************************

;                                                 XREFS First: 1000:0042f979 Number : 1
1000:0042f98e 8b45ec               mov    eax, [ebp-14h]
1000:0042f991 8b55e8               mov    edx, [ebp-18h]
1000:0042f994 e8373ffdff           call   4038d0h
1000:0042f999 7413                 jz     finished_checkfail
1000:0042f99b 6a00                 push   00h
1000:0042f99d 6860fa4200           push   offset s_Failure
1000:0042f9a2 6868fa4200           push   offset s_No_cracker__You_failed_to_enter_a_va
1000:0042f9a7 6a00                 push   00h
1000:0042f9a9 e85e5cfdff           call   _MessageBoxA
finished_checkfail:
;                                                 XREFS First: 1000:0042f4cf Number : 4
1000:0042f9ae 807dd200             cmp    byte ptr [ebp-2eh], 00h
1000:0042f9b2 7418                 jz     42f9cch
1000:0042f9b4 8b45f0               mov    eax, [ebp-10h]
1000:0042f9b7 e8043efdff           call   4037c0h
1000:0042f9bc 85c0                 test   eax, eax
1000:0042f9be 740c                 jz     42f9cch
1000:0042f9c0 81bde0feffff70171200 cmp    dword ptr [ebp-120h], 1185648
1000:0042f9ca 7413                 jz     42f9dfh
;                                                 XREFS First: 1000:0042f9b2 Number : 2
1000:0042f9cc 6a00                 push   00h
1000:0042f9ce 6860fa4200           push   offset s_Failure
1000:0042f9d3 6868fa4200           push   offset s_No_cracker__You_failed_to_enter_a_va
1000:0042f9d8 6a00                 push   00h
1000:0042f9da e82d5cfdff           call   _MessageBoxA
;                                                 XREFS First: 1000:0042f491 Number : 2
1000:0042f9df 33c0                 xor    eax, eax
1000:0042f9e1 5a                   pop    edx
1000:0042f9e2 59                   pop    ecx
1000:0042f9e3 59                   pop    ecx
1000:0042f9e4 648910               mov    fs:[eax], edx
1000:0042f9e7 680cfa4200           push   42fa0ch
;                                                 XREFS First: 1000:0042fa0a Number : 1
1000:0042f9ec 8d85a0feffff         lea    eax, [ebp-160h]
1000:0042f9f2 e84d3bfdff           call   403544h
1000:0042f9f7 8d45e8               lea    eax, [ebp-18h]
1000:0042f9fa ba06000000           mov    edx, 06h
1000:0042f9ff e8643bfdff           call   403568h
1000:0042fa04 c3                   ret    
;                                                 XREFS First: 1000:0042f441 Number : 1
1000:0042fa05 e9de35fdff           jmp    402fe8h
1000:0042fa0a ebe0                 jmp    42f9ech
1000:0042fa0c 5f                   pop    edi
1000:0042fa0d 5e                   pop    esi
1000:0042fa0e 5b                   pop    ebx
1000:0042fa0f 8be5                 mov    esp, ebp
1000:0042fa11 5d                   pop    ebp
1000:0042fa12 c3                   ret    
1000:0042fa13 00                   db     00
s_Success:
;                                                 XREFS First: 1000:0042f97d Number : 1
1000:0042fa14 5375636365737300     ds     "Success"
s_Yeah__you_did_it__cracker__Now_you_a:
;                                                 XREFS First: 1000:0042f982 Number : 1
1000:0042fa1c 596561682c20796f75.. ds     "Yeah, you did it, cracker. Now you are ready to step to next level."
s_Failure:
;                                                 XREFS First: 1000:0042f99d Number : 2
1000:0042fa60 4661696c75726500     ds     "Failure"
s_No_cracker__You_failed_to_enter_a_va:
;                                                 XREFS First: 1000:0042f9a2 Number : 2
1000:0042fa68 4e6f2c637261636b65.. ds     "No,cracker. You failed to enter a valid serial"

And so there is Falcons challenge solved, name:Cronos, serial 296412-Cr, in fact name:xyzzzz, serial 296412-xy. [No need to write a keygen then......].

Conclusions

This crackme was quite hard, although the hardest part for most people will probably be understanding how Delphi compiles programs.

{Cronos}