import os | |
import sys | |
import struct | |
import binaryninja | |
def touch(fname, times=None): | |
with open(fname, 'a'): | |
os.utime(fname, times) | |
#------------------------------------------------------------------- | |
bv = binaryninja.BinaryViewType['ELF'].open(sys.argv[1]) | |
bv.update_analysis_and_wait() | |
symbols = [s.name.split('@')[0] for s in bv.get_symbols() if s.name.endswith('@GOT')] | |
symbols = filter(lambda x: not x in ['__gmon_start__', '__libc_start_main'], symbols) | |
def change_lib_call_mapping(mapping): | |
for k,v in mapping.items(): | |
ka = bv.get_symbols_by_name(k)[0].address | |
va = bv.get_symbols_by_name(v)[0].address | |
refs = bv.get_code_refs(ka) | |
for r in refs: | |
if bv.read(r.address, 1) == '\xe8': | |
nv = struct.pack('<i',va-(r.address+5)) | |
bv.write(r.address+1, nv) | |
def change_plt_mapping(mapping): | |
vals = {} | |
for v in mapping.values(): | |
a = bv.get_symbols_by_name(v+'@GOT')[0].address | |
plta = struct.unpack('<Q',bv.read(a,8))[0] | |
vals[v] = bv.read(plta, 5) | |
for k,v in mapping.items(): | |
a = bv.get_symbols_by_name(k+'@GOT')[0].address | |
plta = struct.unpack('<Q',bv.read(a,8))[0] | |
bv.write(plta, vals[v]) | |
# define the imported symbols to swap | |
mapping = \ | |
{ | |
'srand':'exit', | |
'exit':'srand' | |
} | |
# swap the symbols | |
change_lib_call_mapping(mapping) | |
change_plt_mapping(mapping) | |
# save the modified binary | |
patched_binary = sys.argv[1]+'_patched' | |
touch(patched_binary) | |
print bv.save(patched_binary) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment