ida is so broken

This commit is contained in:
George Hotz 2014-09-19 13:59:57 -04:00
parent d2f08a081f
commit 55682e8f61
4 changed files with 69 additions and 49 deletions

View File

@ -26,4 +26,3 @@ WITH_CAPSTONE = False
WITH_IDA = False WITH_IDA = False

View File

@ -33,6 +33,19 @@ if qira_config.WITH_IDA:
# function stack frames # function stack frames
# decompilation # decompilation
# *** NEWER STATIC FUNCTIONS USE IDA AS STATIC BACKEND ***
def get_static_bytes(addr, llen, numlist=False):
try:
ret = elf_dat[addr-load_addr:addr-load_addr+program.tags[addr]['len']]
if numlist:
return map(ord, list(ret))
else:
return ret
except:
return None
# input is a list of addresses, output is a dictionary names if they exist # input is a list of addresses, output is a dictionary names if they exist
@socketio.on('getnames', namespace='/qira') @socketio.on('getnames', namespace='/qira')
@socket_method @socket_method
@ -40,9 +53,10 @@ def getnames(addrs):
ret = {} ret = {}
for i in addrs: for i in addrs:
i = fhex(i) i = fhex(i)
if qira_config.WITH_IDA: # this is slow
if False and qira_config.WITH_IDA:
name = ida.get_name(i) name = ida.get_name(i)
print i, name #print i, name
if name != None: if name != None:
ret[ghex(i)] = name ret[ghex(i)] = name
else: else:
@ -53,7 +67,7 @@ def getnames(addrs):
@socketio.on('gotoname', namespace='/qira') @socketio.on('gotoname', namespace='/qira')
@socket_method @socket_method
def gotoname(name): def gotoname(name):
if qira_config.WITH_IDA: if False and qira_config.WITH_IDA:
ea = ida.get_name_ea(name) ea = ida.get_name_ea(name)
if ea != None: if ea != None:
emit('setiaddr', ghex(ea)) emit('setiaddr', ghex(ea))
@ -80,6 +94,11 @@ def settags(tags):
program.tags[naddr][i] = tags[addr][i] program.tags[naddr][i] = tags[addr][i]
print hex(naddr), i, program.tags[naddr][i] print hex(naddr), i, program.tags[naddr][i]
@socketio.on('getstaticview', namespace='/qira')
@socket_method
def getstaticview(haddr, flat, flatrange):
addr = fhex(haddr)
# *** OLDER, LESS SUPPORTED STATIC FUNCTIONS *** # *** OLDER, LESS SUPPORTED STATIC FUNCTIONS ***
@app.route('/gettagsa', methods=["POST"]) @app.route('/gettagsa', methods=["POST"])
@ -126,24 +145,29 @@ def getstaticview(haddr, flat, flatrange):
if 'len' in program.tags[i-j] and program.tags[i-j]['len'] == j: if 'len' in program.tags[i-j] and program.tags[i-j]['len'] == j:
i -= j i -= j
program.tags[i]['address'] = ghex(i) program.tags[i]['address'] = ghex(i)
program.tags[i]['bytes'] = get_static_bytes(i, j, True)
ret.append(program.tags[i]) ret.append(program.tags[i])
did_append = True did_append = True
break break
if not did_append: if not did_append:
i -= 1 i -= 1
program.tags[i]['address'] = ghex(i) program.tags[i]['address'] = ghex(i)
program.tags[i]['bytes'] = get_static_bytes(i, 1, True)
ret.append(program.tags[i]) ret.append(program.tags[i])
ret = ret[::-1] ret = ret[::-1]
# find forward # find forward
i = addr i = addr
while len(ret) != abs(flatrange[0]) + flatrange[1]: while len(ret) != abs(flatrange[0]) + flatrange[1]:
program.tags[i]['address'] = ghex(i) program.tags[i]['address'] = ghex(i)
ret.append(program.tags[i])
#print program.tags[i] #print program.tags[i]
if 'len' in program.tags[i]: if 'len' in program.tags[i]:
program.tags[i]['bytes'] = get_static_bytes(i, program.tags[i]['len'], True)
i += program.tags[i]['len'] i += program.tags[i]['len']
else: else:
program.tags[i]['bytes'] = get_static_bytes(i, 1, True)
i += 1 i += 1
ret.append(program.tags[i])
emit('tags', ret, False) emit('tags', ret, False)
else: else:
# function # function
@ -170,12 +194,22 @@ def init_static(lprogram):
global program global program
program = lprogram program = lprogram
if qira_config.WITH_IDA: if qira_config.WITH_IDA:
ida.init_with_program(program) ida.init_with_binary(program.program)
tags = ida.fetch_tags()
print "*** ida returned %d tags" % (len(tags))
# grr, copied from settags, merge into tags
for addr in tags:
for i in tags[addr]:
program.tags[addr][i] = tags[addr][i]
# as a hack, we can assume it's loading at 0x8048000 # as a hack, we can assume it's loading at 0x8048000
# forget sections for now # forget sections for now
# we really need to add a static memory repo # we really need to add a static memory repo
dat = open(program.program, "rb").read() global elf_dat, load_addr
elf_dat = open(program.program, "rb").read()
load_addr = 0x8048000 load_addr = 0x8048000
# generate the static data for the instruction # generate the static data for the instruction
@ -183,7 +217,7 @@ def init_static(lprogram):
for addr in program.tags: for addr in program.tags:
if 'flags' in program.tags[addr] and program.tags[addr]['flags']&0x600 == 0x600: if 'flags' in program.tags[addr] and program.tags[addr]['flags']&0x600 == 0x600:
# the question here is where do we get the instruction bytes? # the question here is where do we get the instruction bytes?
raw = dat[addr-load_addr:addr-load_addr+program.tags[addr]['len']] raw = get_static_bytes(addr, program.tags[addr]['len'])
# capinstruction, bap # capinstruction, bap
program.tags[addr]['capinstruction'] = program.disasm(raw, addr) program.tags[addr]['capinstruction'] = program.disasm(raw, addr)
#print hex(addr), self.tags[addr]['len'], self.tags[addr]['capinstruction'] #print hex(addr), self.tags[addr]['len'], self.tags[addr]['capinstruction']

