Common Assembly Instructions
PUSH <value>
Puts value on top of the stack.
POP <register>
Gets data from the top of the stack and puts in of the stack and puts it in a register.
Example of PUSH and POP:
Code:
PUSH 0x01
PUSH 0X02
POP EAX
POP EDX
After these instructions are ran, EAX would be equal to 0x02 and EDX would be equal to 0x01 (LIFO).
TEST <value><value2>
Compares bitvalues in data often used TEST EAX,EAX in software to check if EAX is zero, example after a function that checks if the serial is correct
CMP <value1>,<value2>
Compares 2 numbers by subtracting the source from the destination and updates the flags.
Example:
MOV <to>,<from>
Moves data from one address to a another
Example:
CALL <address>
Calls (runs) a function. When you use the call instruction it pushes the return address onto the stack and then jumps to the function's address, and when the ret instruction is used it pops the address off of the stack and then jumps to that address. This knowledge is critical to understanding how stack overflows can be transformed into exploits. (thanks nosiop)
Example:
DEC <value>
Decreases a value by 1
Example:
WIll decrease EAX by 1
RET
Returns from a subroutine or function to the code after the call that called the function.
INC <value>
Increases a value by 1
Example:
WIll increase EAX by 1
SUB <value1>,<value2>
Subracts two values, then puts the result in value1
Example:
XOR <value1>,<value2>
exclusive or, most commonly used to quickly set a register to 0 or for simple encryption
Example:
will make EAX 0
ADD <value1>,<value2>
Adds two values, then puts the result in value1
Example:
Jump-instructions
Jumps are used to control the program-flow, they decide where in the programs we go, and in company of e.g. a CMP function the jump can decide weather the program is going to run code in one place or another.
This is compared to other languages like C/C++. They are like "if-cases" or "goto".
//C/C++
Code:
if(register == 0)
{
RegisterPleaseScreen();
}
There are many jump-instructions which are used for different things. Here is a short list of the most common used ones.
Code:
JMP <address> - Jump (always jumps)
JZ <address> - Jump if zero
JNZ <address - Jump if Not Zero
JE <address - Jump if Equal
JNE <address - Jump if not equal
JGE <address> - Jump if Greater or Equal
JBE <address> - Jump if Below or Equal
JA <address - Jump if Above
JAE <address> - Jump if Above or Equal to
The code below is a example code of a program checking the serial number the user inputs and seeing if it is the right one.
Example of a ASM-code with Jumps
Code:
0x0000001 CALL CheckRegistered //Check is user is registered
0x0000002 TEST EAX, EAX //Checks if EAX is eqal to 0
0x0000003 JZ 0x0000006 // if EAX is eqaual to 0 jump to Please register screen
0x0000004 CALL ShowThanksForPurchase // else show Thanksforpurchasescreen
0x0000005 JMP ContinueProgram // coutinues with normal program routinue
0x0000006 CALL PleaseRegisterScreen // calls please register screen
0x0000007 JMP 0x0000009 // jmps to ExitProgram
....
# Exit Routine
0x0000009 movl $1, %eax
0x0000010 movl $0, %ecx
0x0000011 int $0x80
This might look confusing even though will the comments.
The numbers on the left side (0x0000001 example) are address (these are all made up for this example of course) and on the right side are the Assembly instructions that are on the address.
While cracking software you quite often see code similar to this.
First the code calls a function which check if we are registered,
then EAX is test if it is 0.
If EAX is NOT 0 the program calls the "Thank you for purchase"-screen.
If EAX is 0 it jumps to 0x0000006 and there it calls the screen the says you need to register and jumps again to the end of the program.
Program Structure
Now you maybe wondering HOW THE FREAK DO I BUILD A ASSEMBLY PROGRAM? Well we need to know how to structure our program. When we structure the program it is like the stack highest to lowest. We need to structure that program like that stack.
The first part of our assembly program we declare we declare the ".data" part of are program where are used initialized data is held or in other words data we give a variable.
Example:
The second part of our assembly program is the ".bss" part of the program where put initialized data like buffers and other stuff.
Example:
The third and final part of an assembly program is the .text function where the the actual code is put.
Example:
The foruth part of the program is where we declare ".globl _start" this is needed to be (declared for linker (ld)).
Example:
Code:
.data
.bss
.text
.globl _start
The fifth part of our program is where we put the main part of the program. I like the main() function in C/C++ the equivalent to that in assembly is "_start:". (tell linker entry point).
Example:
Code:
.data
.bss
.text
.globl _start
_start:
//Code..
Data types
--------------------------
Now that you learned how to structure a assembly program now we need to learn about data types to use in our program. Now here we go.
Here is a list of data types:
Code:
.int 32 bit number
.ascii String
.asciz Null Terminated String
.short 16 bit number
.byte 1 bytes (32 bits)
.float = Single precision point number
.double = Double precision point number
Other data types for .bss (uninitialized data) are:
Code:
.comm = this declares common memory area. Like global variables.
.lcomm = this declares local memory area. Like local variables in functions.
To declare our data types in our program we do it like this:
Code:
dataname:
.datatype <value>
Here is another example with actual types for people who don't understand.
Code:
AroString:
.asciz "Aro Rules!\n"
For Uninitialized data .bss:
Code:
.lcomm <dataname>, <size>
Real world example:
Code:
.comm arobuffer, 1024
Now lets insert each data type we learned into our program structure we learned how to make before name your program "Lesson.s":
Code:
# by the way to comment in asm put a pound key before the comment
.data
AroString:
.ascii "You are going to learn assembly quickly and easily"
AroStringNull:
.asciz "Can you imagine you learning assembly with ease"
AroInt32:
.int 13
AroInt16:
.int 8
AroByte:
.byte 10
AroFloat:
.float 12.23
AroDouble:
.double 12.131
.bss
.comm AroBuffer,1024
.lcomm YourBuffer, 1024
.text
.globl _start
_start:
//code...
Finally its time to learn how to put assembly code in the .text function. Here we get down and dirty baby. Now in order to do this he need to learn sys calls.
I will teach you how to convert a Linux sys call into assembly. We will use the exit function. Here is the layout how the exit sys call:
Code:
int sys_exit(int status)
They way we pass arguments to syscalls is first we declare the EAX register for the System call number, EBX for the first argument, ECX for the two argument,
EDX for the third argument and for the fivith we use the EDI register. Then we end the $0x80 interrupt to show we are at the end of the function.
Now lets do this with the exit function.
First we need to find the sys call number here
"vim usr/include/asm/unistd_32.h"
The sys call number is 1. We will type it like this.
Second we will need to use the argument 0 to exit our program by moving the value 0 in the %ebx register.
Now we show that the sys call has ended with the $0x80 interrupt
Let put it in the program
Code:
.data
AroString:
.ascii "You are going to learn assembly quickly and easily"
AroStringNull:
.asciz "Can you imagine you learning assembly with ease"
AroInt32:
.int 13
AroInt16:
.int 8
AroByte:
.byte 10
AroFloat:
.float 12.23
AroDouble:
.double 12.131
.bss
.comm AroBuffer,1024
.lcomm YourBuffer, 1024
.text
.globl _start
_start:
#Exit Routine
movl $1, %eax
movl $0, %ecx
int $0x80
Code:
To compile the code in linux type:
as -ggstabs -o <programname.o> <programname.s>
ld -o <programname> <programname.o> // for linking
If you have windows use NASM (I dont know anything about so don't ask quesions) best is to just get a live CD or Vmware.
Now its your turn I taught you enough information to make a simple hello world program. Just follow the instructions I gave you.
To print a string you need the sys call write. Here is what it looks like:
Code:
ssize_t sys_write(unsigned int fd, const char * buf, size_t count)
That's all you get. Post you code when your done.