                      Tutorial for Duelist's Crackme #3
                              cracked by Nuno1
                        any comments are welcome to :
                             Nuno_2@hotmail.com


hey crackerz !
Duelist's Crackme #3 is a nice intersting crackme , i enjoyed crack it
(as mostly i enjoy cracking anything :) )

DueList's Crackme puzzle is a nice 18 checkboxs that we need to find out
witch one need to be ON and witch one need to be OFF . you can try to guess
them , trust me , you dont really want to start 18^18 trys ;)

as the readme file said . you can use a resource editor (or even you should
use one) , but in this crack i even didn't have to use it .. even that it
could help me a bit ;)

let start working !

1.first we want to see what the crackme offer us . so let start with a nice
  breakpoint .. i prefer using SoftIce but u can use what ever debugger you
  like.

  so we can break on a message for a Button click , but we can even get
  closer if we will break in the API call for checking the CheckBox.

  so if you dont know the function that do it , you are welcome to run
  a dissassembly and try to search for a good looking function that do it
  even that i am going to tell you ;) .

  the function called "isDlgButtonChecked" . this function called when trying
  to get infromation from a checkbox. it return on EAX 0 if FALSE , 1 if TRUE

  so let start rolling.

  do a "bpx isDlgButtonChecked" and press couple of F12 till you get to here :

:00401117 33F6                    xor esi, esi
:00401119 33D2                    xor edx, edx
:0040111B 89355E214000            mov dword ptr [0040215E], esi
:00401121 893562214000            mov dword ptr [00402162], esi
:00401127 0FBE8EFE204000          movsx ecx, byte ptr [esi+004020FE]
:0040112E 83F94D                  cmp ecx, 0000004D
:00401131 742F                    je 00401162
:00401133 890D5E214000            mov dword ptr [0040215E], ecx
:00401139 51                      push ecx
:0040113A FF7508                  push [ebp+08]
:0040113D E8D0010000              Call 00401312 --> this is the call to
                                                    isDlgButtonChecked
                                                    -- you will be here --.
:00401142 46                      inc esi
:00401143 83F800                  cmp eax, 00000000
:00401146 74DF                    je 00401127
:00401148 A15E214000              mov eax, dword ptr [0040215E]
:0040114D 0FBE8EFE204000          movsx ecx, byte ptr [esi+004020FE]
:00401154 0FAFC1                  imul eax, ecx
:00401157 0FAFC6                  imul eax, esi


  so we just break into .. let see now what this have to say to us :


xor esi, esi                       ;esi will be 0 here
xor edx, edx                       ;edx will be 0 here.
mov dword ptr [0040215E], esi      ;those vars will be 0 too . (esi=0)
mov dword ptr [00402162], esi

:00401127:  -- Jmp here --
movsx ecx, byte ptr [esi+004020FE] ;mmmm , look intersting till now
                                   ;moving to ecx somthing from esi+004020fe
                                   ;as it look like. it is a table .
                                   ;first esi=0 so it takes the 004020fe value

cmp ecx, 0000004D                  ;checking if ecx=4Dh ??? whats that ?
je 00401162                        ;if ecx is 4Dh we jmp to somewhere

mov dword ptr [0040215E], ecx      ;moving what we got to the var that we
                                   ;init in start.

push ecx                           ;pushing this value ?!?! what is it ?
push [ebp+08]                    
Call 00401312                      ;now this is the call to isDlgbuttonChecked!
                                   ;as we can guess the table above is the
                                   ;IDs for the checkboxs ..
                                   ;good ! now we got somthing new !
                                                
                                                
inc esi                            ;increase the esi (now will be 1)
cmp eax, 00000000                  ;as i told before isDlgButtionChecked
                                   ;return 0 if it is not checked.

je 00401127                        ;jmp if not checked

                                   ;here he will continue if checked.
mov eax, dword ptr [0040215E]      ;moving this strange number to EAX

movsx ecx, byte ptr [esi+004020FE] ;hey .. now we get the next number of
                                   ;the table (remember esi = 1 now)
                                   ;so does it the second checkbox ?
                                   ;we will try to find out.

                                        
imul eax, ecx                      ;he mul the first ID with the second ID ??
                                   ;its look like the ID's are more then an
                                   ;handle here !
                                   ;so eax=first ID * second ID at the first
                                   ;time.

imul eax, esi                      ;now he mul the result with esi ?
                                   ;is esi is a counter of somthing ?     
                                                                           
add dword ptr [00402162], eax      ;oh ! now he use the second var !
                                   ;now he add the result of all this to it.
jmp 00401127                       ;jmp back up!
                                   ;so we can see this is a loop!

//all here is after the loop end .. let see what now.


mov eax, dword ptr [00402162]      ;he take the result of the shit we done.
imul eax, 0000004D                 ;mul it with 004dh

cmp eax, 00F35466                 
                                
jne 00401191                       ;then if it is not equal to 00f35466
                                   ;he jump ! maybe this is the result
                                   ;it need to be ?
                                   ;so i guess we now on the "good guy code"
push 00002000
push 00402001
push 00402017
push 00000000
Call 004012DC
mov eax, 00000001
jmp 004010FA

----- Bad guy code ???? -----
:00401191

push 00002000
push 00402001
push 00402068


  ok . we done well .. now let see the things we have in mind :

    - the ID's of the checkboxs are used for calculation the code.
      it means that we have to get the table for us.

    - is the checkboxs are really goes one by one ? maybe they are not ?

    - does 00F35466h is the code that we need to get to ?
      we have to check the jmp there .. so let patch it.

      break again in 401162

:00401162
      mov eax, dword ptr [00402162]      
      imul eax, 0000004D                 
      cmp eax, 00F35466  ; stand here and do "r eax=00f35466"
                         ; now eax will be 00f35466
      jne 00401191 

      HA ! it is patched... so as the crackme rules .. no patching ! damn! ;)

      so we now know that f35466 is the result we need to get our calculation


  ok . lets go on the code once more with our expirince we got till now ;)


xor esi, esi                       ;we can believe now the esi will allways
                                    be up by one for each checkbox.
xor edx, edx                       
mov dword ptr [0040215E], esi      ;this contain the ID of the last checkbox.
mov dword ptr [00402162], esi      ;this will be our final result

:00401127:  -- Jmp here --
movsx ecx, byte ptr [esi+004020FE] ;004020FE is 99% a table.
                                   
                                   
                                   

cmp ecx, 0000004D                  ;what is this 4d ?? we soon look on the table
je 00401162                        ;we can see now that when we get into
                                   ;ID 4Dh it means that this is the last
                                   ;checkbox !

mov dword ptr [0040215E], ecx      ;get the ID of the checkbox.
                                   ;

push ecx                           ;ecx=ID of checkbox
push [ebp+08]                    
Call 00401312                      ;isDlgButtonChecked 
                                                
inc esi                            ;moving to the next checkbox.
cmp eax, 00000000                  ;checking if checkbox is on or off
                                   

je 00401127                        ;jmp if not checked

                                   ;here he will continue if checked.
mov eax, dword ptr [0040215E]      ;the last ID will be in eax.

movsx ecx, byte ptr [esi+004020FE] ;esi = next checkbox so ecx = ID of the
                                   ;new Checkbox.

                                        
imul eax, ecx                      ;mul the first checkbox with the second.

imul eax, esi                      ;mul the result with checkbox number.(not ID)
                                                                           
add dword ptr [00402162], eax      ;adding it to the total result !

jmp 00401127                       ;jmp back in the loop

//all here is after the loop end .. let see what now.

00401162:
mov eax, dword ptr [00402162]      ;he take the result of the shit we done.
imul eax, 0000004D                 ;mul it with 004dh

cmp eax, 00F35466                 
                                
jne 00401191                       ;then checking if it not equal to f35466
                                   ;if not . BAD GUY ! if equal GOOD GUY.
                                   

----Good Guy Code ----
                                   
