There’s a quiet war going on inside every compiled binary. On one side, the original logic—obfuscated, stripped, or just buried under layers of compiler optimizations—sits frozen in time. On the other, a reverse engineer armed with nothing but a disassembler and a hex editor tries to reconstruct meaning from a sea of bytes. No sandbox, no debugger, no execution. Just the file, its structure, and the tools that can peel it apart. If you’ve spent any time in the trenches of malware triage, firmware extraction, or vulnerability research, you already know: dynamic analysis only gets you so far. Sometimes the sample won’t run. Sometimes it’s a kernel driver. Sometimes you just need to understand what a binary can do without ever letting it touch a CPU. That’s where your toolkit makes or breaks you.
This isn’t a beginner’s shopping list. It’s a walkthrough of the instruments that actually matter when you’re staring at a raw ELF, PE, or Mach-O and need to figure out what it’s up to. We’ll cover disassemblers, hex editors with real muscle, format parsers, and the specialized gear that catches what the big suites miss. No buzzwords, no sales pitches—just the stuff that belongs in a serious reverse engineer’s locker.
The Heavy Hitters: Disassemblers and Decompilers
If static analysis has a center of gravity, it’s the disassembler. This is where machine code gets translated into assembly language, giving you a map of the binary’s logic. A good disassembler doesn’t just dump opcodes; it reconstructs control flow, identifies functions, and cross-references data. It becomes your primary lens for understanding the binary.
Ghidra is the NSA’s open-source beast, and it’s earned its place in the toolkit. The decompiler is shockingly good for a free tool, often producing cleaner C-like output than some paid alternatives. It handles x86, ARM, MIPS, and a growing list of exotic architectures. The real power, though, is in its scripting engine—Java or Python—which lets you automate tedious tasks like decoding custom string obfuscation or identifying known cryptographic constants. The graph view makes control flow visible at a glance, and the collaborative server means multiple analysts can work the same binary without stepping on each other’s toes. The learning curve is real, but once you’ve got the data type manager dialed in and a few scripts under your belt, you’ll wonder how you ever worked without it.
IDA Pro still holds the throne for complex or exotic binaries. Its interactive interface turns a disassembly listing into a living document—renaming functions, retyping variables, adding comments, all with a few keystrokes. The FLIRT signature engine automatically labels known library functions, saving you hours of manual identification. The free version is a capable disassembler, but the full suite with the Hex-Rays decompiler is where IDA really shines. The plugin ecosystem is enormous: Python scripting, third-party extensions like Diaphora for binary diffing, and custom loaders for obscure file formats. It’s less a tool and more a platform.
Binary Ninja has carved out a loyal following with its slick interface and a genuinely useful intermediate language (IL) analysis. The medium-level IL (MLIL) output often reads cleaner than raw decompilation, making it easier to spot patterns at a glance. Its API-first design appeals to teams building custom analysis pipelines, and its speed on large binaries is noticeable. For ARM or MIPS firmware, Binary Ninja’s support is solid, and the collaborative features keep getting better.
radare2 (and its GUI frontend, Cutter) is the command-line junkie’s Swiss Army knife. It’s free, open source, and can dissect everything from x86 to obscure microcontrollers. The learning curve is brutal—memorizing commands like afl (analyze functions list) and izz (search strings) takes time—but the payoff is a tool that can be scripted, piped, and embedded into automated pipelines. For quick triage of a suspicious file, radare2’s string search and entropy analysis are hard to beat.

Peeling Back the Layers: File Format Parsers
Before you even fire up a disassembler, you need to understand the binary’s anatomy. Format parsers dissect headers, sections, imports, and resources, flagging anomalies that might point to packing, corruption, or deliberate tampering. Think of them as your first reconnaissance pass.
readelf and objdump (from GNU binutils) are the old guard for ELF files. A few flags dump section headers, symbol tables, and dynamic linking info. For PE files, pev (PE Viewer) and pecheck do the same from the command line. But when you want a visual approach, PE-bear offers a Qt-based interface that makes navigating the PE structure intuitive. It highlights anomalies, decodes rich headers, and lets you edit fields on the fly—handy for repairing corrupted files or understanding packer stubs.
For Mach-O binaries, MachOView is the go-to. It graphically displays the entire Mach-O structure, from fat binary headers to load commands and sections. When you’re dealing with iOS or macOS malware, this tool helps spot suspicious entitlements, encrypted segments, or abnormal dyld shared cache references. Pair it with jtool2 for command-line parsing and disassembly of Mach-O files, especially when working on a remote server or embedded device.
Hex Editors with Brains
Sometimes you need to get your hands dirty at the byte level. A hex editor isn’t just for viewing raw data—it’s for patching, carving, and manually reconstructing structures. The right hex editor understands binary formats and can interpret data on the fly.
010 Editor stands out with its binary templates. These templates parse file structures and display them in a tree view, letting you click through headers, fields, and substructures. For reverse engineering custom file formats or network protocols, you can write your own templates in a C-like syntax. The integrated disassembler and data inspector make it a lightweight analysis environment all on its own.
ImHex is a newer, open-source alternative that’s gaining traction. It features a pattern language for defining structures, a built-in node graph for data processing, and a modern dark interface. Its diffing capabilities are useful for comparing two versions of a binary to spot patches or injected code. For quick edits, HxD on Windows remains a fast, no-nonsense option with disk editing and memory dumping features.

