Registers

Each CPU core has a set of registers, being the fastest component in any computer. There are two types of registers

  • Data registers for storing instructions/syscall arguments (rax, rbx, rcx, rdx, etc.).
  • Pointer registers used to store specifc important address pointers. The main pointer registers are the base stack pointer rbp which points to the beginning of the Stack, the Current Stack Pointer rsp , which points to the current location within the Stack. and the instruction pointer rip, which holds the address of the next instruction.

Sub-Registers

Each 64-bit register can be further divided into a smaller sub-registers containing the lower bits, at one byte 8-bits, 2 bytes and 4 bytes. Each sub-register can be used and accessed on its own, so we don’t have to consume the full 64 bites if we have a smaller amount of data.

Sub-registers can be accessed as:

Size in bitsSize in bytesNameExample
16-bit2 bytesthe base nameax
8-bit1 bytesbase name and/or ends with lal
32-bit4 bytesbase name + starts with the e prefixeax
64-bit8 bytesbase name + starts with the r prefixrax

Memory Addresses

x86 64-bit processors ahve 64-bit wide addresses. However, RAM is segmented into various regions, like the Stack, heap, etc. Each memory region has specific read, write, execute permissions that specify wheter we can read from it, write to it, or call an address to it. Whenever an instructions goes through the Instruction Cycle, the first step is to fetch the instruction from the address it’s located at. In the x86 there are

Addressing ModeDescriptionExample
ImmediateThe value is given within the instructionadd 2
RegisterThe register name that holds the value is given in the instructionadd rax
DirectThe direct full address is given in the instructioncall 0xffffffffaa8a25ff
IndirectA reference pointer is given in the instructioncall 0x44d000 or call [rax]
StackAddress is on top of the stackadd rsp

Endinanness

Order of its bytes in which they are stored or retrieved from memory.

  • Little-endian, the little-end bytes of the address is filled first so right-to-left
  • Big-endian processors, the big-end byte is filled/retrieved first left-to-right.

Little-endian byte order is used in with Intel/AMD x86 in most OSes, so the shellcode is always represented right-to-left.

Data Type

x86 supportsmany types of data sizes.

ComponentLengthExample
byte8 bits0xab
word16 bits - 2 bytes0xabcd
double word (dword)32 bits - 4 bytes0xabcdef12
quad word (qword)64 bits - 8 bytes0xabcdef1234567890
Whenever we use a variable with a certain data type both operands should be of the same size.