def get_data(segs, cpp_in): '''[str] -> str -> [c_ast]''' def gen(((ti, ea, declstr), node)): '''(tinfo_t, ea_t) -> c_ast''' # NOTE mutates node has_data = ida.seg_name(ea) != '.bss' ptr = ida.can_be_off32(ea) if ptr not in [ida.BADADDR, 0]: ptr_ti = ida.get_or_guess_tinfo(ptr) ti_node = cdecl.get_decls(declstr).decls[utils.cpp_decomp_tag][0] return gen(((ptr_ti, ptr, ''), ti_node)) # XXX our data segment has no strings, but that's probably specific to # the one binary we're dealing with elif ti.is_array(): ai = ida.array_type_data_t() ti.get_array_details(ai) item_size = ai.elem_type.get_size() typename = get_type_for_c_ast_constant(ai.elem_type) length = (ida.item_end(ea) - ida.item_head(ea)) / item_size if has_data is True: if ai.elem_type.is_char(): node.init = ep_ct.constant(typename, c_stringify( ida.get_string(ea))) else: items = list(get_item(ea + j * item_size, ti) for j in xrange(0, length)) node.init = ep_ct.initlist( [ep_ct.constant(typename, str(x)) for x in items]) else: if has_data is True: typename = get_type_for_c_ast_constant(ti) node.init = ep_ct.constant(typename, str(get_item(ea, ti))) return node
def get_item(ea, ti): '''ea_t -> tinfo_t -> c.types obj | int | str''' if ti.is_array(): ai = ida.array_details(ti) if ai.elem_type.is_char(): return ida.get_string(ea) else: sz = ai.elem_type.get_size() ret = get_one_item(ea, ai.elem_type, sz) return ret else: sz = ida.size_of(ti) return get_one_item(ea, ti, sz)
def get_arg_for_va_function(callee, start_ea): '''str -> ea_t -> str''' # XXX hacky; not a very general function # XXX imperative # get a relevant item needed for processing a variadic function sw = { 'printf' : regs.gpr(abi.arg_regs[0]), 'scanf' : regs.gpr(abi.arg_regs[0]), 'sscanf' : regs.gpr(abi.arg_regs[1]) } try: wanted_reg = sw[callee] except KeyError: raise utils.BugError('unrecognized callee %s' % callee) distance = 0 fn = ida.get_func(start_ea) # first, look at the delay slot ea = ida.next_head(start_ea, fn.endEA) while True: if distance > 10: raise VarargsError( 'gave up looking for needed varargs argument for %s between ' + '%s..%s' % (ida.atoa(ea), ida.atoa(start_ea))) if ea == start_ea: ea = ida.prev_head(ea) continue # skip the call insn elif list(ida.code_refs_from(ea, 0)) != []: raise VarargsError( 'encountered branch/jump while looking for varargs argument ' + 'between %s..%s' % (ida.atoa(ea), ida.atoa(start_ea))) rd = ida.get_op(ea, 0) if rd.val == wanted_reg: opvals = ida.get_opvals(ea) # XXX should try to track stkvar values s = ida.get_string(opvals[-1].target) if s is not None: return s ea = ida.prev_head(ea) distance += 1
def get_arg_for_va_function(callee, start_ea): """str -> ea_t -> str""" # XXX hacky; not a very general function # XXX imperative # get a relevant item needed for processing a variadic function sw = {"printf": regs.gpr(abi.arg_regs[0]), "scanf": regs.gpr(abi.arg_regs[0]), "sscanf": regs.gpr(abi.arg_regs[1])} try: wanted_reg = sw[callee] except KeyError: raise utils.BugError("unrecognized callee %s" % callee) distance = 0 fn = ida.get_func(start_ea) # first, look at the delay slot ea = ida.next_head(start_ea, fn.endEA) while True: if distance > 10: raise VarargsError( "gave up looking for needed varargs argument for %s between " + "%s..%s" % (ida.atoa(ea), ida.atoa(start_ea)) ) if ea == start_ea: ea = ida.prev_head(ea) continue # skip the call insn elif list(ida.code_refs_from(ea, 0)) != []: raise VarargsError( "encountered branch/jump while looking for varargs argument " + "between %s..%s" % (ida.atoa(ea), ida.atoa(start_ea)) ) rd = ida.get_op(ea, 0) if rd.val == wanted_reg: opvals = ida.get_opvals(ea) # XXX should try to track stkvar values s = ida.get_string(opvals[-1].target) if s is not None: return s ea = ida.prev_head(ea) distance += 1