Solution Detten crackme 11

Saturday, August 16 2008 @ 11:00 AM CEST

Contributed by: detten

Level : beginner

one thing: save the humanity!

tools: softice for all:))

Crackme [file:20080313184515308 download here]

ok, it's time to save the planet!!!
read the story and take a look to the reference manual:))
here is our task:
1 enable the security mode
2 start the pacman bot
3 flush the battery of the bot
4 start the firewall

we can start with the first: enable the security mode
the command is: "SECURITY MODE"
the password is: ???
so, 'bpx getdlgitemtexta' and click on the "send" button (use this
breakpoint to read any command):

00401289 call j_GetDlgItemTextA ; retrieves the command
0040128E push offset aSecuritymode ; "SECURITYMODE"
00401293 push dword_40D5E4 ; the command you have typed
00401299 call loc_40232C ; compare "SECURITYMODE" with your
0040129E add esp, 8
004012A1 test eax, eax ; if the command is "SECURITYMODE"
004012A3 jnz short loc_401300 ; don't jump
004012A5 push 6Ah
004012A7 push ebx
004012A8 call j_GetDlgItem ; retrieves the handle of the password's editbox
004012AD push eax
004012AE call j_GetWindowTextLengthA ; retrieves the length of the
text in the password's editbox
004012B3 mov esi, eax ; stores the length
004012B5 lea eax, [esi+1]
004012B8 push eax
004012B9 push 40h
004012BB call j_GlobalAlloc ; allocates length(password) bytes
for the password
004012C0 mov dword_40D5E8, eax
004012C5 inc esi
004012C6 push esi
004012C7 push dword_40D5E8 ; points to the first byte of the
allocates memory
004012CD push 6Ah
004012CF push ebx
004012D0 call j_GetDlgItemTextA ; retrieves the password
004012D5 push offset aSpirits ; push "SPIRITS"
004012DA push dword_40D5E8 ; push the password
004012E0 call loc_40232C ; compare "SPIRITS" with our password
004012E5 add esp, 8
004012E8 test eax, eax ; the two string must be equals
004012EA jnz short loc_401300
004012EC push offset aSecuritymodeEn ; push "SECURITYMODE ENABLED."
004012F1 push 65h
004012F3 push ebx
004012F4 call j_SetDlgItemTextA ; place the text "SECURITYMODE
ENABLED." in the highest box
004012F9 mov byte_40B1C0, 1 ; to remember that the security mode is enable

we have found the password: SPIRITS

the first task is done! it's time to task #2: start the pacman bot
type 'START PATROL' in the command's editbox and see what happen (no
password is needed):

00401300 push offset aStartPatrol ; push "START PATROL"
00401305 push dword_40D5E4 ; push our command: START PATROL
0040130B call loc_40232C ; compare our command with "START
00401310 add esp, 8
00401313 test eax, eax ; if the commands are equals:
00401315 jnz short loc_401352 ; don't jump
00401317 cmp byte_40B1C0, 0 ; security mode enabled???
0040131E jz short loc_401352 ; yes if byte_40B1C0 = 1 (and no
00401320 push offset aPatrolStarted_ ; psuh "PATROL
00401325 push 65h
00401327 push ebx
00401328 call j_SetDlgItemTextA ; the new text in the highest box
0040132D movsx eax, byte_40B1BA ; 40B1BA points to 0
00401334 dec eax ; eax = -1
00401335 jz short loc_40134B ; jump if eax != 0
00401337 push 30h
00401339 push offset aMessage ; "Message"
0040133E push offset aYourPackmanIsD ; "Your packman is
disabled! Activate him "...
00401343 push ebx
00401344 call j_MessageBoxA
00401349 jmp short loc_401352
0040134B mov byte_40B1C1, 1 ; to remember that the pacman is
00401352 ...

hmmm...the pacman is not enabled!
you will enable the bot if byte_40B1BA is 1. search for it in the
disasm and:

00401F91 cmp dword_40B1B0, 6
00401F98 jle short loc_401FA1 ; if no: jump and increment the
value of the byte pointed by 40B1B0
00401F9A mov byte_40B1BA, 1
00401FA1 inc dword_40B1B0

interesting! if you take a closer look in the disasm you'll find that
these piece of code is processed when you click on the terminal's bitmap
in the main window.
ok, click on the bitmap for 7 times and...the packman is now enable,
ready to eat ghosts:)))
he's waiting for the command: START PATROL
now the patrol started but we have another problem: the packman is
frozen by a spell:(

004018C7 cmp byte_40B1BF, 0 ; 40B1BF is 0 and...
004018CE jnz short loc_4018F4 ; no jump:(
004018D0 cmp byte_40B1BE, 0
004018D7 jnz short loc_4018F4
004018D9 mov byte_40B1BE, 1
004018E0 push 30h
004018E2 push offset aDamn ; "Damn !"
004018E7 push offset aUrPacmanIsFroz ; "Ur pacman is frozen by a spell :( Break"...
004018EC push dword ptr [ebp+8]
004018EF call j_MessageBoxA

as before, look for 40B1BF:

00401FFD cmp dword_40B1DC, 4
00402004 jle short loc_40200D
00402006 mov byte_40B1BF, 1
0040200D inc dword_40B1DC

the byte pointed by 40B1BF will be 1 if you click on the pacman's
bitmap for at least 5 times!
ok, our packman is protected against the spell!!
so at the end of this task: before type the command "START PATROL"
enable the bot and protect it against the spell. after the 'start patrol'
command the bot will eat a lot of ghosts!!!!
do you remember the note in the reference manual?
so, if you want to save the humanity you have to find the password for
the flush battery command!
when the bot can't eat anymore a msgbox appear and the bot stops
himself. it's time to type the magical command "FLUSH BATTERY" and a fake

00401352 push offset aFlushBattery ; "FLUSH BATTERY"
00401357 push dword_40D5E4 ; our command: "FLUSH BATTERY"
0040135D call loc_40232C ; the commands are equals?
00401362 add esp, 8
00401365 test eax, eax ; yes and we don't jump
00401367 jnz short loc_4013C5
00401369 cmp byte_40B1C1, 0 ; the pacman is enabled??
00401370 jz short loc_4013C5 ; yes:) no jump
00401372 cmp byte_40B1C0, 0 ; the security mode is enabled??
00401379 jz short loc_4013C5 ; yes:)) no jump
0040137B cmp byte_40B1B8, 0 ; battery overload??
00401382 jz short loc_4013C5 ; yes: no jump
004013AF call j_GetDlgItemTextA ; reads the password for the
flush battery command
004013B4 push dword_40D5E8 ; push it
004013BA call loc_40119C ; important call

