Info¶
Getting Started with Reverse Engineering on Pluralsight
Assembly Registers¶
64 bits | 32 bits | Lower 16 bits | Lower 8 bits | Upper 8 bits |
---|---|---|---|---|
RAX | EAX | AX | AL | AH |
RBX | EBX | BX | BL | BH |
RCX | ECX | CX | CL | CH |
RDX | EDX | DX | DL | CL |
RSI | ESI | SI | ||
RDI | RDI | DI | ||
RBP | RBP | BP | ||
RSP | ESP | SP | ||
R8-R15 | R8D | R8W | R8B |
EFLAGS & RFLAGS¶
- 32 and 64 bit registers that represent the resul of operations and the state of the CPU
- Common values include:
- Carry flag - CF
- Zero flag - ZF
- Sign flag - SF
- Trap flag - TF
- Direction flag - DF
- Overflow flag - OF
- The upper 32-bits of RGLAGS are reserved
Segment Purposes¶
.text/.code
: program instructions in binary state, entry point of program.data/.idata
: initialized data.rsrc
: resources used by the program - icons, images, arbitray binary data.bss
: uninitialized data
Math¶
A Note on Syntax¶
- There are syntactical differences between AT&T and Intel syntax - this can cause confusion with getting started with assembly
- AT&T prefixes registers with a
%
and immediate values with a$
- AT&T also changes direction of operands for many instructions: instruction source, destination
mov eax
,ebx
becomesmob %ebx, %eax
Size Directives¶
You will need to think in terms of size and not data types
- quad-word (qword): 8 bytes / 64 bits
- double-word (dword): 4 bytes / 32 bits
- word: 2 bytes / 16 bits
- bit: a single 1 or 0
You may encounter and need to use these directives in your instructions:
mov word ptr [eax], bx
Working with Memory¶
Often necessary to move data:
- between registers
- into and out of memory (heap and stack)
MOV instruction - mov dest, src:
mov <reg>, <reg>
mov <reg>, <mem>
mov <mem>, <reg>
mov <reg>, <const>
mov <const>, <reg>
Examples:
mov eax, ebx
mov dword ptr [ecx], 18h
Performing Comparisions¶
CMP instruction compares 2 values by performing substraction
- Second operand is substracted from first
cmp <reg>, <reg>
cmp <reg>, <mem>
cmp <mem>, <reg>
cmp <reg>, <con>
Results of the comparision updates the corresponding "flags" in the E/RFLAGS register
- Flags affected: CF, OF, SG, ZF; AF, PF
Control Flow with Jumps¶
Instruction | Description |
---|---|
JE / JZ | Jump Equal or Jump Zero |
JNE / JNZ | Jump Not Equal or Jump Not Zero |
JG / JNLE | Jump Greater or Jump Not Less/Equal |
JGE / JNL | Jump Greater/Equal or Jump Not Less |
JL / JNGE | Jump Less or Jump Not Greater/Equal |
JLE / JNG | Jump Less/Equal or Jump Not Greater |
Unconditional jumps don't check the flags register - transfers control to argument.
Conditional jumps allow for branching logic - checks the flags register to determine if it should take the jump.
Bitwise Operations¶
AND - multiplies each register bit by bit.
OR - the bit is 0 only if both bits are 0, otherwise the bit is 1.
XOR - the bit is 0 if both bits are 0 or both bits are 1. If one bit is 0 and the other is 1 then the bit will be 1.
NOT - flips each bit, 0 becomes 1 and 1 becomes 0.
Examples:
AX | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
BX | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | |
and ax, bx | |||||||||||||||||
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | ||
or ax, bx | |||||||||||||||||
1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | ||
xor ax, bx | |||||||||||||||||
1 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 |
Binary Math¶
Addition¶
0 | + | 0 | = | 0 |
0 | + | 1 | = | 1 |
1 | + | 0 | = | 1 |
1 | + | 1 | = | 10 |
Substraction¶
0 | - | 0 | = | 0 |
1 | - | 0 | = | 1 |
1 | - | 1 | = | 0 |
0 | - | 1 | = | 1 |
The last operation requires a borrow of one.
Multiplication¶
0 | x | 0 | = | 0 |
0 | x | 1 | = | 0 |
1 | x | 0 | = | 0 |
1 | x | 1 | = | 1 |
Division¶
10001 R10
101 / 1010111
-101
0
-101
01
-101
011
-101
0111
-101
Arithmethic¶
Many instructions require you to explicitly define the operands, such as:
Addition
- ADD DEST, SOURCE
Substraction
- SUB DEST, SOURCE
Examples:
AX | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
BX | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | |
add ax, bx | |||||||||||||||||
1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | ||
add al, bl | |||||||||||||||||
1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | |||||||||
sub al, bl | |||||||||||||||||
0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 |
Arithmethic - Multiplication¶
Operand Size | Source (implicit) | Source 2 (explicit) | Destination |
---|---|---|---|
Byte 8 bits | AL | 8 bit register or memory | AX |
Word 16 bit | AX | 16 bit register or memory | DX:AX |
Doubleword 32 bits | EAX | 32 bit register or memory | EDX:EAX |
Quadword 64 bits | RAX | 64 bit register or memory | RDX:RAX |
MUL
- Unsigned multiply
- Uses an implicit argument based on operand size
- Example: MUL BX
IMUL
- Signed multiply
- Uses one, two or three operands
- Allows you to explicitly define destination
- Example: IMUL DEST, SRC1, SRC2
Arithmethic - Division¶
Operand Size | Dividend | Remainder | Quotient |
---|---|---|---|
Byte 8 bits | AX | AH | AL |
Word 16 bit | DX:AX | DX | AX |
Doubleword 32 bits | EDX:EAX | EDX | EAX |
Quadword 64 bits | RDX:RAX | RDX | RAX |
DIV
- Unsigned divide
- Uses an implicit argument based on operand size
- Example: DIV AX
IDIV
- Signed divide
- Example: IDIV AX