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 has_got_seg_in_data_refs(refs): # filter out data not referenced by GOT return '.got' in [ida.seg_name(x) for x in refs] def get_refs_and_ea((_, ea)): return (ida.data_refs_to(ea), ea) refs_eas = imap(get_refs_and_ea, ida.ea_list_from_segs(segs)) data = list(get_tinfo_and_declstr(ea) for (refs, ea) in refs_eas if has_got_seg_in_data_refs(refs)) declstrs = '\n'.join([x[2] for x in data]) decls = izip(data, cdecl.get_decls(declstrs, cpp_in).decls[utils.cpp_decomp_tag]) return map(gen, decls) def get_fns_and_types(segs, wanted_fns, cpp_in): '''[str] -> [str] -> str -> ([c_ast], [c_ast])''' # NOTE mutates, because... # # IDA will always give us demangled names in type signatures, so we have to # replace the name in the returned decl with the mangled name def get_wanted(l, (name, decl)): return l + [decl] if name in wanted_fns else l def get_name_type((name, ea)): return (name, ida.print_type2(ea)) fns = reduce(get_wanted,