the call verify the password we have typed. we have to enter in it:

004011A9 movsx ebx, byte ptr [edx+eax] ; bl = eax° char of the
004011AD add ecx, ebx ; ecx is the partial sum of the password's
004011AF movsx ebx, byte ptr [edx+eax]
004011B3 cmp ebx, 30h ; each chars of the password must be >=
004011B6 jl short loc_4011C1
004011B8 movsx ebx, byte ptr [edx+eax]
004011BC cmp ebx, 39h ; and == than 0x12C
004011D3 jge short loc_4011DA
004011D5 mov al, 1 ; will fail the mission:((
004011DA movsx ebx, byte ptr [edx+eax-1] ; some simple operation...
004011DF xor ecx, ebx
004011E1 movsx ebx, byte ptr [edx+eax-4]
004011E6 xor ecx, ebx
004011E8 movsx eax, byte ptr [edx+eax-6]
004011ED xor ecx, eax
004011EF cmp ecx, 239h ; ecx must be 0x239
004011F5 jnz short loc_4011FC ; if so: ok!;)...otherwise: you fail:(
004011F7 xor eax, eax

it's time to find the right serial.
it's easy and you can do it at hand. i choose: 0000959009
infact: (6 * 0x30) + 0x35 + (3 * 0x39) = 0x120 + 0x35 + 0xAB = 0x209
and: (((0x209 xor 0x39) xor 0x39) xor 0x39) = 0x239
this is one of the possible (right) passwords (you can use 5000909009
or 0000909239 or 5555050880 what you want...)

ok, the last task: start the firewall.
put "START FIREWALL" as command and enter a fake password:

004013C5 push offset aStartFirewall ; "START FIREWALL"
004013CA push dword_40D5E4 ; our command
004013D0 call loc_40232C ; compare the command with "START
004013D5 add esp, 8
004013D8 test eax, eax ; equals??
004013DA jnz loc_401484
004013E0 cmp byte_40B1C0, 0 ; the security mode is enabled??
004013E7 jz loc_401484 ; yes!, no jump
004013ED cmp byte_40B1C1, 0 ; the pacman is enabled??
004013F4 jz loc_401484 ; yes!!, no jump
00401425 call j_GetDlgItemTextA ; reads the serial for the
firewall's command
0040142A push dword_40D5E8
00401430 call loc_401108 ; routine that checked the password

so, enter in it:

00401118 movsx eax, byte ptr [esi] ; eax is the first char of the
0040111B add eax, ebx
0040111D add ecx, eax ; pay attention to the value stored in
0040111F cmp ecx, 0B4h
00401125 jle short loc_401132
00401127 sub ecx, 1Dh
0040112A cmp ecx, 0B4h
00401130 jg short loc_401127
00401132 inc ebx
00401133 cmp byte ptr [esi+ebx], 0 ; do you reach the end of the
00401137 jnz short loc_401118 ; no: jump up...
00401139 cmp ebx, 8 ; the length of the password must be at
least 8 chars
0040113C jge short loc_401142
0040113E xor eax, eax ; otherwise....error!
00401140 jmp short loc_401196
00401142 movsx edi, byte ptr [esi+ebx-1] ;
00401147 movsx eax, byte ptr [esi+ebx-2] ;
0040114C add edi, eax ;
0040114E movsx edx, byte ptr [esi+ebx-3] ;
00401153 add edi, edx ; sum the last 3 chars of the password
00401155 mov eax, edi
00401157 cdq
00401158 idiv ecx ; sum / ecx
0040115A mov [ebp-4], eax ; stores the ratio
0040115D mov eax, edi ; repeats the operation...i don't know
0040115F cdq ; "
00401160 idiv ecx ; "
00401162 mov eax, edx ; eax is the rest
00401164 cmp dword ptr [ebp-4], 0 ; compare the ratio with 0
00401168 jle short loc_401189 ; jump if the ratio is 0 and go to
0040116A mov edx, ebx
0040116C sar edx, 1
0040116E jns short loc_401173
00401170 adc edx, 0
00401173 movsx ecx, byte ptr [esi+edx-1] ; cl is the 'middle'
chars of the password
00401178 add eax, ecx
0040117A lea edx, [ebx+ebx*8] ; ebx is the length of the password
0040117D add eax, edx
0040117F dec ebx
00401180 dec dword ptr [ebp-4]
00401183 cmp dword ptr [ebp-4], 0
00401187 jg short loc_40116A ; a little cycle repeated ratio (>0)
00401189 cmp eax, 0CBh ; if we arrive here from 401168 it's
impossible that the rest is equal
; to 0xCB ==> error!
0040118E jnz short loc_401194 ; if the rest is 0xCB we are ok!
00401190 mov al, 1 ; al = 1 means right password
00401192 jmp short loc_401196
00401194 xor eax, eax ; al = 0 means wrong password

let's go to find the password!
don't be afraid:))) it's very simple.
a valid password has at least 8 chars but this routine works with only
5 of these chars: the first, the 'middle' and the last 3 chars.
choose a fake password (i'll work with '123456789') and look what
- 401118/401137: the cycle is based on the first chars "1" and when
you'll arrive in 401142 ecx is 0x9E
- 401142/401153: the sum of the last 3 chars (7, 8 and 9) is 0xA8
- 401155/40115A: 0xA8 / 0x9E : ratio = 1, rest = 0x0A
- 40116A/401189: if (rest + middle + (9 * length(password))) = 0xCB the
password is ok!
my passwords doesn't pass this check, infact: (0x0A + 0x34 + 9 * 0x09)
= 0x0A + 0x34 + 0x51 = 0x8F != 0xCB
and now? change the 'middle' char from "4" to: 0xCB - 0x051 - 0x0A =
so a valid password is: 123p56789
as before there are a lots of valid password...
ok, al = 1 and we can exit from the call. here we re:

00401435 pop ecx
00401436 test al, al ; if the password is = 1
00401438 jz short loc_401484 ; and no jump
0040143A cmp byte_40B1C0, 0 ; security mode enabled?
00401441 jz short loc_401484 ; yes, no jump
00401443 cmp byte_40B1C1, 0 ; pacman enabled?
0040144A jz short loc_401484 ; yes: no jump
0040144C push offset aFirewallEnable ; "FIREWALL ENABLED."
00401451 push 65h
00401453 push ebx
00401454 call j_SetDlgItemTextA
00401459 push offset aSecure_0 ; "SECURE !!!"
0040145E push 66h
00401460 push ebx
00401461 call j_SetDlgItemTextA
00401466 mov byte_40B1B9, 1 ; ATTENTION: 40B1B9 is 1
0040146D mov byte_40B1C2, 1 ; ATTENTION: 40B1C2 is 1
00401474 jmp short loc_401484

we are at the critical point of the crackme: where is the
congratulation box???
i've done all the task asked by the Professor Nitwit but...where i am
looking through the code i found something interesting:

00401E99 cmp byte_40B1C2, 0 ; if the byte pointed by 40B1C2 is 1
00401EA0 jz short loc_401EC4
00401EA2 cmp byte_40B1B9, 0 ; and the byte pointed by 40B1B9 is 0
00401EA9 jnz short loc_401EC4 ; the msgbox will appear
00401EAB mov byte_40B1B9, 1
00401EB2 push 0
00401EB4 push offset aWellDone ; "Well done!"
00401EB9 push offset aUSavedHumanity ; "U saved humanity"
00401EBE push ebx
00401EBF call j_MessageBoxA ; the congratulation box!!!!

the proggie has a bug! the byte pointed by 40B1C2 and 40B1B9 are never
1 and 0 in the same time,so you'll never reach the congratulation box:(
anyway, Detten has just released a new version without the instruction
in 401466; and now the messagebox appear;))))

the humanity has been saved!
that's all...


- Detten
i have never play with this type of crackme and i have appreciate it very much;)))
- my friends and you...