String Analysis and Entropy Detection
Strings are the low-hanging fruit of static analysis. A quick strings dump can reveal IP addresses, URLs, registry keys, and even debug messages left by the developer. But modern malware rarely hands you plaintext. Strings get obfuscated, encrypted, or built on the stack at runtime, so you need tools that go beyond ASCII extraction.
FLOSS (FireEye Labs Obfuscated String Solver) is designed to automatically extract deobfuscated strings from malware. It uses heuristics and light emulation to decode stack strings, tight loops, and other common obfuscation techniques. Running FLOSS on a sample before you open a disassembler can give you a serious head start on identifying capabilities.
Entropy analysis helps detect packing and encryption. High entropy sections suggest compressed or encrypted data that might be unpacked at runtime. Detect It Easy (DIE) is a packer identifier that goes beyond simple signatures—it calculates entropy, examines section characteristics, and uses heuristics to name the packer or compiler. It’s cross-platform and supports plugins for custom detection logic.
Specialized Static Analyzers
Some tasks fall through the cracks of general-purpose disassemblers. That’s where niche tools come in, saving you hours of manual work when you’re dealing with specific file types or analysis goals.
Checksec is a tiny shell script that checks binary hardening features: PIE, RELRO, stack canaries, NX, and Fortify. It’s part of the pwntools suite and is essential for exploit developers assessing target difficulty. For a deeper dive into ELF security, readelf with the -l flag reveals GNU_RELRO segments and stack executability.
BinDiff (now free, integrated into Ghidra) and Diaphora are binary diffing tools that compare two versions of a binary to identify changed functions. This is invaluable for patch analysis: diff the vulnerable and patched versions to find the exact code fix, then reverse the vulnerability. Diaphora works as an IDA plugin and uses multiple heuristics—assembly, pseudo-code, graph matching—to produce high-quality matches.
For analyzing shellcode, scdbg is a libemu-based emulator that logs API calls without executing the code natively. It’s not truly static, but it bridges the gap by emulating just enough to decode the shellcode’s intent. Pair it with sctest for automated testing of shellcode samples.
Building a Workflow
Static analysis isn’t about picking one tool—it’s about chaining them into a pipeline that answers specific questions. Start with file identification: the file command, DIE, and a format parser. Check entropy and strings. If the binary is packed, consider unpacking it statically by locating the original entry point and dumping the unpacked code—tools like UPX can handle common packers, but for custom ones you’ll need to manually reconstruct the import table. Then load the unpacked binary into your disassembler of choice and begin function-level analysis.
Document as you go. Use the disassembler’s commenting and bookmarking features to mark interesting functions, suspicious strings, and potential vulnerabilities. Export your findings to a report or share the project file with your team. The goal is to build a mental model of the binary’s behavior without ever running it—a skill that separates the script kiddies from the professionals.

FAQ
What’s the difference between static and dynamic binary analysis?
Static analysis examines a binary without executing it, focusing on its structure, code, and data. Dynamic analysis runs the binary in a controlled environment (sandbox, debugger) to observe its behavior. Static analysis is safer for malware, can cover all code paths, and is often the only option for non-executable files like firmware or drivers. Dynamic analysis reveals runtime behavior like network connections and process injection. A complete investigation uses both.
Do I need to learn assembly language for static analysis?
Yes, at least one architecture’s assembly (x86, ARM, or MIPS) is necessary. Decompilers can produce C-like pseudo-code, but they’re imperfect—especially with obfuscated or hand-crafted assembly. Understanding the instruction set lets you verify decompiler output, spot anti-disassembly tricks, and manually analyze critical sections. Start with x86-64, as it’s widely documented and used in most desktop malware.
Can static analysis detect all types of malware?
No. Heavily obfuscated, polymorphic, or VM-protected malware can resist static analysis entirely. Some samples decrypt or download payloads only at runtime. In these cases, static analysis might reveal the packer or loader, but dynamic analysis is needed to capture the final payload. However, static analysis is still valuable for initial triage, identifying packers, and extracting metadata like compilation timestamps.
What’s the best free tool for static analysis?
Ghidra is the most powerful free option, offering a full decompiler and collaborative features. For quick triage, radare2/Cutter is excellent. If you’re on a budget, combine GNU binutils, strings, and a hex editor like HxD or ImHex. The free version of IDA is also useful for basic disassembly but lacks decompilation. Your choice depends on the task: Ghidra for deep dives, radare2 for automation, and binutils for quick checks.