View File

@ -134,26 +134,25 @@ def fetch_tags():
for i in range(0, ida.get_nlist_size()): for i in range(0, ida.get_nlist_size()):
ea = ida.get_nlist_ea(i) ea = ida.get_nlist_ea(i)
name = cast(ida.get_nlist_name(i), c_char_p).value.strip() name = c_char_p(ida.get_nlist_name(i)).value.strip()
#print hex(ea), name #print hex(ea), name
tags[ghex(ea)]['name'] = name tags[ea]['name'] = name
def parse_addr(i): def parse_addr(i):
flags = ida.get_flags_ex(i, 0) flags = ida.get_flags_ex(i, 0)
# is code # is code
if (flags&0x600) == 0x600: if (flags&0x600) == 0x600:
#print ghex(i) print ghex(i)
tags[ghex(i)]['flags'] = flags tags[i]['flags'] = flags
tags[ghex(i)]['flow'] = [] tags[i]['flow'] = []
tags[ghex(i)]['semantics'] = [] tags[i]['semantics'] = []
tags[i]['len'] = ida.decode_insn(i)
if ida.is_call_insn(i): if ida.is_call_insn(i):
tags[ghex(i)]['semantics'].append("call") tags[i]['semantics'].append("call")
if ida.is_ret_insn(i, 1): if ida.is_ret_insn(i, 1):
tags[ghex(i)]['semantics'].append("ret") tags[i]['semantics'].append("ret")
tags[ghex(i)]['len'] = ida.decode_insn(i)
#print ghex(i), ida.is_basic_block_end(0)
if ida.is_basic_block_end(0): if ida.is_basic_block_end(0):
tags[ghex(i)]['semantics'].append("endbb") tags[i]['semantics'].append("endbb")
#print ghex(i), tags[ghex(i)]['len'] #print ghex(i), tags[ghex(i)]['len']
return flags return flags
@ -169,7 +168,7 @@ def fetch_tags():
#print i #print i
fxn = cast(ida.getn_func(i), POINTER(c_long)) fxn = cast(ida.getn_func(i), POINTER(c_long))
fxn = [fxn[0], fxn[1]] fxn = [fxn[0], fxn[1]]
tags[ghex(fxn[0])]['funclength'] = fxn[1]-fxn[0] tags[fxn[0]]['funclength'] = fxn[1]-fxn[0]
#print hex(fxn[0]), hex(fxn[1]) #print hex(fxn[0]), hex(fxn[1])
# get the flags for each address in the function # get the flags for each address in the function
@ -178,11 +177,11 @@ def fetch_tags():
#flags = parse_addr(i) #flags = parse_addr(i)
flags = ida.get_flags_ex(i, 0) flags = ida.get_flags_ex(i, 0)
if (flags&0x600) == 0x600: if (flags&0x600) == 0x600:
tags[ghex(i)]['scope'] = ghex(fxn[0]) tags[i]['scope'] = ghex(fxn[0])
cref = ida.get_first_fcref_from(i) cref = ida.get_first_fcref_from(i)
while cref != -1: while cref != -1:
if cref >= fxn[0] and cref < fxn[1]: if cref >= fxn[0] and cref < fxn[1]:
tags[ghex(i)]['flow'].append(ghex(cref)) tags[i]['flow'].append(ghex(cref))
#print " ",ghex(cref) #print " ",ghex(cref)
cref = ida.get_next_fcref_from(i, cref) cref = ida.get_next_fcref_from(i, cref)
@ -190,34 +189,34 @@ def fetch_tags():
def set_name(ea, name): def set_name(ea, name):
ida.set_name(ea, name, 0) ida.set_name(ea, create_string_buffer(name), 0)
def set_comment(ea, text): def set_comment(ea, text):
# all repeatable # all repeatable
ida.set_cmt(ea, text, 1) ida.set_cmt(ea, create_string_buffer(text), 1)
def get_name(ea): def get_name(ea):
# TODO(ryan): why do i have to malloc here?
tmp = libc.malloc(80) tmp = libc.malloc(80)
#tmp = create_string_buffer(80) #tmp = create_string_buffer(80)
ida.get_name.restype=c_char_p
ret = ida.get_name(BADADDR, ea, tmp, 80) ret = ida.get_name(BADADDR, ea, tmp, 80)
if ret != 0: if ret != None:
# TODO(ryan): wtf what's breaking here return ret
return "named"
#return cast(tmp, c_char_p).value
return None return None
def get_name_ea(name): def get_name_ea(name):
ea = ida.get_name_ea(BADADDR, name) ea = ida.get_name_ea(BADADDR, create_string_buffer(name))
if ea == BADADDR: if ea == BADADDR:
return None return None
return ea return ea
def init_with_program(program): def init_with_binary(filename):
global ida, libc, FILE global ida, libc, FILE
FILE = "/tmp/qida/ida_binary" FILE = "/tmp/qida/ida_binary"
os.system("rm -rf /tmp/qida; mkdir -p /tmp/qida") os.system("rm -rf /tmp/qida; mkdir -p /tmp/qida")
os.system("cp "+program.program+" "+FILE) os.system("cp "+filename+" "+FILE)
if sys.platform == 'darwin': if sys.platform == 'darwin':
ida = cdll.LoadLibrary(IDAPATH+"/libida.dylib") ida = cdll.LoadLibrary(IDAPATH+"/libida.dylib")
@ -240,15 +239,3 @@ def init_with_program(program):
print "*** ida.init_database", ida.init_database(argc, argv, pointer(newfile)) print "*** ida.init_database", ida.init_database(argc, argv, pointer(newfile))
run_ida() run_ida()
# *** REMOVE UNDER THIS LINE ***
tags = fetch_tags()
print "*** ida returned %d tags" % (len(tags))
# grr, copied from settags
for addr in tags:
naddr = fhex(addr)
for i in tags[addr]:
program.tags[naddr][i] = tags[addr][i]
#print hex(naddr), self.tags[naddr][i]

