Tutorial on W32Dasm
 
Info

Hello, and welcome on the tutorial on W32Dasm. W32Dasm (or WDasm, this is shorter to type for me :) is a disassembler. A disassembler analyses exe-, dll, com-files (but also other types which I won't discuss here) and breaks it down into its assembly equivalent. So, this means that any exe-file can be disassembled into assembly? Well, yes and no... A file can be disassembled if it's not packed with a packer. If a file is packed, you can still load it into WDasm, but you won't be able to see the string-references and import tables.
The difference between WDasm and SoftIce is that you get a deadlisting in WDasm.
But, more about that in the tutorial!
I've written a little crackme in assembly (to have clean code :) which we will try to tackle with WDasm!
So, let's get started!

Tutorial
Fire up WDasm, and open the crackme. I'll try to make you understand the basic functions of WDasm while we try to crack the very easy crackme that I made.

Now you disassembled the crackme, you can see some buttons highlighted. To the right you can see the StringReferences (StrnRef). If you press this button, you can see all the strings that are used in a program. You can use these to trace quickly to the code where the password you entered is compared to the correct password. Or, if it is a very bad protected program, you can even find the correct password here!!
It is also possible that if you try to disassemble a program, that you find nothing in the string references. The reason for that will probably be because the program is packed.

Another interesting function of WDasm is the Import Table. If you press this button, you see the functions that are imported in the program you are disassembling. In this list you can find for example the GetDlgItemText api. Not in my crackme though. I use another api to read the text you entered. I used, GetWindowTextA as you can see in the list. Also in the list is lstrcmp. This is another api I call and it is used to compare two strings.
Now, this is interesting! Why would two strings be compared with each other? You already guessed it huh? To check if you entered the correct serial.

Now, if you double-click GetWindowText or lstrcmp, we go to almost the same place in the program (my crackme) as they happen right after each other. Also, if you double-click on "You entered the right serial" in the string references, we jump to the same spot in the assembly program. We see this:
   

:0040122C 6A1E push 0000001E ; push the parameters for the :0040122E 6837304000 push 00403037 ; GetWindowTextA-api :00401233 FF3504314000 push dword ptr [00403104] ; here too
* Reference To: USER32.GetWindowTextA, Ord:015Bh
         |
         :00401239 E8A2000000 Call 004012E0                   ; GetWindowTextA-call
* Possible StringData Ref from Data Obj ->"cannabis"          ; string
| :0040123E 6855304000 push 00403055 ; push string at address 403055 ("cannabis")
:00401243 6837304000 push 00403037 ; push string at address 403037 ("string you entered")
* Reference To: KERNEL32.lstrcmpA, Ord:02D6h
         |
         :00401248 E8E7000000 Call 00401334                   ; call the lstrcmpA-api
         :0040124D 0BC0 or eax, eax                           ; test if strings are equal
         :0040124F 7516 jne 00401267                          ; jmp if strings not equal
         :00401251 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Correct!"
         |
         :00401253 687E304000 push 0040307E                    ; push "Correct"-string = title of MessageBox
* Possible StringData Ref from Data Obj ->"You entered the right password!"
         |
         :00401258 685E304000 push 0040305E                    ; push "You entered..."-string = MessageBox text
         :0040125D FF7508 push [ebp+08]                        ; handle to owner of messagebox
* Reference To: USER32.MessageBoxA, Ord:01BBh
         |
         :00401260 E88D000000 Call 004012F2                    ; call MessageBox
         :00401265 EB21 jmp 00401288                           
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
         |:0040124F(C)
         |
         :00401267 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Nope!"               ; Title of bad guy message
         |
         :00401269 6887304000 push 00403087                     ; title pushed on stack
* Possible StringData Ref from Data Obj ->"Maybe, you should          try again, it's "
         ->"sooo easy!!"
         |
         :0040126E 688D304000 push 0040308D                     ; push "maybe, you should..."
         :00401273 FF7508 push [ebp+08]                         ; handle to owner of MessageBox
* Reference To: USER32.MessageBoxA, Ord:01BBh
         |
         :00401276 E877000000 Call 004012F2                     ; call MessageBox
         :0040127B 6A00 push 00000000
         :0040127D FF3504314000 push dword ptr [00403104]


Now, what happens in this piece of code? We first see that GetWindowTextA is called. I used this api in my crackme to read what you entered in the editbox. Then, 2 strings are pushed. This happens at address 0040123E and 004011243 ("cannabis and the string you entered are pushed).
Right after that, there is a reference to Kernel32.lstrcmpA. As I said before, this api is used to compare 2 strings.
If the return value of the api is 0, it means the 2 strings are equal. Else the 2 strings are not the same.

After the lstrcmp, there is a jump (at address 0040124F). It is a jump if not zero (jnz) and this means that, if the the string you entered and the correct password are not the same, you jump to the messagebox that says: Nope!

        

If you have any questions of if you see a mistake in this tutorial, mail me @ michiel_dg@hotmail.com