Difference between revisions of "Example 1"

From SkullSecurity
Jump to navigation Jump to search
Line 1: Line 1:
{{Infobox assembly}}
{{Infobox assembly}}
[[Category: Assembly Examples]]


Welcome to the first example assembly1 If you've read and understood all the sections up to here, there won't be any surprises here.  
Welcome to the first example assembly1 If you've read and understood all the sections up to here, there won't be any surprises here.  
Line 11: Line 12:
I'll go through those steps here, to hopefully give you an idea of how to approach a function like this. I highly recommend you try it yourself first, though.  
I'll go through those steps here, to hopefully give you an idea of how to approach a function like this. I highly recommend you try it yourself first, though.  


== Code ==
<pre>
<pre>
   ; Note: ecx is a pointer to a 13-digit Starcraft cdkey
   ; Note: ecx is a pointer to a 13-digit Starcraft cdkey
Line 44: Line 46:
</pre>
</pre>


[[Category: Assembly Examples]]
== Annotated Code ==
Please, try this yourself first!
 
I've been over this code a dozen times, so I know it very well. I've tried to annotate it as clearly as possible.
 
<pre>
  ; Note: ecx is a pointer to a 13-digit Starcraft cdkey
  ; This is a function that returns 1 if it's a valid key, or 0 if it's invalid
  mov    eax, 3    ; Set eax to 3
  mov    esi, ecx  ; Move the cdkey pointer to esi. It'll likely stay there, since esi is non-volatile
  xor    ecx, ecx  ; Clear ecx. Since a loop is coming up, this might be a loop counter