View File

@ -103,17 +103,17 @@ $(document).ready(function() {
}*/ }*/
}); });
$('body').on('mousewheel', '.flat', function(e) { $('body').on('mousewheel', '.flat', function(e) {
/*var cdr = $(".flat").children(); var cdr = $(".flat").children();
if (e.originalEvent.wheelDelta < 0) { if (e.originalEvent.wheelDelta < 0) {
Session.set('iaddr', get_address_from_class(cdr[16].childNodes[0])); Session.set('iview', get_address_from_class(cdr[16].childNodes[0]));
} else if (e.originalEvent.wheelDelta > 0) { } else if (e.originalEvent.wheelDelta > 0) {
Session.set('iaddr', get_address_from_class(cdr[14].childNodes[0])); Session.set('iview', get_address_from_class(cdr[14].childNodes[0]));
}*/ }
if (e.originalEvent.wheelDelta < 0) { /*if (e.originalEvent.wheelDelta < 0) {
Session.set('iview', bn_add(Session.get('iview'), -1)); Session.set('iview', bn_add(Session.get('iview'), -1));
} else if (e.originalEvent.wheelDelta > 0) { } else if (e.originalEvent.wheelDelta > 0) {
Session.set('iview', bn_add(Session.get('iview'), 1)); Session.set('iview', bn_add(Session.get('iview'), 1));
} }*/
}); });
$("#idump")[0].addEventListener("mousewheel", function(e) { $("#idump")[0].addEventListener("mousewheel", function(e) {
//p("idump mousewheel"); //p("idump mousewheel");