Reversing
My notes on cybersecurity topics.
Last updated: May 4th, 2023
Theory
Basics
Components of a CPU
- ALU (Arithmetic Logic Unit)
- Functions and arithmetic operations
- Control Unit (CU)
- Role in instruction execution
- Instruction cycle
- Registers
- General-purpose registers
- Segment registers
- Flags register
- Instruction pointer
Memory Hierarchy
Level | Type | Characteristics |
---|---|---|
Registers | Fastest | Smallest capacity, closest to the CPU |
Cache | Fast | Provides a bridge between registers and main memory |
Main Memory (RAM) | Slower | Stores program instructions and data |
Secondary Storage | Slowest | Long-term storage (e.g., hard drives, SSDs) |
Terminology
- Functions
- A function is a named sequence of instructions that performs a specific task.
- Process
- A process is an instance of a running program.
- It represents the execution environment for a program, including its memory space, resources, and execution state.
- Thread
- A thread is a unit of execution within a process.
- It represents a single sequence of instructions that can be scheduled and executed independently.
- Threads share the same memory space as the process and can communicate with each other.
- Stack
- The stack is a region of memory used for organizing function calls and managing local variables.
- It grows and shrinks dynamically as functions are called and return.
- Stack Frames
- A stack frame, also known as an activation record, is a data structure associated with each function call on the stack.
- It contains information such as the return address, function arguments, and local variables.
- Heaps
- The heap is a region of memory used for dynamic memory allocation.
- It is managed by the program and can be used to allocate and deallocate memory blocks at runtime.
- Handles
- Handles are unique identifiers used by an operating system to reference resources such as files, windows, or synchronization objects.
- Exceptions
- Exceptions are events that occur during program execution that disrupt the normal flow.
- They are often triggered by exceptional conditions such as errors or abnormal situations.
Registers(x86)
General-Purpose
Register | Description |
---|---|
EAX | Accumulator register used for arithmetic and logical operations |
EBX | Base register used for addressing data in memory |
ECX | Counter register often used in loop operations |
EDX | Data register used for arithmetic operations and I/O |
ESI | Source index register used for string operations and array access |
EDI | Destination index register used for string operations and array access |
ESP | Stack pointer register used for managing the stack |
EBP | Base pointer register used for accessing function parameters and local variables |
Segment
Segment registers are used in x86 architecture for memory segmentation. They include:
- CS (Code Segment): Points to the segment that contains the current instruction being executed
- DS (Data Segment): Points to the segment that contains data used by the program
- SS (Stack Segment): Points to the segment used for the stack
- ES (Extra Segment): Used as an additional data segment
- FS and GS (Additional Segments): Additional segment registers available in some x86 processors
Flags
Flag | Description |
---|---|
ZF | Zero Flag: Indicates whether the result of the previous operation was zero |
CF | Carry Flag: Indicates whether an arithmetic operation generated a carry or borrow |
OF | Overflow Flag: Indicates whether an arithmetic operation resulted in an overflow |
SF | Sign Flag: Indicates the sign of the result of an arithmetic or logical operation |
DF | Direction Flag: Controls the direction of string operations (forward or backward) |
Instruction Pointer
The Instruction Pointer (IP) or EIP (Extended Instruction Pointer) register stores the memory address of the next instruction to be executed.
Instructions
Instruction Set Architectures (ISAs)
- x86
- Intel's x86 architecture commonly used in modern desktop and server systems.
- ARM
- ARM architecture widely used in mobile devices, embedded systems, and IoT devices.
Common Instructions(x86)
Instruction | Type | Description |
---|---|---|
MOV | Control Flow | Moves data between registers, memory, or immediate values. |
CMP | Control Flow | Compares two values and sets flags based on the result. |
JMP | Control Flow | Unconditionally jumps to a specified address. |
CALL | Control Flow | Pushes the return address onto the stack and transfers control to a specified address. |
RET | Control Flow | Pops the return address from the stack and transfers control back to the calling function. |
MOV | Memory Access | Moves data between registers and memory. |
LOAD | Memory Access | Loads data from memory into a register. |
STORE | Memory Access | Stores data from a register into memory. |
ADD | Arithmetic Operations | Adds two values and stores the result. |
SUB | Arithmetic Operations | Subtracts one value from another and stores the result. |
MUL | Arithmetic Operations | Multiplies two values and stores the result. |
DIV | Arithmetic Operations | Divides two values and stores the result. |
AND | Bitwise Operations | Performs a bitwise AND operation between two values and stores the result. |
OR | Bitwise Operations | Performs a bitwise OR operation between two values and stores the result. |
XOR | Bitwise Operations | Performs a bitwise XOR operation between two values and stores the result. |
Memory Addressing
Memory addressing in x86 architecture involves various addressing modes:
-
Direct addressing: Accessing memory using a specific memory address.
mov eax, [0x12345678]
-
Indirect addressing: Accessing memory using a value stored in a register or memory location.
mov eax, [ebx]
-
Indexed addressing: Adding an offset to a base address stored in a register.
mov eax, [ebx + 0x10]
-
Scaled indexing: Multiplying an offset by a scaling factor before adding it to a base address.
mov eax, [ebx + esi*2]
-
Relative addressing: Accessing memory relative to the current instruction pointer or program counter.
jmp near ptr label
Example
; Example x86 assembly code
section .text
global _start
_start:
mov eax, 1 ; Control Flow - Move value 1 into the eax register
mov ebx, 42 ; Control Flow - Move value 42 into the ebx register
add eax, ebx ; Arithmetic Operations - Add the values in eax and ebx, storing the result in eax
cmp eax, 50 ; Control Flow - Compare eax with the value 50
jl less_than_50 ; Control Flow - Jump if less than 50
jg greater_than_50 ; Control Flow - Jump if greater than 50
jmp equal_to_50 ; Control Flow - Jump if equal to 50
less_than_50:
; Code for when eax is less than 50
jmp end
greater_than_50:
; Code for when eax is greater than 50
jmp end
equal_to_50:
; Code for when eax is equal to 50
end:
; End of program
mov eax, 1
Windows
File System
Windows supports different file systems. Here's a comparison:
File System | Features |
---|---|
NTFS | Supports advanced features like file and folder permissions, encryption, compression, and journaling. |
FAT | Simple file system with limited features, suitable for small storage devices and compatibility with older systems. |
In Windows, important directories include:
- User Directory (e.g., C:\Users\Username): The user's home directory, which contains personal files and user-specific settings.
- System Directory (e.g., C:\Windows\System32): Stores essential system files and libraries.
- Registry (e.g., HKEY_CURRENT_USER\Software): A hierarchical database that stores system and application settings.
When comparing the file structures of 32-bit and 64-bit versions of Windows, the main difference lies in the system directories. On 64-bit systems, there are separate directories for 32-bit and 64-bit files:
- 32-bit System Directory: C:\Windows\SysWOW64
- 64-bit System Directory: C:\Windows\System32
This structure ensures compatibility for 32-bit applications on 64-bit systems.
Registry
Consists of keys, subkeys, and values. Here's an overview of the registry structure:
Root Key | Description |
---|---|
HKEY_CLASSES_ROOT | Contains file associations, COM objects, and ActiveX controls. |
HKEY_CURRENT_USER | Stores settings for the currently logged-in user. |
HKEY_LOCAL_MACHINE | Stores system-wide settings and hardware configurations. |
HKEY_USERS | Contains profiles for all user accounts on the system. |
HKEY_CURRENT_CONFIG | Stores information about the current hardware profile. |
Windows APIs
The Windows API (Application Programming Interface) provides a set of functions that allow developers to interact with the operating system and its components.
Memory, Process, and Thread Management
Memory Management
Windows identifies memory regions through memory addresses and uses memory management techniques to allocate, deallocate, and protect memory. Some unique attributes include:
- Virtual Memory: The virtual memory system provides each process with its own address space, allowing programs to operate independently of one another.
- Memory Protection: Memory regions can be protected with different access permissions, such as read, write, or execute, to ensure memory integrity and security.
- Page Tables: Windows employs page tables to map virtual addresses to physical addresses and manage memory pages efficiently.
Process Management
A process in Windows represents an instance of a running program. Each process has a unique identifier (Process ID) and its own virtual address space. Some important attributes and API functions include:
Attribute | Description | API Functions |
---|---|---|
Process ID (PID) | A unique identifier assigned to each process. | CreateProcess, OpenProcess, GetCurrentProcess |
Process Termination | API functions to terminate a process. | TerminateProcess, ExitProcess |
Process Creation | API functions to create new processes. | CreateProcess, CreateRemoteThread |
Thread Management
A thread represents an execution context within a process. Threads allow concurrent execution and enable multitasking. Each thread has its own stack, registers, and execution state but uses the virtual address space assigned to its parent process. Some important attributes and API functions include:
Attribute | Description | API Functions |
---|---|---|
Thread ID (TID) | A unique identifier assigned to each thread within a process. | CreateThread, GetCurrentThread, OpenThread |
Thread Synchronization | API functions for thread synchronization and coordination. | WaitForSingleObject, WaitForMultipleObjects, CreateMutex |
Thread Termination | API functions to terminate a thread. | TerminateThread, ExitThread |
PEB and TEB
- PEB: The PEB contains information about a process, including its image base address, command-line arguments, environment variables, loaded modules, and more.
- TEB: The TEB stores thread-specific information, such as the thread ID, stack base and limit, thread-local storage (TLS) data, and exception handling information.
Here's a table summarizing the attributes and API functions related to the PEB and TEB:
Attribute | Description | API Functions |
---|---|---|
PEB | Process-specific information | GetModuleHandle, GetCommandLine, GetEnvironmentVariable |
TEB | Thread-specific information | GetCurrentThread, GetThreadId |
Tools
Hex Editor
A hex editor is a tool used to view and edit binary files at the hexadecimal level. It allows users to examine and modify the raw data of files, including executables, libraries, and other binary formats.
Decompiler
A decompiler is a tool that takes an executable or binary file and attempts to reconstruct the original source code from which it was compiled. It can be useful in reverse engineering to analyze and understand the functionality and logic of a program.
Disassembler
A disassembler is a tool that converts machine code or binary files into assembly language instructions. It allows reverse engineers to examine the low-level instructions of a program, understand its structure, and analyze its behavior.
Debugger
A debugger is a tool used for analyzing and troubleshooting programs. It allows users to execute a program step by step, set breakpoints, inspect variables, and track the program's execution flow. Debuggers are essential for dynamic analysis, bug hunting, and vulnerability discovery.
- Ring0
- A ring0 debugger operates in kernel mode and provides deep visibility into the system's inner workings and allows for advanced kernel-level debugging, allowing access to any address in memory.
- Ring3
- A ring3 debugger operates in user mode and only lets us access the address space used by the process we are debugging. They are often user friendly but are commonly detected by anti-reversing techniques
Monitoring Tools
- System:
- System monitoring tools are used to monitor access to files or registry keys
- API:
- API monitoring tools hook Windows APIs used by the process under examination.