Binary analysis without symbols
Without symbols, a binary speaks a different language. But you already know most of the words. Structure, strings, imports, and calling conventions tell you a great deal before you disassemble a single instruction.
Stripped binaries — executables without symbol tables, without function names, without the human-readable annotations that make compiled code interpretable — are not the wall they appear to be. They are a different reading problem. The vocabulary is smaller. The grammar is less explicit. But a significant amount of what you need to know about a binary is present in forms that do not require symbols to read.
This is a post about methodology, not tools. The tools — IDA Pro, Ghidra, Binary Ninja, the family of open-source disassemblers — are well documented and not the limiting factor in most binary analysis. What limits the analysis is the reading strategy: what you look at first, what you use to orient yourself before you begin reading code, and what questions you are trying to answer.
Strings
The strings in a binary are a high-density summary of its function. Error messages. File paths. Protocol strings. Version identifiers. Format strings that tell you what data structures the binary processes. Cryptographic constants that tell you what algorithms are in use. Hard-coded addresses, credentials, and keys that tell you rather more than the author intended.
Start with strings. Run them through a filter that removes the noise — the generic C library error strings, the common boilerplate — and read what remains. The specific strings are the biography of the binary: what it does, what it talks to, what it was originally built to process. Often the strings alone are sufficient to orient the subsequent analysis toward the functions and code paths that are interesting for the specific question you are asking.
Import tables
The import table — the list of external functions the binary calls — is a capability list. A binary that imports recv and send handles network data. One that imports CreateProcess or execve creates new processes. One that imports EVP_EncryptInit uses OpenSSL for encryption. The import table tells you what the binary can do before you look at how it does it.
For ELF binaries, the dynamic symbol table (readelf -d, objdump -p) provides this information. The GOT and PLT — global offset table and procedure linkage table — are the runtime machinery that makes dynamic linking work, and they are visible in the disassembly as indirect calls through known addresses. Learning to recognise GOT/PLT call patterns in disassembly is one of the first things that makes stripped binary analysis legible.
Function prologues and calling conventions
Without symbols, function boundaries are identified by disassemblers heuristically, using knowledge of calling conventions and function prologue patterns. x86-64 System V functions typically begin with push rbp; mov rbp, rsp or a frame-pointer-less variant. ARM64 functions begin with a store-pair instruction saving the frame and link registers. These patterns are recognisable even without symbols.
Calling conventions tell you how arguments are passed. In x86-64 System V, the first six arguments arrive in rdi, rsi, rdx, rcx, r8, r9. Reading what is loaded into these registers before a call — and reading what the called function does with them — reconstructs the function signature without needing the symbol name. The return value is in rax. A function that checks a value against zero after a call is checking the return value for success or failure.
What structure reveals
Before disassembling anything, look at the binary's section layout. .text (code), .data (initialised data), .rodata (read-only data, including strings), .bss (uninitialised data). The relative sizes of these sections tell you about the binary's architecture: a large .rodata section suggests a lot of string constants; a large .data section suggests significant global state; an unusually large .text section suggests either a very large program or one that has had its code section padded or packed.
Entropy analysis — measuring the randomness of each section — tells you whether the binary is packed or encrypted: packed code has high entropy (approaching random), which is visually distinct from unpackaged compiled code. High-entropy sections are a flag to investigate further before proceeding with standard disassembly.
A stripped binary is not silent — it is speaking in a register you have to learn to hear. The structure, the strings, the imports, the calling conventions: these are the words you already know. Learning them well enough that they become automatic is what allows the disassembly, when you finally open it, to be read for what matters rather than for what is merely present.