const {P,H2,H3,Callout,Code,Ul,Related,PostHead}=window;
function Article(){
return <>
<PostHead cat="/TOOLS" date="2026-07-22" title="The reverse-engineering desk: what each tool is for" lede="A binary is not a Ghidra window. Identify, decompile, confirm. The tools only make sense as a sequence."/>
<P>People ask “IDA or Ghidra?” as if that were the engagement. It is a later question. First: what is the file. Then: who is allowed to open it. Then: which view of it is a hypothesis, and which view is a measurement.</P>
<Callout>Everything here assumes an offline sample and a written authorization. No production attach, no “just this one vendor box on the internet.”</Callout>
<H2>Identify before you decompile</H2>
<P><strong>file</strong>, <strong>readelf</strong>/<strong>otool</strong>, <strong>objdump -d | head</strong>, hashes. You want architecture, stripped or not, packed or not, linked how. A 40 MB “firmware.bin” is not an ELF. Opening it in IDA as raw x86 is how you waste a day.</P>
<P><strong>strings</strong> is not analysis. It is a map of what the author left readable. Use it to name targets (“dropbear”, “uboot”, “JNI_OnLoad”), not to declare findings.</P>
<Code lang="sh">{`sha256sum sample
file sample
readelf -h sample 2>/dev/null || otool -hv sample
# packer hint: high entropy + tiny readable stub`}</Code>
<H2>Decompilers are hypotheses</H2>
<H3>Ghidra</H3>
<P>Default on our desk. Free, headless, good enough decompiler, SLEIGH for odd ISAs. Java, slow to start, excellent for “analyze this folder of ELFs overnight.” If the customer has no IDA seats, this is the report’s screenshot.</P>
<H3>IDA Pro + Hex-Rays</H3>
<P>Still the industry default when the decompiler <em>is</em> the product: FLIRT, processor modules, the graph people already know how to read. We open it when the customer already paid for it, or when Hex-Rays is clearly better on that compiler. It is not a moral upgrade over Ghidra. It is a license.</P>
<H3>Binary Ninja</H3>
<P>BNIL is the reason to buy it: a stable intermediate language you can script without fighting the GUI. Smaller processor coverage than Ghidra. We use it when the question is “rewrite this parser in Python,” not “what is this PowerPC VLE blob.”</P>
<H3>radare2 / rizin</H3>
<P>Pipes. Headless by nature. Ugly graphs, unmatched for “give me the xref to this immediate from a script.” We do not teach new analysts r2 as a GUI. We teach it as the thing that runs in CI.</P>
<H3>Capstone / Keystone / Unicorn</H3>
<P>Libraries, not products. Capstone disassembles a buffer. Keystone assembles. Unicorn executes a snippet. Together they are the offset-oracle: the decompiler guessed a struct; the emulator votes.</P>
<H2>How we actually combine them</H2>
<P>One sequence, almost every time:</P>
<Ul items={[
'Hash and file. If packed, unpack or stop and say packed.',
'Load in Ghidra (or IDA if that is the house tool). Do not rename 400 functions on day one.',
'Find the parser, the update path, or the JNI bridge — the thing in scope.',
'Treat recovered types as fiction until confirmed.',
'Confirm with Unicorn or QEMU on a slice, or with a debugger on a device you own.',
'Write the layout the bytes actually use. That is the deliverable, not the decompiler listing.'
]}/>
<Code lang="desk.txt">{`identify  →  decompile  →  confirm  →  write
file/readelf   Ghidra/IDA    Unicorn/QEMU   struct notes
strings        BN (optional) Frida (owned)  risk register`}</Code>
<P>If you skip confirm, you are shipping Ghidra’s opinion. We have been wrong that way. Unicorn on a slice is the vote; the decompiler window is the draft.</P>
<H2>What we do not combine</H2>
<P>We do not chain “decompiler → copy-paste into a consumer chatbot → publish.” Customer samples stay in the tenant. The model, if used, sees a function or a calling convention, not the whole firmware.</P>
<Related items={[
['post-stripped.html','What “stripped” actually means']
]}/>
</>;
}
window.Article=Article;
mountPost();
