Reverse Engineering Tooling Training

The Reverse Engineering Toolkit: CallHook, TrueDiffing, ExportFinder and NetHook

Mr.Un1k0d3r

Every reverse engineering session starts the same way: you have a binary, and the binary has no interest in explaining itself. No symbols, no source, no documentation, and quite possibly some effort spent making sure it stays that way. What you do have is a set of questions, and the speed at which you can answer them is the entire game.

Over the past year we have been building tools around those questions. Not a monolithic "reversing suite" that does everything badly, but small, sharp Windows tools that each answer one question fast and get out of your way. This post is a tour of three of them: CallHook, TrueDiffing and ExportFinder, plus a word on where NetHook fits.

They also point at something bigger. All four are the working kit for Reverse Engineering for Red Teamers, our next training, which is coming soon. If you want to know the moment it lands, and hear about new tools as they ship, subscribe to the newsletter - that is where both get announced first.

Diagram of the four-tool reverse engineering loop: CallHook to observe calls, ExportFinder to resolve symbols, TrueDiffing to compare builds, and NetHook to intercept traffic, with a feedback arrow returning to the start.
The loop. Each tool answers one question, and every answer reshapes the next one.

The problem with reading a binary

Static analysis tells you what a program can do. Open it in a disassembler, follow the cross references, and you get the full space of possible behaviour. That is enormous, most of it never executes, and none of it tells you which branch the program actually took when it decided to phone home at 03:00.

Dynamic analysis tells you what a program just did, which is far more useful and far harder to capture. Attach a debugger and you get precision, but you also get a stop-the-world workflow: break, inspect, step, resume, lose your place, start over. That is fine for a function. It falls apart when the interesting behaviour is spread across four threads, a child process, and eight seconds of startup you keep skipping past.

The toolkit exists to close that gap. Observe the whole run, then dive into the twelve instructions that matter.

CallHook: what is it actually calling?

CallHook injects into a running process and records the calls it makes, in order, with arguments. Not just the imports in the IAT, and not just the handful of APIs a sandbox happens to hook: in full single-step mode it observes execution itself, so dynamically resolved calls, internal helpers, and anything reached through a pointer all show up alongside the obvious kernel32 traffic.

CallHook tracing a PowerShell process: a live call table with time, sequence, thread, depth, caller and callee columns, and a panel below showing the selected call's arguments as pointer values with hex and ASCII dumps.
CallHook mid-trace: 3,593 calls from a PowerShell process, with the selected call's arguments dumped as hex and ASCII.

A few details in that screenshot matter more than they look:

Traces are searchable by function, module or argument content and can be saved, which turns a behavioural question into a diffable artifact: capture a trace of the working case, capture one of the failing case, and compare the two.

TrueDiffing: what changed?

Diffing is the highest leverage technique in reverse engineering, because a vendor who ships a patch has told you exactly where the bug was. The difficulty has never been the concept, it has been that recompiling a program moves everything. Addresses shift, functions get reordered, the compiler inlines something new, and a byte-level diff lights up the entire file.

TrueDiffing works at the level you actually think at. It parses both files, matches functions across them, and classifies each one as modified, new, removed, or unchanged. The counters in the screenshot below tell the story of the whole build in one line: 278 modified, 1,947 added, 1,671 removed, out of 3,896 functions.

TrueDiffing comparing two builds: a function list classified as modified, new or removed on the left, and an instruction-level diff of the selected function on the right showing opcode bytes and added and removed instructions in colour.
Instruction-level diff of one function. The same code lives at 0x10fe4 in the first build and 0x11c7c in the second, and TrueDiffing lines them up anyway.

Look at the header of that diff: primary 0x10fe4 → secondary 0x11c7c, with a +5/-5 insns summary. The function moved by more than 3KB between builds and is still matched and aligned instruction by instruction, with opcode bytes alongside the mnemonics so you can see encoding changes that the disassembly text alone would hide. That alignment is the whole point: you are diffing the code, not the offsets.

It is not limited to Windows binaries either. The build in the screenshot is ELF, ARM 32-bit, which is exactly the sort of target that shows up when the interesting device on the engagement is not a laptop. There is a Strings tab beside Functions for the same reason: a changed string is often the fastest route to a changed feature.

When the instruction list is not enough, switch to the graph view:

TrueDiffing graph view: two control flow graphs side by side, with basic blocks colour-coded as unchanged, modified, new or removed and edges marked as branch taken or not taken.
Side-by-side control flow graphs, with each basic block classified and each edge marked as taken or not taken.

