Open-source project
hasherezade/tiny_tracer avatar
hasherezade/tiny_tracer

tiny_tracer records API calls as RVA-tagged events, and needs kernel debugging turned off first

A Pin Tool for tracing API calls etc

1,711 stars169 forksC++GPL-2.0

At a glance

What is it?
tiny_tracer is an Intel Pin tool that traces API calls, selected instructions, inline syscalls and section transitions into a .tag file of relative addresses. Its most practical constraint is not technical: Pin requires kernel debugging to be disabled, which changes how you configure the analysis machine.
Who is it for?
Adopt tiny_tracer when you are analysing a packed or evasive Windows sample and want an RVA-tagged log that can include selected API inputs and outputs and load into other analysis tools. Do not adopt it on a machine where kernel debugging must stay enabled, since Pin cannot work correctly with it on, and check the Defender false positive note before assuming an infection.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 144 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The trace format is RVA;event, and that is the point

Output goes to a.tag file where each line is a relative virtual address followed by a semicolon and the traced event:

txt
345c2;section: .text
58069;called: C:\Windows\SysWOW64\kernel32.dll.IsProcessorFeaturePresent
3976d;called: C:\Windows\SysWOW64\kernel32.dll.LoadLibraryExW
3983c;called: C:\Windows\SysWOW64\kernel32.dll.GetProcAddress

The choice of RVA rather than an absolute address is what makes the file useful. Addresses are module-relative, so the log can be loaded into a disassembler or debugger alongside the same module and the calls line up with the code you are looking at. The README links a wiki page on using the tags with disassemblers and debuggers.

The events are labelled by kind, here section transitions and called. In the abbreviated example the sequence LoadLibraryExW then GetProcAddress twice is the ordinary dynamic resolution pattern, and having it laid out as addresses rather than text makes the repetition visible at a glance.

The format can also represent the input and output of selected functions.

What can be traced beyond plain API calls

The tracing scope is broader than a call log, and each extension has its own wiki page in the project.

Beyond API calls with input and output of selected functions, the tool traces defined local functions and functions from statically linked libraries, which is the part that matters for a sample with a small or empty import table.

Selected instructions can be traced individually: RDTSC, CPUID and INT are each named. RDTSC and CPUID are the classic anti-debug signals, so tracing them shows when a sample checks for timing anomalies or processor features.

Inline system calls are traced with parameters of selected syscalls. That covers samples that bypass the normal API layer, which ordinary API hooking misses entirely.

Section transitions between parts of the traced module are recorded, described in the README as helpful in finding the OEP, the original entry point, of a packed module. And executed instructions inside code fragments you define can be traced, with disassembly output, which is how you narrow a trace to the interesting region instead of the whole run.

There is also evasion watching in the source tree, with AntiDebug and AntiVm units alongside it.

Anti-debug and anti-VM evasion, stated plainly

The README claims the tool evades some known anti-debug and anti-VM techniques, and links both to their own wiki sections under the INI file documentation. That the behaviour is configured from an INI file is worth noticing: it means the evasion settings are part of the tool's configuration surface rather than compiled in.

The source layout supports that reading. AntiDebug.cpp and AntiVm.cpp sit at the repository root as first-class units, next to EvasionWatch.cpp, and Settings.cpp with its header suggests configuration is central. PinLocker.h and ThreadMapper.cpp indicate the tool manages per-thread state and pinning, both necessary when instrumenting real multi-threaded samples.

The honest reading of the claim is that it defeats some techniques, not all. A sample that fingerprints the Pin toolchain by other means will still detect it, and the word some in the README is doing real work. If your sample's evasion is not working, the answer is more configuration in the INI file, not a different tool.

Kernel debugging must be disabled, and Defender will flag the checker

This is the section to read before anything else, because it changes your environment rather than your workflow.

For Pin to work correctly, kernel debugging must be disabled. That requirement is stated in the README warnings.

The repository ships a helper for this. In install32_64 there is a utility that checks whether the kernel debugger is disabled, kdb_check.exe with its source in a related pe_utils repository, and the Tiny Tracer batch scripts call it. If you build the project by hand you still need to confirm this state yourself.

