Reverse engineering is the process of dissecting compiled software to understand its logic, behavior, and intent without access to source code. Whether you're analyzing malware, auditing closed-source binaries, or studying CTF challenges, the same core workflow applies: gather information statically, then confirm your hypotheses dynamically. This guide walks through that workflow with practical, tool-agnostic steps you can apply immediately.
Setting Up a Safe Analysis Environment
Before touching any unfamiliar binary, isolate your workspace. Use a dedicated virtual machine with no network access to your host, snapshot it before analysis, and disable shared folders and clipboard sync. Tools like a Linux VM with radare2, Ghidra, gdb, and objdump cover most static and dynamic needs, while a Windows VM with x64dbg and Process Monitor is essential for PE files. Never analyze suspicious samples on your primary machine, and always revert snapshots between sessions to avoid cross-contamination.
Static Analysis: Reading Without Running
Start by identifying the file type and architecture using file and readelf -h (Linux) or a PE header inspector (Windows). Check for packing or obfuscation with entropy analysis — tools like Detect It Easy flag suspiciously high entropy sections that suggest compression or encryption.
Next, load the binary into a disassembler such as Ghidra or IDA Free. Focus on:
- Imports and exports — API calls like
CreateRemoteThreadorVirtualAllocExhint at process injection;WSAStartupsuggests networking. - Strings — run
strings -n 8 binaryto surface hardcoded URLs, file paths, or debug messages that reveal functionality. - Control flow graphs — Ghidra's decompiler view turns raw assembly into readable pseudo-C, dramatically speeding up comprehension of loops and conditionals.
Annotate function names as you understand them. Renaming sub_401020 to decrypt_config immediately makes the rest of your analysis easier to follow.
Dynamic Analysis: Watching It Run
Static analysis only gets you so far, especially against obfuscated or packed code. Load the binary in a debugger and set breakpoints at suspicious API calls identified earlier. In x64dbg, breaking on VirtualAlloc or WriteProcessMemory often reveals unpacking routines as they write decrypted code into memory just before execution.
Use Process Monitor or strace/ltrace on Linux to log file, registry, and network activity in real time. This external view complements the internal view from the debugger and often surfaces behavior that's hard to spot in disassembly alone, such as temporary file creation or DNS lookups.
For network-capable binaries, run them alongside Wireshark or a fake internet simulator like INetSim to observe command-and-control traffic without letting the sample actually reach the internet.
Dealing With Anti-Analysis Tricks
Many binaries — especially malware — include checks designed to detect debuggers, virtual machines, or sandboxes. Common techniques include calling IsDebuggerPresent, checking for VM-specific registry keys, or measuring execution timing to detect single-stepping. When you spot these checks during static analysis, you can patch the conditional jump in the debugger to force the