Skip to content

Instantly share code, notes, and snippets.

@joshwatson
Last active April 27, 2016 13:41
Show Gist options
  • Save joshwatson/fa3808f8e665d9785a197c720816dffc to your computer and use it in GitHub Desktop.
Save joshwatson/fa3808f8e665d9785a197c720816dffc to your computer and use it in GitHub Desktop.
Binary Ninja script to identify virtual functions missed by auto-analysis
#! /usr/bin/python
import sys
import platform
import time
import os
try:
import binaryninja as binja
except ImportError:
if platform.mac_ver()[0]:
sys.path.append('/Applications/Binary Ninja.app/Contents/Resources/python')
if platform.dist()[0]:
# I don't know where your linux install is. Here's mine
sys.path.append('/data/binaryninja/python')
if platform.win32_ver()[0]:
sys.path.append(r'C:\Program Files\Vector35\BinaryNinja\python')
import binaryninja as binja
if len(sys.argv) < 3:
print 'usage: find_virtual_functions.py <input_db> [output_db]'
raise SystemExit(-1)
input_db = sys.argv[1]
# if no output_db, save over input_db
if len(sys.argv) < 4:
output_db = input_db
fm = binja.FileMetadata()
db = fm.open_existing_database(input_db)
if db is None:
print 'Could not open database!'
raise SystemExit(-1)
bv = db.get_view_of_type('PE')
reader = binja.BinaryReader(bv)
bv.update_analysis()
time.sleep(1)
# Start looking for read only pages after the PE header
# Every page and its page permissions have to be checked,
# because segment information isn't yet reachable in the API.
for page in range(bv.start+0x1000, bv.end, 0x1000):
if (bv.is_offset_readable(page) and
not bv.is_offset_executable(page) and
not bv.is_offset_writable(page)):
reader.seek(page)
# assume that function pointers are aligned
for offset in range(page, page+0x1000, bv.address_size):
if bv.address_size == 4:
addr = reader.read32le()
elif bv.address_size == 8:
addr = reader.read64le()
else:
print 'Uh, what arch is this?!'
raise SystemExit(-1)
if addr is None:
continue
# If we find a pointer to executable memory,
# it is probably a virtual function. Go ahead and add it.
if bv.is_offset_executable(addr):
# print 'Found virtual function at {:x}'.format(addr)
bv.add_function(bv.platform, addr)
fm.create_database(output_db)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment