In 2011, Google acquired the company Zynamics which made reverse engineering tools. A few months ago, in late August, Google open-sourced one of these tools, BinNavi, which they describe as a binary analysis IDE. BinNavi can be thought of as an alternative front-end for the popular reversing tool IDA Pro. BinNavi was directly reliant on IDA Pro to disassemble binaries and make sense of that disassembly so although BinNavi was now free, you still had to pay at least $600 for IDA Pro to be able to use it.
So two weeks ago Chris Eagle (author of "The IDA Pro Book: The Unofficial Guide to the World's Most Popular Disassembler") released fREedom to convert disassembly, that was created by the library Capstone, to something useable for BinNavi. This means you could have a complete tool chain for doing reversing made from free, open-source, tools, that at least had a fairly polished front-end, as many of the open-source alternatives lack a nice UI. Professional reversers will still opt for the amazing support and large feature set of IDA Pro, but an open-source tool chain opens up some options, such as being able to tinker and specialize the tool to specific needs.
Halvar Flake (former CEO of Zynamics) showed a little of what BinNavi and fREedom could do in his post here, where he also mentions some of the current limitations. One limitation not mentioned was the need for some guidance on getting all of this to work. That's the goal of this post.
Before anyone feels misled, it should be mentioned that in general, this tool chain is not yet usable for real work. fREedom is not providing BinNavi with enough information, and BinNavi has enough little bugs, that I couldn't actually use it to reverse anything. For example, from fREedom, I need the ability to find where the
main function is, what text strings are being referenced, and what API calls from DLL imports are being made. From BinNavi, there are bugs where I couldn't see what the comments were that I was writing until I submitted them, and then I couldn't edit them. However, both those projects are huge stepping stones, and BinNavi clearly has a lot of untapped potential once it has the data it needs and the minor bugs get cleaned up. I expect great things from these, and I hope this post helps get people set up quickly so they can work on some of these issues.
Installing on Debian
In my setup, I installed fREedom and it's postgres database in a Debian VM, and then run BinNavi on my host which connects to the database inside the guest VM.
The main requirements of fREedom are capstone (for disassembling), psycopg2 (for communicating between python and postgres), and a postgres database. The following script works on a fresh install of Debian 8.2, which will create a database user and DB named
binnavi with the password
CHANGEME. There are two lines that can be uncommented to allow remote access to the database, which is required for my setup of running this in a VM that I connect to from the host.
export PGPASSWORD='CHANGEME' # Get some dependencies apt-get install -y build-essential python-dev libffi-dev git-core # Get sudo so the database code can be scripted apt-get install -y sudo # Install pip wget https://bootstrap.pypa.io/get-pip.py python get-pip.py # Install Capstone pip install capstone # Install PostgreSQL apt-get install -y postgresql postgresql-client postgresql-server-dev-all # Install psycopg (must install from source for latest version) git clone https://github.com/psycopg/psycopg2.git cd psycopg2/ python setup.py build python setup.py install cd .. # Set up DB export PGHOST=localhost # TODO: Need to lock this down more # I create a new DB user called binnavi, but that's not really required echo "ALTER USER binnavi WITH SUPERUSER;" | sudo -u postgres psql echo "ALTER USER binnavi PASSWORD '$PGPASSWORD'" | sudo -u postgres psql # Ensure they can connect locally echo "local all binnavi md5" >> /etc/postgresql/9.4/main/pg_hba.conf # Uncomment if you want to allow remote connections to the DB # echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.4/main/pg_hba.conf # echo "listen_addresses='*'" >> /etc/postgresql/9.4/main/postgresql.conf service postgresql restart # The database must be created by the user are connecting from BinNavi with echo "CREATE DATABASE binnavi;" | psql -Ubinnavi -dpostgres # Get fREedom git clone https://github.com/cseagle/fREedom cd fREedom/ psql -Ubinnavi -dbinnavi -f postgresql_tables.sql
Copy a binary to your VM that you want to disassemble (I used putty.exe like Halvar had), and from the fREedom directory run:
python fREedom.py --database=binnavi --user=binnavi --pass='CHANGEME' --dbhost=127.0.0.1 --binary=putty.exe
The screen output should show:
Created section .text, 0x401000:0x471c87, raw length 0x70e00, perms 5 Created section .rdata, 0x472000:0x4905d6, raw length 0x1e600, perms 1 Created section .data, 0x491000:0x497848, raw length 0x1c00, perms 3 Created section .rsrc, 0x498000:0x49bd40, raw length 0x3e00, perms 1 Created section .reloc, 0x49c000:0x4a1a58, raw length 0x5c00, perms 1 After first pass, have 49911 insts found 49911 instructions found 9189 basic blocks found 634 functions add_sections add_types add_operands add_instructions add_functions add_basic_blocks add_nodes add_trees add_tree_nodes
On my host, I then installed Java (it requires the latest Java 8), and then simply ran:
git clone email@example.com:google/binnavi.git cd binnavi java -jar prebuilt\binnavi-all.jar`
Ignore the prompt about configuring your IDA Pro by clicking cancel.
Set up your database. The identity field is simply used to show a name next to any comments you create, which would be useful if you were on a team of people all reversing the same binary.
From here, you'll be able to see various disassembly views and call graphs. You can change the color of disassembly nodes and comment on them. For example, here is contrived example of me making multiple comments on a node from different session Widows I had open which auto-refreshed the comments on the different views as I entered them.
Hopefully this helps people get started in playing with these tools so they can get them fixed up so they can be made more usable.
I ran into a couple of problems trying to get all this set up, so this is just for search engines to pick up when people run into the same problems.
I originally used
apt-get to install psycopg2, and ended up with this error when running fREedom:
File "./fREedom/binnavi_db.py", line 456, in create_empty_tables with self.conn as conn: AttributeError: __exit__
If you see that, upgrade your psycopg2 by installing from source as explained above. Check you're using the latest:
# python >>> import psycopg2 as psy >>> psy.__version__ '2.7.dev0 (dt dec pq3 ext)'
Unsupported major.minor version 52.0
I was using an old VM initially for test this out on, and received this error when running BinNavi:
$ java -jar prebuilt/binnavi-all.jar Exception in thread "main" java.lang.UnsupportedClassVersionError: com/google/security/zynamics/binnavi/CMain : Unsupported major.minor version 52.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:800) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:449) at java.net.URLClassLoader.access$100(URLClassLoader.java:71) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)
If you see that, then you aren't running Java 8. Check with
BinNavi E00060 error
BinNavi may not like how you've created your database, which will show this error:
Error Message: E00060: The module could not be initialized org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2270) org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1998) org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255) org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:570) org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:420) org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:413) com.google.security.zynamics.binnavi.Database.AbstractModuleCreator.initializeModule(AbstractModuleCreator.java:330) com.google.security.zynamics.binnavi.Database.PostgreSQLProvider.initializeModule(PostgreSQLProvider.java:475) com.google.security.zynamics.binnavi.disassembly.Modules.CModule.initialize(CModule.java:326) com.google.security.zynamics.binnavi.Gui.MainWindow.Implementations.CModuleInitializationFunctions.initializeModuleInternal(CModuleInitializationFunctions.java:69) com.google.security.zynamics.binnavi.Gui.MainWindow.Implementations.CModuleInitializationFunctions.access$000(CModuleInitializationFunctions.java:33) com.google.security.zynamics.binnavi.Gui.MainWindow.Implementations.CModuleInitializationFunctions$1.run(CModuleInitializationFunctions.java:98)
This is issue #62, and the install script above should avoid this, but alternatively, give BinNavi creds for a database superuser that can create a new database and pass it a non-existing database to connect to so it will create it, then run fREedom's sql script on that and use fREedom to load a module into it.