Getting Started for Reverse Engineering 102
Basics of x86 Architecture for Reversing -2
Prerequisites:-
Getting Started for Reverse Engineering 101
Instruction Set
Instruction set in x86 are all the instruction mnemonic code which the x86 Architecture supports all the instructions are single line the instruction laid can perform operation such as data movement, arithmetic and logic, etc. We will focus on some of the core instructions from x86 which you probably will come across frequently.
Get Anoni’s stories in your inbox
Join Medium for free to get updates from this writer.
Please recall syntax previously on how a complete instruction looks like:-
Arithmetic Instruction
This instruction carry out arithmetic operation such as Multiplication, Addition, Division, etc.
- add :- The add mnemonic additions between one, two or three operands. It adds source operand to the destination operand and stores result in destination. For one operand it adds the operand to accumulator EAX and stores result in accumulator. When three operands addition result is finally stored in destination.
Ex:-
1. add EBX, 5ch
Adds hex 5c(Decimal 92) to the content stored in EBX register and result is stored in EBX only.
2. add EDX, EBX
Adds value stored in EBX to EDX and result is stored in EDX(EBX+EDX).
3. add ESI, EBX, ECX
Adds values stored in ECX to EBX the result of this addition is then added to ESI and the final result is stored in ESI. (ESI = ESI + EBX + ECX). - sub :- The sub mnemonic subtracts the source operand from destination operand and result is stored in destination.
Ex:-
1. sub EBX, 5ch
Subtracts hex 5c from EBX and stores result in EBX register.
2. sub EAX, EDX
Subtracts value of EDX from EAX and result is stored in eax. - mul :- The mul mnemonic only takes one operand and multiplies that operand with the EAX and result is stored in EDX:EAX, because multiplication of n bit number with n bit number can result in 2n bit output. The upper half of the result is stored in EDX and lower half in EAX.
Note:- not every time extra register(EDX) is used, for 16 bit, result is stored in EAX..
Ex:-
1. mul 04h
Multiplies 0x4(hex can be written with prefix 0x or suffix h) with the value stored in EAX and the result is stored in EDX:EAX.
2. mul EBX
Multiplies value stored in EBX with value stored in EAX and result is stored in EDX:EAX. - div :- The div mnemonic divides is used for division this to uses implicit addressing(Some instruction don’t require us to address where to store and to take from these instruction by design know where to goto) only one operand is needed that is the divisor and the dividend is to be at EDX:EAX and the result which is quotient and remainder are stored at EAX:EDX.
Ex:-
1. div 05h
Divides the value stored in EDX:EAX with 5h and quotient is in EAX and remainder is in EDX. Consider EDX:EAX is fh now f in decimal is 15 and 5h is 5 so 15 divided by 5 yields quotient as 3 and remainder as 0, so 3 will be in EAX and 0 in EDX.
Data Movement
This instruction are used for moving data between, register, memory and I/O.
- mov :- This instruction is used to move data between register and memory location. This is the most common instruction which we will see all the time, data is transferred from source to destination operand. mov instruction only copies the values hence values stores in source remains as it is.
Ex:-
1. mov EBX, 20h
Moves 20h into EBX Register.
2.mov EDX, [EBP+1Bh]
Moves the data pointed by the address stored in EBP + 1Bh into ESI.
We haven’t discussed addressing modes in x86 so this syntax will look new its easy to understand though this square brackets represent ‘the address pointed by’ just like pointers in C/C++. So in above example what will happen is whatever value is stored in EBP that and we add 1Bh to it and this final value is an address where we need to go and on that address there will be some value that we shall copy into the ESI.
3.mov [ESI], EBX
This will copy value of EBX into the memory location pointed by ESI. - xchg :- This instruction is used for swapping the values between two operands. The exchange cannot be between memory and memory it can be between register and memory or only register and register.
Ex:-
1. xchg ESI, DSI
This swaps the the value of DSI with the value of ESI.
2. xchg [ESP + 04h], EAX
This swaps the value of EAX with the memory location pointed by ESP+04h. - push :- It pushes the operand to the top of the current stack frame pointed by re-calculated ESP. Consider it as copying whatever operand was supplied to the memory location pointed by ESP which got re-calculated just before copying. But this memory location is a little special, we will learn more about stack in detail also about the memory pointer calculation of ESP at later stages, just the intro on previous blog was enough.
Ex:-
1. push EAX
Pushes(Copy) the value of EAX to the top of the stack. - pop :- pop is used to take value out from the stack. The value stored at the top of the stack frame gets copied to the specified operand location and the stack pointer gets calculated again to point to the next location which will become now current stack pointer.
Ex:-
1.pop EDX
Copy the top element from stack to EDX, recalculates stack pointer for next value.
Logical and Shift Instructions
These type of instructions perform operations on bits of data hence bitwise operations such as rotate, shift and logical operations.
- and :- It performs bitwise AND between source and destination operand.
Ex:-
1. and EAX, EBX
Does bitwise AND between EBX and EAX and result is stored in EAX.
If EAX is 1010 and EBX 1100 then result is 1000 stored in EAX. - or :- Does bitwise OR between source and destination.
Ex:-
1. or EBX, EDX
Performs bitwise OR between EBX and EDX result stored in EBX.
If EBX is 1010 and EDX is 1100 result is 1110 stored in EBX. - xor :- Does bitwise exclusive or between source and destination operand.
Ex:-
1. xor EDX,ECX
Calculates exclusive OR between source and destination operand.
If EDX is 1010 and ECX 1100 then result 0100 stored in EDX. - not :- Negation of bits, flipping a bit of specified operand(Compliment).
Ex:-
1. not EAX
One’s Complement on EAX. If EAX is 1010 result is 0101 - rol :- Rotate left instruction rotates the bit towards left side; bit at LSB position shifts towards the immediate left bit and so on and the MSB bit is rotated and brought to the LSB position.
Ex:-
1. rol EAX
Rotate left all bits of EAX.
If EAX is 1010 then result is 0101 stored in EAX.
Note:- We can define the number of bits to rotate for all rotate instruction in CL(ECX → CX → CL)register. - rcl :- Rotate left through carry is same as rol but the carry flag is included in rotation so now the carry flag is rotated to the LSB and MSB is rotated towards the carry flag.
Ex:-
1. rcl EAX
Rotate EAX left include the carry flag.
If EAX is 1010 and CF is 0 then result is 0100 and CF is 1. - ror :- Rotate right instruction rotates the bits towards right side; bit at LSB shift towards the carry flag and the carry flag bit shift towards the MSB.
Ex:-
1. ror EAX
Rotate EAX to the right.
If EAX is 1010 then result is 0101 stored in EAX. - rcr :- Rotate right through carry rotates the bit towards right and also includes the carry flag so carry flag moves towards the MSB and the LSB is rotated to CF.
Ex:-
1. rcr EAX
Rotate EAX right also include CF(Carry Flag) in rotation.
If EAX is 1010 and CF is 1then result is 1101 and CF is 0. - shl :- Shift left is a logical operation in which the bits shift to the left and MSB is shifted to the carry flag and in place of LSB a zero is introduced.
Ex:- shl <destination>, <count>
1. shl EAX , 1
Shift the EAX bit towards the left into carry flag and introduce 0 at LSB thus performing a logical left shift by 1.
If EAX is 1011 and CF is 0 then result is 0110 and CF is 1. - shr :- Logical right shift the specified operand, the lsb bit is carried to the carry flag and a zero is introduced from the MSB.
Ex:- shr <destination>, <count>
1. shr EAX, 1
Shifts the EAX bits to the right while introducing zero from msb and LSB into carry flag,.
If EAX is 1010 and CF is 1 then result is 0101 and CF is 0. - sal :- Shift arithmetic left, its exactly same as shl.
- sar :- Shift arithmetic right is an arithmetic shift as called in which the MSB bit is never shifted its retained and the right shift is done with preserving the signed bit stored at MSB, its used for signed division by powers of 2. The LSB bit moves into the carry flag.
Ex:- sar <destination>, <count>
1. sar EAX, 1
Right shift the bits of EAX while preserving the MSB; LSB into CF.
If EAX is 1010 and CF is 1 then result is 1001 and CF is 0.
String Instructions
This set of instructions are specifically defined for string handling such as load, moves and compare, etc. This instructions use their default ESI as source index and EDI as destination index for a string operation, and this utilize ECX for repeating instructions n times as ECX acts as counter and DF flag which tells the direction to follow(forward or backward).
- movs :- This is used to copy a data element it can be a byte, word, double-word from memory location pointed by ESI to the location pointed by EDI. Also ESI and EDI gets changed according to DF(Direction Flag).
Ex:-
1. movsb
Copies a byte from memory location at ESI to memory location at EDI.
Increment ESI and EDI by 1.
2. movsw
Similarly for word(16 bits) and ESI, EDI incremented by 2.
3. movsd
For double word; ESI , EDI increment by 4.
I'm assuming direction flag is not set(DF = 0) hence its incrementing. - lods :- Load string instruction used to load string at memory location pointed by ESI either into AL, AX, or EAX.
Ex:-
1. lodsb
For loading(copying) a byte from ESI pointed memory into AL.ESI= +/-1.
2. lodsw
Similarly but for a word into AX. ESI = +/- 2.
3. lodsd
Similarly for double word into EAX. ESI = +/- 4
ESI will get incremented accordingly. - stos :- Store string for storing back from AL,AX, or EAX back into the location pointed by EDI.
Ex:-
1. stosb
Copy byte from AL to memory pointed by EDI. EDI = +/- 1.
2. stosw
Copy from AX into memory pointed by EDI. EDI = +/- 2.
3.stosd
For double word from EAX. EDI = +/- 4. - rep :- This instruction is used to repeat the string instruction say n times and how many times to repeat is stored in ECX. This instruction is added as prefix for the specific instruction to repeat.
Ex:-
1. rep movsb
Will move a byte from memory location pointed by ESI to EDI repeating same n times and value of n is in ECX as soon as ECX becomes zero repetition stops. - cmps :- Compares the value at memory location pointed by ESI and EDI and updates the flag according to the result.
Ex:-
1. cmpsb
For byte comparison.
2. cmpsw
For word comparison.
3. cmpsd
For double word comparison. - scas :- Scan string also does the comparison but between AL,AX or EAX and the memory location pointed by EDI. Flags are updated according to result.
Ex:-
1. scasb
For scanning byte, and similarly for others.
Flag Manipulation Instructions
These instructions are used to set the values of flag which can be set by a programmer.
- clc :- Clear Carry is an instruction which will set the Carry Flag(CF) to 0.
- stc :- Sets Carry Flag(CF) to 1.
- cmc :- Complements the Carry Flag(CF).
- cld :- Clears the Direction Flag(DF); DF = 0.
- std :- Sets the Direction Flag becomes 1, backward direction.
- cli :- Clears the Interrupt Flag(IF) .
- sti :- Sets the Interrupt Flag(IF) to 1.
- lahf :- Loads flags value in to AH register.
- sahf :- Stores to flag from AH register.
- pushfd :- Pushes the flags to stack.
- popfd :- pops the flag from stack and stores back to the flag register.
Control Transfer Instructions
These set of instructions are used to control the flow of the program we can make decisions using this instructions as well as can branch out, loop through code, etc. Like jump to some other part of code or invoke a function, etc.
- jmp :- This is an unconditional jump instruction in which the program will jump to the specified instruction at that address.
Ex.
1. jmp 0x0000a64f
This instruction will transfer the execution of program to the instruction stored at above address and program will begin executinf from that instruction from now on. - j<cc> :- Jump conditionally based on a condition, condition is defined by <cc> which will be something like JZ jump if Zero or JNC jump if not carry.
- call :- This instruction is used to call a procedure, while doing so the current EIP is pushed to stack to preserve after returning from procedure and the program execution is transferred to that procedure.
- ret :- To return from the procedure this is used, it pops the EIP stored in stack and passes control to that address. To think of this way if anything stored on stack top the control will be transferred to the instruction at that address.
- loop :- Used to repeat a block of instructions n times the n is stored in ECX , loops until ECX doesn’t become zero.
- int :- Used to invoke an interrupt request with the specified code from IDT(Interrupt Descriptor Table) , interrupts have special meaning and are assigned priority and they do a particular work. The focus of CPU shifts to this interrupt and current flags, EIP(Instruction Pointer),etc are pushed to stack to restore after interrupt execution.
- iret :- Return from an Interrupt and restore the previous original state and continue normal execution. This involves restoring the flags and other values stored in stack previously to its position and continue.
Some instructions which are common but not listed in above categories are as follows:-
- lea :- Load Effective Address used to calculate the effective address of source operand and store it in destination operand.
- nop :- No instruction just pass. Does nothing.
- xlat :- Translate instruction which will translate a byte by looking up value in a table. Value from AL as index and table pointer can be EBX and now translate to EBX pointer + AL and store.
- cpuid :- Gets information about processor its identification and feature numbers into general purpose register.
These are very few set of common instructions which we will come across often there are so many instructions which can be found in official manual of intel and various google searches can lead you.