Two control flow graphs, side by side, with every basic block coloured by what happened to it and every edge labelled as the taken or not-taken path. This is how you spot a bounds check that quietly gained a branch, or a loop that grew an extra exit. Hover a block and you get its full disassembly; the panes zoom and pan independently so you can hold the interesting subgraph in view on both sides at once. When you are done, export the report and hand it to someone who was not sitting next to you.

The obvious use is 1-day analysis, but it earns its place just as often on ordinary work: comparing your own build before and after an obfuscator, checking what a vendor changed in a "minor" release, or telling two samples of the same malware family apart.

ExportFinder: what does it really import?

CallHook tells you a call went to kernel32!AcquireSRWLockExclusive. Then you go looking for that function in kernel32.dll and it is not there. Not in a meaningful sense, anyway.

ExportFinder showing the export table of kernel32.dll: a list of DLLs in a folder on the left and a table of ordinal, RVA, name and forwarded-to columns on the right, including entries marked as forwarders.
ExportFinder on C:\Windows\System32. kernel32.dll exports 1,693 symbols, and the first two are forwarders into NTDLL.

ExportFinder reads export tables and shows you what is genuinely there: ordinal, RVA, name, and the forward target when there is one. The screenshot makes the point immediately. AcquireSRWLockExclusive has no RVA at all. It is a forwarder to NTDLL.RtlAcquireSRWLockExclusive, and the code you want to read is in a different module entirely. AddDllDirectory forwards into an api-ms-win-core-libraryloader API set, which resolves somewhere else again depending on the host.

That is not trivia. Three things fall out of it:

It is also free. No licence, no trial timer. Download it and keep it in the same folder as the rest of your tools.

NetHook: what does it send?

The fourth question is the one that comes up the moment the binary talks to something. NetHook captures, inspects and rewrites a process's traffic before it is encrypted, by hooking the API calls the application uses to send and receive data. Certificate pinning, a custom TLS stack and proxy-unaware code all stop mattering, because you are reading the buffer before it ever reaches the network.

NetHook attached to a PowerShell process: a capture table of EncryptMessage, DecryptMessage and recv calls with source and destination addresses, beside a packet pane showing the plaintext HTTP request in hex and ASCII and controls to forward, modify or drop the held packet.
NetHook on a PowerShell process. Those are Schannel calls on a 443 connection, and the pane on the right is the request in clear text.

Read that capture table from the left: EncryptMessage going out, DecryptMessage and recv coming back, on a connection to port 443. The pane on the right is the same traffic as a plain HTTP request, hex on one side and ASCII on the other, because the hook sits on the buffer and not on the socket. Switch from Capture to Intercept and a packet is held instead of passed on, so you can edit it and then forward, modify, or drop it - the point where testing stops being observation and starts being interaction.

We have written about it at length already, so rather than repeat it here: see Thick-Client Penetration Testing with NetHook for the full walkthrough, or the NetHook product page.

Putting it together

Here is what a real session looks like when the tools are in the same toolbox. Say you are handed an updater binary that is doing something it should not.

  1. Run it under CallHook. Single-step trace, all threads, loader tracing on, follow the child it spawns. Ninety seconds later you have a few thousand calls and, more usefully, a depth column showing that everything interesting happens under one caller at depth 4.
  2. Resolve the odd one out with ExportFinder. One callee is an ordinal import from a DLL you have never seen. A folder-wide search finds it, the export table names it, and a forwarder chain points at the module that actually implements it.
  3. Diff the two versions with TrueDiffing. The behaviour is new, so compare last month's build against this one. Out of 3,896 functions, 278 changed, and the graph view shows one of them gained a branch that was not there before. That is your function.
  4. Watch the wire with NetHook. Confirm what it sends, in plaintext, and you have the full story: which code path, why it changed, and what left the machine.

Each step took minutes and produced an artifact you can hand to someone else. None of it required sitting on a breakpoint hoping the right thread hit it.

These tools are the backbone of the RE training

There is a reason all of this exists at once. Every tool here is part of Reverse Engineering for Red Teamers, our next training, and the course is written around them rather than around a slide deck. You will trace a live process, resolve what it imports, diff two builds down to the branch that changed, and intercept what it sends, using the same tools on the same kind of targets you meet on a real engagement.

The course is coming soon. The full course synopsis is already online if you want to see exactly what it covers, and the tooling modules are being built around these tools right now. The release announcement goes out to the newsletter first.

Subscribe to the newsletter to get the announcement the day Reverse Engineering for Red Teamers goes live, along with new tool releases and technical posts as they land.

Try them

CallHook, TrueDiffing and NetHook each come with a free trial, and ExportFinder is free outright. They all live on the Software hub. Point them at something you have been meaning to understand and see how far you get before lunch.

← Back to Blog