Top:
  movsx  edx, byte ptr [ecx+esi] ; ecx is a loop counter, and esi is the cdkey. This takes the ecx'th .
                                  ; character (dereferenced, because of the square brackets [ ]) and moves
                                  ; it into ecx. Since it's a character array (string), there is no multiplier
                                  ; for the array index.
 
  sub    edx, 30h                ; Subtract 0x30 from the character. This converts the ascii character '0',
                                  ; '1', '2', etc. to the integer 0, 1, 2, etc.
  lea    edi, [eax+eax]         ; Double eax. This is likely an accumulator, which stores a result.
  xor    edx, edi                ; Xor the current digit by the current checksum.
  add    eax, edx                ; Add the value in eax back into the checksum.
  inc    ecx                    ; Increment the loop counter, ecx.
  cmp    ecx, 0Ch                ; Compare the loop counter to 0x0c, or 12.
  jl      short Top              ; Go back to the top until the 12th character (note that the last character
                                  ; is skipped
 
  xor    edx, edx                ; Clear edx
  mov    ecx, 0Ah                ; Set edx to 0x0a (10)
  div    ecx                    ; Remember division? edx is cleared above, so this basically does eax / ecx
                                  ; We don't know yet whether it will use the quotient (eax) or remainder (edx)
 
  movsx  eax, byte ptr [esi+0Ch] ; Move the last character in the cdkey to eax. Note that this used move with
                                  ; sign extension, which means the character is signed. Because it's an ascii
                                  ; number (between 0x30 and 0x39), it'll never be negative so this doesn't
                                  ; matter.
  add    edx, 30h                ; Convert edx (which is the remainder from the division -- the checksum % 10)
                                  ; back to an ascii character. From the integer 0, 1, 2, etc. to the characters
                                  ; '0', '1', '2', etc.
 
  cmp    eax, edx                ; Compare the last digit of the cdkey to the checksum result.
  jnz    bottom                  ; If they aren't equal, jump to the bottom, which returns 0
 
  mov    eax, 1                  ; Return 1
  ret
 
bottom:
  xor    eax, eax                ; Clear eax, and return 0
  ret
</pre>
 
== C Code ==
 
== Cleaned up C Code ==
 
== Reduced C Code ==

Revision as of 01:24, 13 March 2007

Assembly Language Tutorial
Please choose a tutorial page:

Welcome to the first example assembly1 If you've read and understood all the sections up to here, there won't be any surprises here.

That way you should approach this is to to do the following:

  1. Copy all the assembly code to your IDE or somewhere safe.
  2. Go through each line, and make a note of what it does (typically, by putting a ; at the end and adding a comment works well). Try and understand what the code is doing.
  3. Go through each line, and convert it to the equivalent C code (or Java, if you're more comfortable with that).
  4. Try and combine and reduce the code to make it as simple as possible.

I'll go through those steps here, to hopefully give you an idea of how to approach a function like this. I highly recommend you try it yourself first, though.

Code

   ; Note: ecx is a pointer to a 13-digit Starcraft cdkey
   ; This is a function that returns 1 if it's a valid key, or 0 if it's invalid
   mov     eax, 3
   mov     esi, ecx
   xor     ecx, ecx
 Top:
   movsx   edx, byte ptr [ecx+esi]
   sub     edx, 30h
   lea     edi, [eax+eax]
   xor     edx, edi
   add     eax, edx
   inc     ecx
   cmp     ecx, 0Ch
   jl      short Top

   xor     edx, edx
   mov     ecx, 0Ah
   div     ecx

   movsx   eax, byte ptr [esi+0Ch]
   add     edx, 30h
   cmp     eax, edx
   jnz     bottom

   mov     eax, 1
   ret

 bottom:
   xor     eax, eax
   ret

Annotated Code

Please, try this yourself first!

I've been over this code a dozen times, so I know it very well. I've tried to annotate it as clearly as possible.

   ; Note: ecx is a pointer to a 13-digit Starcraft cdkey
   ; This is a function that returns 1 if it's a valid key, or 0 if it's invalid
   mov     eax, 3    ; Set eax to 3
   mov     esi, ecx  ; Move the cdkey pointer to esi. It'll likely stay there, since esi is non-volatile
   xor     ecx, ecx  ; Clear ecx. Since a loop is coming up, this might be a loop counter
 Top:
   movsx   edx, byte ptr [ecx+esi] ; ecx is a loop counter, and esi is the cdkey. This takes the ecx'th .
                                   ; character (dereferenced, because of the square brackets [ ]) and moves
                                   ; it into ecx. Since it's a character array (string), there is no multiplier
                                   ; for the array index. 

   sub     edx, 30h                ; Subtract 0x30 from the character. This converts the ascii character '0', 
                                   ; '1', '2', etc. to the integer 0, 1, 2, etc.
   lea     edi, [eax+eax]          ; Double eax. This is likely an accumulator, which stores a result. 
   xor     edx, edi                ; Xor the current digit by the current checksum.
   add     eax, edx                ; Add the value in eax back into the checksum.
   inc     ecx                     ; Increment the loop counter, ecx.
   cmp     ecx, 0Ch                ; Compare the loop counter to 0x0c, or 12. 
   jl      short Top               ; Go back to the top until the 12th character (note that the last character
                                   ; is skipped

   xor     edx, edx                ; Clear edx
   mov     ecx, 0Ah                ; Set edx to 0x0a (10)
   div     ecx                     ; Remember division? edx is cleared above, so this basically does eax / ecx
                                   ; We don't know yet whether it will use the quotient (eax) or remainder (edx)

   movsx   eax, byte ptr [esi+0Ch] ; Move the last character in the cdkey to eax. Note that this used move with 
                                   ; sign extension, which means the character is signed. Because it's an ascii 
                                   ; number (between 0x30 and 0x39), it'll never be negative so this doesn't
                                   ; matter. 
   add     edx, 30h                ; Convert edx (which is the remainder from the division -- the checksum % 10)
                                   ; back to an ascii character. From the integer 0, 1, 2, etc. to the characters
                                   ; '0', '1', '2', etc.

   cmp     eax, edx                ; Compare the last digit of the cdkey to the checksum result. 
   jnz     bottom                  ; If they aren't equal, jump to the bottom, which returns 0

   mov     eax, 1                  ; Return 1
   ret

 bottom:
   xor     eax, eax                ; Clear eax, and return 0
   ret

C Code

Cleaned up C Code

Reduced C Code