The utility has a side effect worth anticipating: the README states it is sometimes flagged as malware by Windows Defender, and describes that as a known false positive. The suggested fix is to exclude the installation directory from Windows Defender scans. On a locked-down corporate analysis host where you cannot add exclusions, that is a blocker rather than an inconvenience.

There is also a version boundary: since Pin 3.20, support for old versions of Windows was dropped. For Windows below 8 there is a separate legacy build documented in the wiki.

Building on Windows and Linux, and the AppVeyor escape hatch

The project was tested with Intel Pin 4.2, which is the version to match when building.

Build instructions exist for both Windows and Linux, in the wiki, and the repository carries the tooling for both paths: build_env.bat and install_vs.bat for the Windows Visual Studio route, and make_linux.sh, make_mingw.sh and find_sdk_win.sh alongside a makefile and makefile.rules for the others. There is also a .appveyor.yml at the root and tasks.vs.json for Visual Studio task configuration.

The README offers a specific workaround if the Windows build gives you trouble: use the test builds from the AppVeyor server, select your platform, and open Artifacts. It also tells you to check the Console output to see which version of Pin those artefacts require, then follow the installation instructions.

That is a useful detail rather than boilerplate. A mismatch between the Pin version you have and the one a prebuilt artefact expects produces a load failure that is hard to diagnose from the error alone, so the console line is the thing to read first.

There is also a related tool for the tedious part: IAT-Tracer by YoavLevi, recommended for automatically generating the params.txt file used to trace API arguments.

Where it is the wrong tool

It traces x86 and x64 Windows binaries through Pin, so it is not a cross-platform instrument and not a Linux or macOS native tracer.

It also does not decompile, does not dump memory as a readable structure and does not tell you what a function means. For static analysis of a binary without running it, a disassembler is the right instrument; for dynamic analysis with an argument-level view, a full debugger gives more.

Where it beats a debugger is scale and stealth of output. A full trace of a sample that runs for minutes produces a log you cannot read, while a tag file of addresses loads into the tool you are already using. That is a real advantage for the packed-sample case the section-transition tracing targets.

One more constraint to plan around: kernel debugging off means you cannot also attach WinDbg to the kernel on the same machine, so a workflow that combines kernel and user-mode inspection needs two machines.

The repository is not archived, the last push was on 2026-06-02, release 4.0 was tagged on 2026-05-28 after 3.2 in November 2025 and 3.0 in June 2025, and the code is GPL-2.0.

Editorial conclusion

Adopt tiny_tracer when you are analysing a packed or evasive Windows sample and want an RVA-tagged log that can include selected API inputs and outputs and load into other analysis tools. Do not adopt it on a machine where kernel debugging must stay enabled, since Pin cannot work correctly with it on, and check the Defender false positive note before assuming an infection. First build against the Pin version the AppVeyor console output names, since the test builds are platform specific and 3.20 dropped support for Windows versions before 8.

Frequently asked questions

What does tiny_tracer require before it will run?

Kernel debugging must be disabled, because Pin cannot work correctly with it enabled. The repository ships kdb_check.exe in install32_64 to verify this, and the batch scripts call it during setup.

What version of Intel Pin does tiny_tracer work with?

It was tested with Intel Pin 4.2. Note that Pin 3.20 dropped support for old versions of Windows, so Windows below 8 needs the separate legacy build.

What format is the tiny_tracer output file?

A .tag file with one RVA;traced event pair per line, for example 58069;called: C:\Windows\SysWOW64\kernel32.dll.IsProcessorFeaturePresent. Relative addresses let the tags be loaded into other analysis tools alongside the module.

Can tiny_tracer trace syscalls and local functions, not just API calls?

Yes. It traces defined local functions and statically linked library functions, inline system calls with parameters of selected syscalls, RDTSC, CPUID and INT instructions, and transitions between sections of the traced module.

Why does Windows Defender flag the tiny_tracer setup?

The README states that kdb_check.exe, the utility that checks whether kernel debugging is disabled, is sometimes flagged as a known false positive, and suggests excluding the installation directory from Defender scans.

Official sources

  1. hasherezade/tiny_tracer on GitHub
  2. Issues
  3. License: GPL-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hasherezade-tiny-tracer.svg)](https://hysenlabs.com/projects/hasherezade-tiny-tracer)

Was this useful?