TORN@DO presents: cRACKER's n0TES
Assembly for Crackers (CoRN2)


AND
Usage: AND dest,src
Purpose: Performs a logical AND of the two inputs, replacing the dest with the result
Example: AND BX,03h

There's not very much that can be said about this call, it does what it says.




CALL
Usage: CALL address
Purpose: Executes a function at the address 'address'
Example: CALL 10284312

Calls the function at address 'address', once the function has finished, the code will continue the line after the call.




CMP
Usage: CMP dest,scr
Purpose: Subtracts src from dest and updates the flags.
Example: CMP AX,03h

This is an important instruction as far as we (crackers) are concerned :). Somewhere in the program for it to verify something, ie. to compare the real serial to the one we enter, or to check if a program is registered etc.

This instruction usually preceeds a jump instruction of some kind.




Flags
Flags are essentially like registers except that they can only be true or false (ie 0 or 1). These are set by commands such as CMP, and are used to check the outcome of such a call, ie:

     CMP AX, BX          ; Compare AX to BX, if equal the zero flag is set to 1
     JZ  00124531        ; If the zero flag is set, jump to 001254531


To understand this properly, you'll probably have to read on and then come back ...




INT
Usage: INT interrupt_number
Purpose: Calls a default function (usually coded in the BIOS)
Example: INT 10h

You won't really see this command much (if at all) when debugging windows programs, but they turn up all over the place in DOS. Usually the parameters are passed in the default registers (AX, BX, CX etc.).

There are far too many INT calls to list here, better to get a copy of an interrupt list. Ralph Browns is very good! :)




JMP
Usage: JMP address
Purpose: Equivalent to a basic GOTO, jumps to a section of code
Example: JMP 00402011

JMP is an unconditional jump to a section of code. As simple as that! :)
There are tons of variations on this instruction, the most important ones are:


     JZ     Jump if zero flag is set       (same as  JE)
     JNZ    Jump if zero flag is not set   (same as JNE)

These usually follow a CMP instruction, ie:

     CMP    RealSerial,BadSerial           ; Compare the real serial to our serial
     JNE    GoAwayBadCracker               ; If Not Equal then exit.




LODSB / LODSW (Cruehead)
Usage: LODSB / LODSW
Purpose: Loads either a byte or a word from DS:SI and puts it in AL (LODSB) or AX (LODSW). Increments SI
Example: LODSW

Lets say that DS:SI points to a word which holds the value of EBh

     LODSW      ; Copies the word that DS:SI points to and places it in AX

AX will now contain the value of EBh



These instructions are often used together with the REP instruction.




MOV
Usage: MOV dest,src
Purpose: Copies byte or word value from the source to the destination
Example: MOV AX,DX

You will see this a *lot* when you're stepping through code, it basically means (to use BASIC terms ;))
LET dest = src

There are quite a few variants including MOVSX, but they all basically do the same thing. It might help to get the Intel Programming Specifications from their website.

If you can't understand this one, you're screwed! ;)




MOVSB / MOVSW (Cruehead)
Usage: MOVSB / MOVSW
Purpose: Moves (well, copies really) either a byte (MOVSB) or a word (MOVSW) from DS:SI to ES:DI. Increments SI
Example: MOVSB

Lets say that DS:SI points to a byte which holds the value of 5h

     MOVSB      ; Takes the byte that DS:SI points to and places it in ES:DI

The byte that ES:DI points to now has the value of 5h



This instruction is very common in cracking, when a string is copied to another location. The instructions are then used together with the REP instruction.




Registers
Registers are basically default places in which to store data. The only ones we need to worry abot are:
(E)AX, (E)BX, E(CX), E(DX)    (The (E) is only significant when debugging 32-Bit-Code).

Also the register pairs:

     DS:SI      ; Can be used as the source for string operations
     ES:DI      ; Used as the target for string operations

To understand registers isn't very important for cracking, generally just to know that they're variables for data storage is enough to get you started :)




REP
Usage: REP
Purpose: Repeat an instruction for the number of times specified in the CX register. A REP infront of a MOVSB, LODSB or STOSB (or infront of the word versions of these instructions) would cause that instruction to repeat itself.
Example: MOV AL,Bh    ; AL now contains bh
MOV CX,5h    ; CX now contains 5h
REP STOSB    ; Copy value of AL (5h) into whatever DS:SI points to 5 times and increment SI for every time




RET
Usage: RET
Purpose: To return from a function
Example: RET

You will usually see this at the end of a function, and it simply instructs the processor to RETurn to the address of the CALL to the function.




STOSB / STOSW (Cruehead)
Usage: STOSB / STOSW
Purpose: Takes the value in AL (STOSB) or AX (STOSW) and places it in DS:SI. Increments SI.
Example: STOSB

Lets say that AX holds the value of EBh

     STOSB

Copies the value in AX and places it in the word that DS:SI points to. DS:SI now points to a word containing EBh


The instructions are then used together with the REP instruction.




The Stack & Push/Pop
Before any function call, a program must 'push' any parameters that the function expects onto the stack. Think of it as a stack of plates, the first plate on the stack is the last one to be taken off - the stack is exactly the same. It's important to remember this 'first on/last off' principal when looking at a CALL, as this means that the parameters will be passed in reverse order ...

In case my babbling has confused you, lets look at this example:

The Windows API function GetDlgItemText requires the following parameters:


(1) Handle of dialog box
(2) Identifier of control
(3) Address of buffer for text
(4) Maximum size of string

Therefore these could be passed like so:

     MOV EDI,[ESP+00000220]     ; Get Handle of dialog box in EDI
     PUSH 00000100              ; PUSH (4) Max size of string
     PUSH 00406130              ; PUSH (3) Address of buffer for text
     PUSH 00000405              ; PUSH (2) Identifier of control
     PUSH EDI                   ; PUSH (1) Handle of dialog box
     CALL GetWindowText         ; CALL the function

Easy eh? This can be one of the simplest ways of cracking a serial number app, if you know the address of the buffer for the serial number, in this case 00406130, just breakpoint it, and you'll usually end up in or around the procedure that generates the real serial!! :)

POP is simply used to remove the first item from the stack, there are usually a lot of them before a function returns to the program ...


The cRACKER's n0tES are divided into 10 main parts:
 00. INDEX
 01. Assembly for Crackers (CoRN2)
 02. SoftICE (Boot Menu, Setup, Commands)
 03. Breakpoints & Win API Details
 04. Jump Instructions
 05. SET Instructions
 06. Tips & Tricks for Cracking
 07. Window Messages For Crackers
 08. Identifying Functions, Arguments, and Variables (Rhayader)
 09. Commercial Protection Systems
 10. Bitmanipulation (Cruehead)
 11. General Cracking Theory
 12. FAQ

 +A. How to contact me
 +B. What's New?



The cRACKER's n0TES are Copyright © 1998-2000 by TORN@DO of ID. All Rights Reserved.