What is x86 Disassembly?
Disassembly is the process of translating machine language (binary code) into assembly language. When a program is compiled, the human-readable source code is converted into machine code that the processor can execute directly. Disassembly reverses this process, converting the binary instructions back into human-readable assembly language.
The x86 architecture, developed by Intel, is one of the most widely used instruction set architectures in personal computers, servers, and workstations. Understanding x86 assembly is essential for reverse engineering, malware analysis, exploit development, and low-level debugging.
Use Cases: Disassembly is crucial for analyzing malware behavior, understanding proprietary software, finding vulnerabilities, debugging compiled code without source, and learning how programs work at the machine level.
x86 Architecture Basics
The x86 architecture uses a complex instruction set computing (CISC) design, meaning it has many specialized instructions that can perform complex operations. Understanding the fundamental components helps you read disassembled code effectively.
General Purpose Registers
x86 processors have several general-purpose registers used to store data, memory addresses, and intermediate calculation results:
Note: In 64-bit x86 (x86-64 or AMD64), these registers are extended to 64 bits and prefixed with 'R' instead of 'E' (RAX, RBX, etc.), and additional registers R8-R15 are available.
Common x86 Instructions
x86 assembly language consists of instructions that tell the processor what operations to perform. Here are some of the most common instruction categories:
Data Movement
MOV destination, source
Copies data from source to destination
mov eax, 0x42 ; Load value 0x42 into EAX register
PUSH source
Pushes a value onto the stack
push ebx ; Save EBX on the stack
POP destination
Pops a value from the stack
pop ebx ; Restore EBX from the stack
Arithmetic Operations
ADD destination, source
Adds source to destination
add eax, 5 ; Add 5 to EAX
SUB destination, source
Subtracts source from destination
sub ecx, edx ; Subtract EDX from ECX
INC destination
Increments destination by 1
inc eax ; Add 1 to EAX
DEC destination
Decrements destination by 1
dec ecx ; Subtract 1 from ECX
Control Flow
JMP address
Unconditional jump to address
jmp 0x401000 ; Jump to address 0x401000
CALL address
Call a function at address
call printf ; Call the printf function
RET
Return from function
ret ; Return to caller
CMP operand1, operand2
Compare two operands (sets flags)
cmp eax, 0 ; Compare EAX with 0
JE/JZ address
Jump if equal / zero
je 0x401020 ; Jump if previous comparison was equal
JNE/JNZ address
Jump if not equal / not zero
jne loop_start ; Jump if not equal
Logical Operations
AND destination, source
Bitwise AND operation
and eax, 0xFF ; Keep only lowest 8 bits
OR destination, source
Bitwise OR operation
or eax, ebx ; OR EAX with EBX
XOR destination, source
Bitwise XOR operation
xor eax, eax ; Common way to zero EAX
Using CyberChef's Disassemble x86
CyberChef's Disassemble x86 operation uses the Capstone disassembly framework to convert raw machine code bytes into readable assembly language. This is particularly useful when analyzing extracted shellcode, binary patches, or examining specific sections of compiled executables.
Basic Usage Steps:
- Obtain the raw machine code bytes (as hex, binary, or base64)
- Load the data into CyberChef's input pane
- If needed, convert your data format using "From Hex" or similar operations
- Add the "Disassemble x86" operation from the Code category
- Select the appropriate architecture (32-bit or 64-bit)
- View the disassembled assembly code in the output
Pro Tip: Chain operations like "From Hex" → "Disassemble x86" when working with hex dumps. If analyzing shellcode extracted from network traffic, you might use "From Base64" → "Disassemble x86".
Example: Simple Function Disassembly
Understanding Addressing Modes
x86 assembly uses various addressing modes to specify where data is located:
| Addressing Mode |
Syntax Example |
Description |
| Immediate |
mov eax, 5 |
Value is directly specified in the instruction |
| Register |
mov eax, ebx |
Value is in a register |
| Direct Memory |
mov eax, [0x401000] |
Value is at a specific memory address |
| Register Indirect |
mov eax, [ebx] |
Address is stored in a register |
| Indexed |
mov eax, [ebx + 4] |
Register plus constant offset |
| Base + Index |
mov eax, [ebx + ecx*4] |
Base register plus scaled index register |
Common Analysis Scenarios
1. Shellcode Analysis
When analyzing malware or exploit code, shellcode is often extracted as raw bytes. Disassembly reveals what the shellcode does: open a reverse shell, download a file, elevate privileges, etc.
2. Patch Analysis
Software updates and patches modify binary code. By disassembling the patched bytes, you can understand what vulnerability was fixed or what functionality was changed.
3. Malware Reverse Engineering
Malware analysis often involves disassembling suspicious executables to understand their behavior, identify indicators of compromise, and develop detection signatures.
4. Exploit Development
Understanding how vulnerable functions are implemented in assembly helps security researchers develop proof-of-concept exploits and understand attack vectors.
5. Binary Diffing
Comparing two versions of a binary by disassembling specific functions can reveal what changed between versions.
CyberChef Recipe Ideas
Here are some useful recipe combinations involving Disassemble x86:
- Hex to Assembly: From Hex → Disassemble x86 (32-bit)
- Base64 Shellcode: From Base64 → Disassemble x86 (64-bit)
- Extract & Disassemble: Extract Files → Regular Expression → From Hex → Disassemble x86
- Network Capture Analysis: From Base64 → Gunzip → Disassemble x86
- XOR Encoded Shellcode: XOR → Disassemble x86 (useful when shellcode is obfuscated)
x86 vs x86-64 (AMD64)
x86 (32-bit)
- 32-bit registers (EAX, EBX, etc.)
- 4 GB addressable memory
- Function arguments typically passed on stack
- 8 general-purpose registers
x86-64 (64-bit)
- 64-bit registers (RAX, RBX, etc.)
- Virtually unlimited addressable memory
- Function arguments in registers (fastcall)
- 16 general-purpose registers
Important: Make sure to select the correct architecture (32-bit or 64-bit) in CyberChef's Disassemble x86 operation. Using the wrong mode will produce incorrect or nonsensical disassembly.
Calling Conventions
Understanding how functions are called is crucial for reading disassembled code:
cdecl (C Declaration) - 32-bit
- Arguments pushed onto stack right-to-left
- Caller cleans up the stack
- Return value in EAX
stdcall (Standard Call) - 32-bit
- Arguments pushed onto stack right-to-left
- Callee cleans up the stack
- Used by Windows API functions
fastcall - x86-64
- First 4-6 arguments in registers (RCX, RDX, R8, R9 on Windows; RDI, RSI, RDX, RCX, R8, R9 on Linux)
- Additional arguments on stack
- More efficient than stack-based calling
Tips for Reading Disassembly
- Identify Function Boundaries: Look for prologue (push ebp, mov ebp esp) and epilogue (leave, ret) patterns
- Track Register Usage: Pay attention to which registers are used for what purpose
- Understand the Stack: Variables at [ebp-offset] are local variables
- Follow Control Flow: Identify loops (backward jumps) and conditionals (compare + conditional jump)
- Recognize Patterns: Common operations like zeroing registers (xor eax, eax) appear frequently
- Check Cross-References: Multiple calls to the same address indicate an important function
Limitations and Considerations
While CyberChef's disassembler is powerful, keep these limitations in mind:
- No Context: The disassembler only sees raw bytes, not symbols, function names, or comments
- Data vs Code: May incorrectly interpret data as code or vice versa
- Optimization: Compiler optimizations can make code harder to understand
- Obfuscation: Intentionally obfuscated code will be difficult to analyze
- Starting Point: Disassembling from the wrong offset produces nonsensical results
For Advanced Analysis: For comprehensive reverse engineering, consider dedicated tools like IDA Pro, Ghidra, radare2, or Binary Ninja which provide features like decompilation, graphing, and debugging.
← Back to Operations Guide