Live x86 Code Instrumentation with Frida
Since I moved to Oslo in February, I’ve had the pleasure of working together with Ole André Vadla Ravnås (say that ten times quick, or optimize and use @oleavr). In our not-so-ample spare time, we’ve been hacking on the Frida project that Ole André and Håvard started a while ago.
The Frida IRE is a free, interactive disassembler and reverse-engineering environment that we’re slowly piecing together for doing reverse-engineering the way we want it. It’s primarily targeted at binary code for the x86 (32bit and 64bit), ARM (Thumb, 32 and Thumb2) and MIPS. I’ve written the MIPS and ARM 32 and Thumb disassemblers, and I’m still working on the x86 (32 and 64) and the Thumb2 ARM disassembler.
I expect I’ll be blogging a lot about this project in the time to come, because there’s so much really cool stuff jam-packed into Frida now, of the feeling-very-brainy-when-we-figured-how-to-do-this type.
The first really cool part I’ll mention, is a project Ole André—-the undisputed Frida coding hero—-recruited me to do pair programming on. It’s a Windows-specific code tracing engine, which we refer to as a stalker. Think debugging running processes. Think live binary code rewriting. Think aspect oriented programming. Think inserting code chunks on the fly that inspect and modify the registers, stack, thread local storage, heap, function call arguments, function return values of running programs. Think scripting this. Think doing it all safely. That’s where we want to go.
So where are? Not too far away, actually. Last year, while waiting for summer to arrive, Ole André hacked up a prototype for a library called GUM that does a form of dynamic recompilation of x86 code. We took this prototype and extended it so that we can do live code tracing of any (32bit for now — but we have a lot of the 64bit parts work already) Windows application. We can even debug into Skype and Spotify, which normally kill themselves at the first sign of a debugger or code instrumentation tool. In fact, iTunes and Skype were our main motivation for writing this tool. Trying to figure out how these apps work seem to require a whole different class of code inspection tools than what Visual Studio, OllyDbg and SoftICE can provide.
Stalking programs
The core idea of the GUM-based stalker is as follows: you give it a block of code (usually a basic block), and it will generate a new basic block (in memory) where each original instruction is wrapped with customizable instrumentation code. If you somehow manage to trick the caller of the original basic block into calling the new block, you can do live instrumentation of the running program. This is what we referred to earlier as stalking.
The instrumented code is generated in a conceptually simple fashion: The original code block is disassembled, instruction by instruction. Each instruction ends up in the instrumented code block, wrapped inside an instrumentation template. The instrumented code is placed in a new memory page, and this page is marked executable.
The instrumentation template may be used to do any form of code tracing you might be interested in. It might look at the state of the stack/registers/heap, before or after any instruction in the basic block. In pure instrumentation mode, the template will never modify any state — the instrumentation is completely hidden from the running code.
But those are basic blocks. What happens to jumps? We rewrite those. When the stalker sees a call, ret or jmp instruction, we handle those specially. We figure out where in memory the call goes to, picks up that page, and run the stalker on it. This allows us to dynamically stalk (trace) through a program, and monitor its every instruction and call (that occurs in user-space).
And the really great part is that yes!, this works for dynamic calls too, and even for weird code that uses ret to call instead of jmp — you can’t believe how many nights we spent figuring out all the weird corner cases in the x86 instruction set to cover these things. Another weird corner case we’ve added support for is code that uses a local, in-function call to get esp (instruction pointer) for purposes of self-modifying code or similar. These might sound like weird corner cases to bother about, but when doing reverse-engineering, the subject program you’re investigating might have been run through all kinds of obfuscators and anti-RE tricks.
Injecting stalkers into running processes
Ole André is the kind of guy who grew up under particularly harsh conditions in the south western part of Norway. This has hardened him to a level where the usual abuse offered by the Win32 and Win64 APIs don’t affect him at all. Armed with his unshakable fearlessness, he spent a few weeks in the darkest and coldest periods of the Norwegian winter to write Win32 and Win64 apps that dynamically inject DLLs into running applications, and also execute arbitrary code from those DLLs.
You might already see where this is heading. By putting the stalker code into a DLL, and injecting it into Skype or iTunes, we can all of a sudden start tracing every instruction executed in every thread of these apps.
Sketches of an interactive environment
The following screenshot is the Frida IRE in its current incarnation.
This screenshot shows two possible uses of Frida:
We may start stalking the Spotify process when it makes a call to
WSARecv(somewhat equivalent toread()in Unix sockets) in theWS2_32.dlland that we stop stalking when it does another call to the same function. I.e, we trace all that happens inside the Spotify process between two calls toWSARecv. If you click theGo-button, this will happen.We also have a CLI, of course. Here, the trace shows that we’ve eventually managed to attach a script execute on calls to
DrawTextExWin the dynamic librarygdi32.dll.
The script (not shown) replaces the second argument to DrawTextExW, the pointer to the string to draw, with a pointer to a constant string which reads Hei. This is the result:
Whenever you mouse over a label, it is be redrawn, and its text replaced with Hei. In the screenshot, mr Vadla Ravnås has painted the play and the friends list on the left and right hand sides, respectively.