push 00002000
push 00402001
push 00402017
push 00000000
Call 004012DC
mov eax, 00000001
jmp 004010FA

----- Bad guy code -----
:00401191

push 00002000
push 00402001
push 00402068


  so we got it ! we know what happend here but still .. what does it help us.

  let say in words what happend here :

  running on all checkboxs and mul the ID of the one of the checkboxs with
  the one that after him.
  after that mul the checkbox number with the result and add it to a variable
  that contain the total !.

  but now ... how the hell we get the number F35466 with this kind of algo..

  ok ! :) so let first see the table of the ID's.

  I used W32Dasm to get it .. u can use what ever tool you like .

  we know that the address of the table is 004020FE so i will dump it :

                              |this is 4020FE .. see for yourself ;).
                              __
  :004020F8 69 74 6F 72 21 00 16 49  itor!..I
  :00402100 5E 15 27 26 21 25 1D 59  ^.'&!%.Y
  :00402108 53 37 31 48 5D 0C 61 52  S71H].aR
  :00402110 4D 00 00 00 00 00 00 00  M.......
  :00402118 00 00 00 00 00 00 00 00  ........
  :00402120 00 00 00 00 00 00 00 00  ........
  :00402128 00 00 00 00 00 00 00 00  ........

  ok we can see that there are 19 numbers from FE that are not zero ..
  starnge because there are only 18 checkboxs.. but hey !! do you remember
  that 4D ???? so here it is !! when he find 4D he finish the loop .. and
  thats it absoultly 18 numbers ... 18 checkBoxs IDs !!

  ok .. but it still doesn't help us to find out the states of the checkboxs
  to crack this shit .

  so before really getting into it . we allready know what calculations are
  going on .. so we can write a little program that will use all the information
  and run on all the combinations .

  here is what i think :
    first writing a routine that will make the check (i mean check if its the
    right combination) and we can do it .. just write the routine we just debugged.
    second we have to write a little routine that will run on all the combinations
    and call the check routine until the check routine will return "FOUND" that
    can take time .. but it will work.... (7 min ;) )

  but as i said before how can we be sure that the ID's are really goes on
  the table as they are in the dialog !? lets check this out !


  run the crackme and turn ON the first checkbox ... now bpx on isdlgbuttonchecked
  press the "Check" button.

  ok . now we in isdlgbuttonchecked .. press F12 and we will be out ..
  let see the EAX .. is it 1 ? (ON) ... NO!! it's not !!! so they are not in
  the right order !!!! fuck ! more work to be done ;)

  press more F12 (remember ESI tell us the number of the checkbox we are on)
  when ESI=11h you will see that EAX=1 .. so the first one is really 11h ! (17)

  ok .. so write on paper that the 1 is really 17.

  now turn off the checkbox number 1 and turn on the checkbox number 2.
  
  do the same as above .. write 2 and ESI on the paper.. and do it to all of the
  other checkboxs (They are only 17 left to go :) ).. when finished you will
  have this table :

                           ---------------------
                           | Dialog | ID Table |
                           ---------------------
                           |    1   |    17    |
                           |    2   |     2    |
                           |    3   |     3    |
                           |    4   |     1    |
                           |    5   |     8    |
                           |    6   |     6    |
                           |    7   |     7    |
                           |    8   |    10    |
                           |    9   |    11    |
                           |   10   |     4    |
                           |   11   |    12    |
                           |   12   |    13    |
                           |   13   |    14    |
                           |   14   |    15    |
                           |   15   |    16    |
                           |   16   |    18    |
                           |   17   |    5     |
                           |   18   |    9     |

  so now we have another table .. translation table of the checkboxs.
  if we found that the 17 checkbox ID is need to be ON. it means that
  the first Dialog checkbox need to be ON .

  all left to be done is to write the search program and we finished.

  go and see the source code or just run the EXE it will show you what
  ever i did there..


  hope you got it ..

  thanks to Duelist's for a great crackme ! keep up the great work !


  have a nice cracking .. and dont forget to buy the programs you are cracking!



  Nuno1 - Nuno_2@hotmail.com
