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
The crackme says you just need a serial and presents you with a box for a name and four spinners with which to enter a serial number. I note that there is a reg.dat file with the crackme but I didn't find a use for it, perhaps it is just for some obscurity ? A red herring ? Oh well, I cracked it first and realised there was this file later :).
Analysis
It's not difficult to find the relevant part of the program, with the success messages in, and not far away is some code which stands out due to its use of some values and some maths involving idiv's. In the disassembly of the program I have just shown the mainly relevant parts of the code, in a more relevant order for me to talk about.
success_messages: ; XREFS First: 1000:00437b8f Number : 1 1000:00437ea0 6a00 push 00h 1000:00437ea2 68b47e4300 push offset s_Success_ 1000:00437ea7 68c07e4300 push offset s_Hey__Man__you_did_it__You_cracked_my 1000:00437eac 6a00 push 00h 1000:00437eae e831dbfcff call _MessageBoxA 1000:00437eb3 c3 ret s_Success_: ; XREFS First: 1000:00437ea2 Number : 1 1000:00437eb4 537563636573732100 ds "Success!" 1000:00437ebd 00 db 00 1000:00437ebe 00 db 00 1000:00437ebf 00 db 00 s_Hey__Man__you_did_it__You_cracked_my: ; XREFS First: 1000:00437ea7 Number : 1 1000:00437ec0 4865792c204d616e2c.. ds "Hey, Man, you did it!You " "cracked my little proggie.AAAAH! :(" |
Here is the first part we spot, although browsing through the code would soon reveal the second part below, which contains the serial code we are looking for. |
1000:00437c02 8b45fc mov eax, [ebp-04h] 1000:00437c05 e86ebdfcff call 403978h 1000:00437c0a 83f805 cmp eax, 05h ; length >=5 ? 1000:00437c0d 0f8caf000000 jl 437cc2h 1000:00437c13 8b45fc mov eax, [ebp-04h] 1000:00437c16 0fb600 movzx eax, [eax] ; first character 1000:00437c19 b90a000000 mov ecx, 0ah ; divide by 10 1000:00437c1e 99 cdq 1000:00437c1f f7f9 idiv ecx 1000:00437c21 a32ca74300 mov [43a72ch], eax ; save result 1000:00437c26 8b45fc mov eax, [ebp-04h] 1000:00437c29 0fb64002 movzx eax, [eax+02h] ; third character 1000:00437c2d b90a000000 mov ecx, 0ah 1000:00437c32 99 cdq 1000:00437c33 f7f9 idiv ecx ; divide by 10 1000:00437c35 a330a74300 mov [43a730h], eax ; save 1000:00437c3a 8b45fc mov eax, [ebp-04h] 1000:00437c3d 0fb64003 movzx eax, [eax+03h] ; fourth character 1000:00437c41 b90a000000 mov ecx, 0ah 1000:00437c46 99 cdq 1000:00437c47 f7f9 idiv ecx ; divide by 10 1000:00437c49 a334a74300 mov [43a734h], eax ; save 1000:00437c4e 8b45fc mov eax, [ebp-04h] 1000:00437c51 0fb64004 movzx eax, [eax+04h] ; fifth character 1000:00437c55 b90a000000 mov ecx, 0ah 1000:00437c5a 99 cdq 1000:00437c5b f7f9 idiv ecx ; divide by 10 1000:00437c5d a338a74300 mov [43a738h], eax ; save 1000:00437c62 be01000000 mov esi, 01h 1000:00437c67 bb2ca74300 mov ebx, offset 43a72ch ; XREFS First: 1000:00437c94 Number : 1 1000:00437c6c 8d55f8 lea edx, [ebp-08h] 1000:00437c6f 8b03 mov eax, [ebx] 1000:00437c71 e88aecfcff call 406900h 1000:00437c76 8b45f8 mov eax, [ebp-08h] 1000:00437c79 e8fabcfcff call 403978h 1000:00437c7e 48 dec eax 1000:00437c7f 740c jz 437c8dh 1000:00437c81 8b03 mov eax, [ebx] ; just check to see if any 1000:00437c83 b90a000000 mov ecx, 0ah ; are more than 10 1000:00437c88 99 cdq ; in which case we divide again 1000:00437c89 f7f9 idiv ecx 1000:00437c8b 8903 mov [ebx], eax ; XREFS First: 1000:00437c7f Number : 1 1000:00437c8d 46 inc esi 1000:00437c8e 83c304 add ebx, 04h 1000:00437c91 83fe05 cmp esi, 05h 1000:00437c94 75d6 jnz 437c6ch 1000:00437c96 be01000000 mov esi, 01h 1000:00437c9b b82ca74300 mov eax, offset 43a72ch ; now check it 1000:00437ca0 ba3ca74300 mov edx, offset 43a73ch ; to spinner settings ; XREFS First: 1000:00437cbe Number : 1 1000:00437ca5 8b0a mov ecx, [edx] 1000:00437ca7 3b08 cmp ecx, [eax] 1000:00437ca9 7407 jz 437cb2h 1000:00437cab b901000000 mov ecx, 01h 1000:00437cb0 eb15 jmp 437cc7h ; XREFS First: 1000:00437ca9 Number : 1 1000:00437cb2 33c9 xor ecx, ecx 1000:00437cb4 46 inc esi 1000:00437cb5 83c204 add edx, 04h 1000:00437cb8 83c004 add eax, 04h 1000:00437cbb 83fe05 cmp esi, 05h 1000:00437cbe 75e5 jnz 437ca5h 1000:00437cc0 eb05 jmp 437cc7h ; XREFS First: 1000:00437c0d Number : 1 1000:00437cc2 b901000000 mov ecx, 01h ; XREFS First: 1000:00437cb0 Number : 2 1000:00437cc7 85c9 test ecx, ecx 1000:00437cc9 7514 jnz 437cdfh 1000:00437ccb a128a74300 mov eax, [43a728h] 1000:00437cd0 8b80e0010000 mov eax, [eax+1e0h] 1000:00437cd6 b201 mov dl, 01h 1000:00437cd8 e87b54feff call 41d158h 1000:00437cdd eb12 jmp 437cf1h |
This is the majority of a subroutine which starts with typical Delphi instance code and ends with typical Delphi exit code. You can see the regular mov ecx,0ah followed by cdq followed by idiv ecx. In depth this is taking some characters from the name we input (offsets 0,2,3,4 so 'Cronos' uses 'Cono'). For each digit we take the Ascii value and divide by 10 to produce a set of figures. We then check if any are more than 9 and if they are we divide them again by 10. The result is four digits (and we have four spinners which go from 0 to 9 :)). These four digits are the code we need to set. Simple. So for 'Cronos' we use 'Cono' which is 67,111,110,111 and we are just taking the first digit of each, or '6111' which is the code to set on the spinners.
In fact this is the sort of place I would enter 'aaaaaa' as the code and see if it matched any of '0000' to '9999', which of course it does ('9999'). |
And so there you have it, name:Cronos, serial:6111.
Conclusions
This crackme was quite easy, the hardest part for most people will probably be understanding how Delphi compiles programs.
{Cronos}