Example 1
Jump to navigation
Jump to search
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:
- Copy all the assembly code to your IDE or somewhere safe.
- 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.
- Go through each line, and convert it to the equivalent C code (or Java, if you're more comfortable with that).
- 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