Friday, October 6, 2017

Pin Visual Coverage Tool for Binary Ninja

Introduction

I've been getting familiar with Vector 35's Binary Ninja. It's an incredible, affordable, cross-platform static analysis toolkit for binaries. Binary Ninja also has an intuitive Python API, which you will see soon.

Pin is Intel's dynamic binary instrumentation toolkit. It allows you to easily write your own plugins in C++ for dynamically instrumenting code on the fly. I've decided to use this tool in conjunction with Binary Ninja to provide visual code coverage for test cases, or for quickly identifying dead code paths. This has been an over simplification of both Binary Ninja, and Pin. You should check them both out, and see if they are right for you.

I am not an expert in either of these tools, and this has been my first endeavor writing plugins for either of them. As such, if you see something wrong, then please submit a pull request. This whole process has been a learning experience, and I'm always down to sharpen the toolkit.

Install Pin

This was all done on a Linux based system. First, go ahead and download + extract the Pin toolkit. You'll want to place the path where it's been extracted into your $PATH variable.

Inside of the pin directory you will see source/tools. This is where the plugins that are shipped with Pin. You can compile them individually, and play around with their functionality. A typical execution will look like the following, which will execute /bin/ls with the desired instrumentation.

$ pin -t (shared object of plugin) -- /bin/ls

Go ahead and grab a copy of BasicBlocks from github. BasicBlocks is a pin tool written for this Binary Ninja plugin. It prints the address of each basic block that is executed. We'll import this data later into Binary Ninja, in order to get a visual analysis of code coverage.

Now, you can fire up Binary Ninja, and two menu items will be added under the Tool menu.

Go ahead and open /bin/ls. If you haven't generated a basic block trace, go ahead and run the pin command shown above. Our next step will be to import it into Binary Ninja.

If the binary is compiled as a Position Independent Executable (PIE), the plugin will attempt to calculate the slide from the initial Basic Block to the program's entry point. This has so far been successful on x86_64 Linux using both tcpdump, and tshark as examples. Below is a screenshot from tshark with PIE enabled, and a Basic Block trace using the pcap testcase that ships with AFL.