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,ebxbecomesmob %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