miasm.jitter.loader.elf module
import struct from collections import defaultdict from future.utils import viewitems from miasm.loader import cstruct from miasm.loader import * import miasm.loader.elf as elf_csts from miasm.jitter.csts import * from miasm.jitter.loader.utils import canon_libname_libfunc, libimp from miasm.core.utils import force_str, find_free_name from miasm.core.interval import interval import logging log = logging.getLogger('loader_elf') hnd = logging.StreamHandler() hnd.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s")) log.addHandler(hnd) log.setLevel(logging.CRITICAL) def get_import_address_elf(e): import2addr = defaultdict(set) for sh in e.sh: if not hasattr(sh, 'rel'): continue for k, v in viewitems(sh.rel): k = force_str(k) import2addr[('xxx', k)].add(v.offset) return import2addr def preload_elf(vm, e, runtime_lib, patch_vm_imp=True, loc_db=None): # XXX quick hack fa = get_import_address_elf(e) dyn_funcs = {} for (libname, libfunc), ads in viewitems(fa): # Quick hack - if a symbol is already known, do not stub it if loc_db and loc_db.get_name_location(libfunc) is not None: continue for ad in ads: ad_base_lib = runtime_lib.lib_get_add_base(libname) ad_libfunc = runtime_lib.lib_get_add_func(ad_base_lib, libfunc, ad) libname_s = canon_libname_libfunc(libname, libfunc) dyn_funcs[libname_s] = ad_libfunc if patch_vm_imp: log.debug('patch 0x%x 0x%x %s', ad, ad_libfunc, libfunc) set_endianness = { elf_csts.ELFDATA2MSB: ">", elf_csts.ELFDATA2LSB: "<", elf_csts.ELFDATANONE: "" }[e.sex] vm.set_mem(ad, struct.pack(set_endianness + cstruct.size2type[e.size], ad_libfunc)) return runtime_lib, dyn_funcs def fill_loc_db_with_symbols(elf, loc_db, base_addr=0): """Parse the miasm.loader's ELF @elf to extract symbols, and fill the LocationDB instance @loc_db with parsed symbols. The ELF is considered mapped at @base_addr @elf: miasm.loader's ELF instance @loc_db: LocationDB used to retrieve symbols'offset @base_addr: addr to reloc to (if any) """ # Get symbol sections symbol_sections = [] for section_header in elf.sh: if hasattr(section_header, 'symbols'): for name, sym in viewitems(section_header.symbols): name = force_str(name) if not name or sym.value == 0: continue if loc_db.get_offset_location(sym.value) is not None: continue name = find_free_name(loc_db, name) loc_key = loc_db.get_or_create_name_location(name) loc_db.set_location_offset(loc_key, sym.value) #loc_db.add_location(name, sym.value)#, strict=False) if hasattr(section_header, 'reltab'): for rel in section_header.reltab: if not rel.sym or rel.offset == 0: continue if loc_db.get_offset_location(sym.value) is not None: continue name = force_str(rel.sym) name = find_free_name(loc_db, name) loc_key = loc_db.get_or_create_name_location(name) loc_db.set_location_offset(loc_key, sym.value) #loc_db.add_location(name, rel.offset)#, strict=False) if hasattr(section_header, 'symtab'): log.debug("Find %d symbols in %r", len(section_header.symtab), section_header) symbol_sections.append(section_header) elif isinstance(section_header, ( elf_init.GNUVerDef, elf_init.GNUVerSym, elf_init.GNUVerNeed )): log.debug("Find GNU version related section, unsupported for now") for section in symbol_sections: for symbol_entry in section.symtab: # Here, the computation of vaddr assumes 'elf' is an executable or a # shared object file # For relocatable file, symbol_entry.value is an offset from the section # base -> not handled here st_bind = symbol_entry.info >> 4 st_type = symbol_entry.info & 0xF if st_type not in [ elf_csts.STT_NOTYPE, elf_csts.STT_OBJECT, elf_csts.STT_FUNC, elf_csts.STT_COMMON, elf_csts.STT_GNU_IFUNC, ]: # Ignore symbols useless in linking continue if st_bind == elf_csts.STB_GLOBAL: # Global symbol weak = False elif st_bind == elf_csts.STB_WEAK: # Weak symbol weak = True else: # Ignore local & others symbols continue absolute = False if symbol_entry.shndx == 0: # SHN_UNDEF continue elif symbol_entry.shndx == 0xfff1: # SHN_ABS absolute = True log.debug("Absolute symbol %r - %x", symbol_entry.name, symbol_entry.value) elif 0xff00 <= symbol_entry.shndx <= 0xffff: # Reserved index (between SHN_LORESERV and SHN_HIRESERVE) raise RuntimeError("Unsupported reserved index: %r" % symbol_entry) name = symbol_entry.name name = force_str(name) if name == "": # Ignore empty symbol log.debug("Empty symbol %r", symbol_entry) continue if absolute: vaddr = symbol_entry.value else: vaddr = symbol_entry.value + base_addr # 'weak' information is only used to force global symbols for now already_existing_loc = loc_db.get_name_location(name) if already_existing_loc is not None: if weak: # Weak symbol, this is ok to already exists, skip it continue else: # Global symbol, force it loc_db.remove_location_name(already_existing_loc, name) already_existing_off = loc_db.get_offset_location(vaddr) if already_existing_off is not None: loc_db.add_location_name(already_existing_off, name) else: loc_key = loc_db.add_location() loc_db.add_location_name(loc_key, name) loc_db.set_location_offset(loc_key, vaddr) def apply_reloc_x86(elf, vm, section, base_addr, loc_db): """Apply relocation for x86 ELF contained in the section @section @elf: miasm.loader's ELF instance @vm: VmMngr instance @section: elf's section containing relocation to perform @base_addr: addr to reloc to @loc_db: LocationDB used to retrieve symbols'offset """ if elf.size == 64: addr_writer = lambda vaddr, addr: vm.set_mem(vaddr, struct.pack("<Q", addr)) elif elf.size == 32: addr_writer = lambda vaddr, addr: vm.set_mem(vaddr, struct.pack("<I", addr)) else: raise ValueError("Unsupported elf size %d" % elf.size) symb_section = section.linksection for reloc in section.reltab: # Parse relocation info r_info = reloc.info if elf.size == 64: r_info_sym = (r_info >> 32) & 0xFFFFFFFF r_info_type = r_info & 0xFFFFFFFF elif elf.size == 32: r_info_sym = (r_info >> 8) & 0xFFFFFF r_info_type = r_info & 0xFF is_ifunc = False symbol_entry = None if r_info_sym > 0: symbol_entry = symb_section.symtab[r_info_sym] r_offset = reloc.offset r_addend = reloc.cstr.sym if (elf.size, reloc.type) in [ (64, elf_csts.R_X86_64_RELATIVE), (64, elf_csts.R_X86_64_IRELATIVE), (32, elf_csts.R_386_RELATIVE), (32, elf_csts.R_386_IRELATIVE), ]: # B + A addr = base_addr + r_addend where = base_addr + r_offset elif reloc.type == elf_csts.R_X86_64_64: # S + A addr_symb = loc_db.get_name_offset(symbol_entry.name) if addr_symb is None: log.warning("Unable to find symbol %r" % symbol_entry.name) continue addr = addr_symb + r_addend where = base_addr + r_offset elif (elf.size, reloc.type) in [ (64, elf_csts.R_X86_64_TPOFF64), (64, elf_csts.R_X86_64_DTPMOD64), (32, elf_csts.R_386_TLS_TPOFF), ]: # Thread dependent, ignore for now log.debug("Skip relocation TPOFF64 %r", reloc) continue elif (elf.size, reloc.type) in [ (64, elf_csts.R_X86_64_GLOB_DAT), (64, elf_csts.R_X86_64_JUMP_SLOT), (32, elf_csts.R_386_JMP_SLOT), (32, elf_csts.R_386_GLOB_DAT), ]: # S addr = loc_db.get_name_offset(symbol_entry.name) if addr is None: log.warning("Unable to find symbol %r" % symbol_entry.name) continue is_ifunc = symbol_entry.info & 0xF == elf_csts.STT_GNU_IFUNC where = base_addr + r_offset else: raise ValueError( "Unknown relocation type: %d (%r)" % (reloc.type, reloc) ) if is_ifunc: # Resolve at runtime - not implemented for now log.warning("Relocation for %r (at %x, currently pointing on %x) " "has to be resolved at runtime", name, where, sym_addr) continue log.debug("Write %x at %x", addr, where) addr_writer(where, addr) def vm_load_elf(vm, fdata, name="", base_addr=0, loc_db=None, apply_reloc=False, **kargs): """ Very dirty elf loader TODO XXX: implement real loader """ elf = elf_init.ELF(fdata, **kargs) i = interval() all_data = {} for p in elf.ph.phlist: if p.ph.type != elf_csts.PT_LOAD: continue log.debug( '0x%x 0x%x 0x%x 0x%x 0x%x', p.ph.vaddr, p.ph.memsz, p.ph.offset, p.ph.filesz, p.ph.type) data_o = elf._content[p.ph.offset:p.ph.offset + p.ph.filesz] addr_o = p.ph.vaddr + base_addr a_addr = addr_o & ~0xFFF b_addr = addr_o + max(p.ph.memsz, p.ph.filesz) b_addr = (b_addr + 0xFFF) & ~0xFFF all_data[addr_o] = data_o # -2: Trick to avoid merging 2 consecutive pages i += [(a_addr, b_addr - 2)] for a, b in i.intervals: vm.add_memory_page( a, PAGE_READ | PAGE_WRITE, b"\x00" * (b + 2 - a), repr(name) ) for r_vaddr, data in viewitems(all_data): vm.set_mem(r_vaddr, data) if loc_db is not None: fill_loc_db_with_symbols(elf, loc_db, base_addr) if apply_reloc: arch = guess_arch(elf) sections = [] for section in elf.sh: if not hasattr(section, 'reltab'): continue if isinstance(section, elf_init.RelATable): pass elif isinstance(section, elf_init.RelTable): if arch == "x86_64": log.warning("REL section should not happen in x86_64") else: raise RuntimeError("Unknown relocation section type: %r" % section) sections.append(section) for section in sections: if arch in ["x86_64", "x86_32"]: apply_reloc_x86(elf, vm, section, base_addr, loc_db) else: log.debug("Unsupported relocation for arch %r" % arch) return elf class libimp_elf(libimp): pass # machine, size, sex -> arch_name ELF_machine = {(elf_csts.EM_ARM, 32, elf_csts.ELFDATA2LSB): "arml", (elf_csts.EM_ARM, 32, elf_csts.ELFDATA2MSB): "armb", (elf_csts.EM_AARCH64, 64, elf_csts.ELFDATA2LSB): "aarch64l", (elf_csts.EM_AARCH64, 64, elf_csts.ELFDATA2MSB): "aarch64b", (elf_csts.EM_MIPS, 32, elf_csts.ELFDATA2MSB): "mips32b", (elf_csts.EM_MIPS, 32, elf_csts.ELFDATA2LSB): "mips32l", (elf_csts.EM_386, 32, elf_csts.ELFDATA2LSB): "x86_32", (elf_csts.EM_X86_64, 64, elf_csts.ELFDATA2LSB): "x86_64", (elf_csts.EM_SH, 32, elf_csts.ELFDATA2LSB): "sh4", (elf_csts.EM_PPC, 32, elf_csts.ELFDATA2MSB): "ppc32b", } def guess_arch(elf): """Return the architecture specified by the ELF container @elf. If unknown, return None""" return ELF_machine.get((elf.Ehdr.machine, elf.size, elf.sex), None)
Module variables
var BREAKPOINT_READ
var BREAKPOINT_WRITE
var ELF_machine
var EXCEPT_ACCESS_VIOL
var EXCEPT_BREAKPOINT_INTERN
var EXCEPT_BREAKPOINT_MEMORY
var EXCEPT_CODE_AUTOMOD
var EXCEPT_DIV_BY_ZERO
var EXCEPT_DO_NOT_UPDATE_PC
var EXCEPT_ILLEGAL_INSN
var EXCEPT_INT_1
var EXCEPT_INT_XX
var EXCEPT_NUM_UPDT_EIP
var EXCEPT_PRIV_INSN
var EXCEPT_SOFT_BP
var EXCEPT_SPR_ACCESS
var EXCEPT_SYSCALL
var EXCEPT_UNK_MNEMO
var PAGE_EXEC
var PAGE_READ
var PAGE_WRITE
var hnd
var log
Functions
def apply_reloc_x86(
elf, vm, section, base_addr, loc_db)
Apply relocation for x86 ELF contained in the section @section @elf: miasm.loader's ELF instance @vm: VmMngr instance @section: elf's section containing relocation to perform @base_addr: addr to reloc to @loc_db: LocationDB used to retrieve symbols'offset
def apply_reloc_x86(elf, vm, section, base_addr, loc_db): """Apply relocation for x86 ELF contained in the section @section @elf: miasm.loader's ELF instance @vm: VmMngr instance @section: elf's section containing relocation to perform @base_addr: addr to reloc to @loc_db: LocationDB used to retrieve symbols'offset """ if elf.size == 64: addr_writer = lambda vaddr, addr: vm.set_mem(vaddr, struct.pack("<Q", addr)) elif elf.size == 32: addr_writer = lambda vaddr, addr: vm.set_mem(vaddr, struct.pack("<I", addr)) else: raise ValueError("Unsupported elf size %d" % elf.size) symb_section = section.linksection for reloc in section.reltab: # Parse relocation info r_info = reloc.info if elf.size == 64: r_info_sym = (r_info >> 32) & 0xFFFFFFFF r_info_type = r_info & 0xFFFFFFFF elif elf.size == 32: r_info_sym = (r_info >> 8) & 0xFFFFFF r_info_type = r_info & 0xFF is_ifunc = False symbol_entry = None if r_info_sym > 0: symbol_entry = symb_section.symtab[r_info_sym] r_offset = reloc.offset r_addend = reloc.cstr.sym if (elf.size, reloc.type) in [ (64, elf_csts.R_X86_64_RELATIVE), (64, elf_csts.R_X86_64_IRELATIVE), (32, elf_csts.R_386_RELATIVE), (32, elf_csts.R_386_IRELATIVE), ]: # B + A addr = base_addr + r_addend where = base_addr + r_offset elif reloc.type == elf_csts.R_X86_64_64: # S + A addr_symb = loc_db.get_name_offset(symbol_entry.name) if addr_symb is None: log.warning("Unable to find symbol %r" % symbol_entry.name) continue addr = addr_symb + r_addend where = base_addr + r_offset elif (elf.size, reloc.type) in [ (64, elf_csts.R_X86_64_TPOFF64), (64, elf_csts.R_X86_64_DTPMOD64), (32, elf_csts.R_386_TLS_TPOFF), ]: # Thread dependent, ignore for now log.debug("Skip relocation TPOFF64 %r", reloc) continue elif (elf.size, reloc.type) in [ (64, elf_csts.R_X86_64_GLOB_DAT), (64, elf_csts.R_X86_64_JUMP_SLOT), (32, elf_csts.R_386_JMP_SLOT), (32, elf_csts.R_386_GLOB_DAT), ]: # S addr = loc_db.get_name_offset(symbol_entry.name) if addr is None: log.warning("Unable to find symbol %r" % symbol_entry.name) continue is_ifunc = symbol_entry.info & 0xF == elf_csts.STT_GNU_IFUNC where = base_addr + r_offset else: raise ValueError( "Unknown relocation type: %d (%r)" % (reloc.type, reloc) ) if is_ifunc: # Resolve at runtime - not implemented for now log.warning("Relocation for %r (at %x, currently pointing on %x) " "has to be resolved at runtime", name, where, sym_addr) continue log.debug("Write %x at %x", addr, where) addr_writer(where, addr)
def fill_loc_db_with_symbols(
elf, loc_db, base_addr=0)
Parse the miasm.loader's ELF @elf to extract symbols, and fill the LocationDB instance @loc_db with parsed symbols.
The ELF is considered mapped at @base_addr @elf: miasm.loader's ELF instance @loc_db: LocationDB used to retrieve symbols'offset @base_addr: addr to reloc to (if any)
def fill_loc_db_with_symbols(elf, loc_db, base_addr=0): """Parse the miasm.loader's ELF @elf to extract symbols, and fill the LocationDB instance @loc_db with parsed symbols. The ELF is considered mapped at @base_addr @elf: miasm.loader's ELF instance @loc_db: LocationDB used to retrieve symbols'offset @base_addr: addr to reloc to (if any) """ # Get symbol sections symbol_sections = [] for section_header in elf.sh: if hasattr(section_header, 'symbols'): for name, sym in viewitems(section_header.symbols): name = force_str(name) if not name or sym.value == 0: continue if loc_db.get_offset_location(sym.value) is not None: continue name = find_free_name(loc_db, name) loc_key = loc_db.get_or_create_name_location(name) loc_db.set_location_offset(loc_key, sym.value) #loc_db.add_location(name, sym.value)#, strict=False) if hasattr(section_header, 'reltab'): for rel in section_header.reltab: if not rel.sym or rel.offset == 0: continue if loc_db.get_offset_location(sym.value) is not None: continue name = force_str(rel.sym) name = find_free_name(loc_db, name) loc_key = loc_db.get_or_create_name_location(name) loc_db.set_location_offset(loc_key, sym.value) #loc_db.add_location(name, rel.offset)#, strict=False) if hasattr(section_header, 'symtab'): log.debug("Find %d symbols in %r", len(section_header.symtab), section_header) symbol_sections.append(section_header) elif isinstance(section_header, ( elf_init.GNUVerDef, elf_init.GNUVerSym, elf_init.GNUVerNeed )): log.debug("Find GNU version related section, unsupported for now") for section in symbol_sections: for symbol_entry in section.symtab: # Here, the computation of vaddr assumes 'elf' is an executable or a # shared object file # For relocatable file, symbol_entry.value is an offset from the section # base -> not handled here st_bind = symbol_entry.info >> 4 st_type = symbol_entry.info & 0xF if st_type not in [ elf_csts.STT_NOTYPE, elf_csts.STT_OBJECT, elf_csts.STT_FUNC, elf_csts.STT_COMMON, elf_csts.STT_GNU_IFUNC, ]: # Ignore symbols useless in linking continue if st_bind == elf_csts.STB_GLOBAL: # Global symbol weak = False elif st_bind == elf_csts.STB_WEAK: # Weak symbol weak = True else: # Ignore local & others symbols continue absolute = False if symbol_entry.shndx == 0: # SHN_UNDEF continue elif symbol_entry.shndx == 0xfff1: # SHN_ABS absolute = True log.debug("Absolute symbol %r - %x", symbol_entry.name, symbol_entry.value) elif 0xff00 <= symbol_entry.shndx <= 0xffff: # Reserved index (between SHN_LORESERV and SHN_HIRESERVE) raise RuntimeError("Unsupported reserved index: %r" % symbol_entry) name = symbol_entry.name name = force_str(name) if name == "": # Ignore empty symbol log.debug("Empty symbol %r", symbol_entry) continue if absolute: vaddr = symbol_entry.value else: vaddr = symbol_entry.value + base_addr # 'weak' information is only used to force global symbols for now already_existing_loc = loc_db.get_name_location(name) if already_existing_loc is not None: if weak: # Weak symbol, this is ok to already exists, skip it continue else: # Global symbol, force it loc_db.remove_location_name(already_existing_loc, name) already_existing_off = loc_db.get_offset_location(vaddr) if already_existing_off is not None: loc_db.add_location_name(already_existing_off, name) else: loc_key = loc_db.add_location() loc_db.add_location_name(loc_key, name) loc_db.set_location_offset(loc_key, vaddr)
def get_import_address_elf(
e)
def get_import_address_elf(e): import2addr = defaultdict(set) for sh in e.sh: if not hasattr(sh, 'rel'): continue for k, v in viewitems(sh.rel): k = force_str(k) import2addr[('xxx', k)].add(v.offset) return import2addr
def guess_arch(
elf)
Return the architecture specified by the ELF container @elf. If unknown, return None
def guess_arch(elf): """Return the architecture specified by the ELF container @elf. If unknown, return None""" return ELF_machine.get((elf.Ehdr.machine, elf.size, elf.sex), None)
def preload_elf(
vm, e, runtime_lib, patch_vm_imp=True, loc_db=None)
def preload_elf(vm, e, runtime_lib, patch_vm_imp=True, loc_db=None): # XXX quick hack fa = get_import_address_elf(e) dyn_funcs = {} for (libname, libfunc), ads in viewitems(fa): # Quick hack - if a symbol is already known, do not stub it if loc_db and loc_db.get_name_location(libfunc) is not None: continue for ad in ads: ad_base_lib = runtime_lib.lib_get_add_base(libname) ad_libfunc = runtime_lib.lib_get_add_func(ad_base_lib, libfunc, ad) libname_s = canon_libname_libfunc(libname, libfunc) dyn_funcs[libname_s] = ad_libfunc if patch_vm_imp: log.debug('patch 0x%x 0x%x %s', ad, ad_libfunc, libfunc) set_endianness = { elf_csts.ELFDATA2MSB: ">", elf_csts.ELFDATA2LSB: "<", elf_csts.ELFDATANONE: "" }[e.sex] vm.set_mem(ad, struct.pack(set_endianness + cstruct.size2type[e.size], ad_libfunc)) return runtime_lib, dyn_funcs
def vm_load_elf(
vm, fdata, name='', base_addr=0, loc_db=None, apply_reloc=False, **kargs)
Very dirty elf loader TODO XXX: implement real loader
def vm_load_elf(vm, fdata, name="", base_addr=0, loc_db=None, apply_reloc=False, **kargs): """ Very dirty elf loader TODO XXX: implement real loader """ elf = elf_init.ELF(fdata, **kargs) i = interval() all_data = {} for p in elf.ph.phlist: if p.ph.type != elf_csts.PT_LOAD: continue log.debug( '0x%x 0x%x 0x%x 0x%x 0x%x', p.ph.vaddr, p.ph.memsz, p.ph.offset, p.ph.filesz, p.ph.type) data_o = elf._content[p.ph.offset:p.ph.offset + p.ph.filesz] addr_o = p.ph.vaddr + base_addr a_addr = addr_o & ~0xFFF b_addr = addr_o + max(p.ph.memsz, p.ph.filesz) b_addr = (b_addr + 0xFFF) & ~0xFFF all_data[addr_o] = data_o # -2: Trick to avoid merging 2 consecutive pages i += [(a_addr, b_addr - 2)] for a, b in i.intervals: vm.add_memory_page( a, PAGE_READ | PAGE_WRITE, b"\x00" * (b + 2 - a), repr(name) ) for r_vaddr, data in viewitems(all_data): vm.set_mem(r_vaddr, data) if loc_db is not None: fill_loc_db_with_symbols(elf, loc_db, base_addr) if apply_reloc: arch = guess_arch(elf) sections = [] for section in elf.sh: if not hasattr(section, 'reltab'): continue if isinstance(section, elf_init.RelATable): pass elif isinstance(section, elf_init.RelTable): if arch == "x86_64": log.warning("REL section should not happen in x86_64") else: raise RuntimeError("Unknown relocation section type: %r" % section) sections.append(section) for section in sections: if arch in ["x86_64", "x86_32"]: apply_reloc_x86(elf, vm, section, base_addr, loc_db) else: log.debug("Unsupported relocation for arch %r" % arch) return elf
Classes
class libimp_elf
class libimp_elf(libimp): pass
Ancestors (in MRO)
- libimp_elf
- miasm.jitter.loader.utils.libimp
- builtins.object
Static methods
def __init__(
self, lib_base_ad=1896943616, **kargs)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, lib_base_ad=0x71111000, **kargs): self.name2off = {} self.libbase2lastad = {} self.libbase_ad = lib_base_ad self.lib_imp2ad = {} self.lib_imp2dstad = {} self.fad2cname = {} self.cname2addr = {} self.fad2info = {} self.all_exported_lib = [] self.fake_libs = set()
def check_dst_ad(
self)
def check_dst_ad(self): for ad in self.lib_imp2dstad: all_ads = sorted(viewvalues(self.lib_imp2dstad[ad])) for i, x in enumerate(all_ads[:-1]): if x is None or all_ads[i + 1] is None: return False if x + 4 != all_ads[i + 1]: return False return True
def lib_get_add_base(
self, name)
def lib_get_add_base(self, name): assert isinstance(name, basestring) name = name.lower().strip(' ') if not "." in name: log.warning('warning adding .dll to modulename') name += '.dll' log.warning(name) if name in self.name2off: ad = self.name2off[name] else: ad = self.libbase_ad log.warning("Create dummy entry for %r", name) self.fake_libs.add(name) self.name2off[name] = ad self.libbase2lastad[ad] = ad + 0x4 self.lib_imp2ad[ad] = {} self.lib_imp2dstad[ad] = {} self.libbase_ad += 0x1000 return ad
def lib_get_add_func(
self, libad, imp_ord_or_name, dst_ad=None)
def lib_get_add_func(self, libad, imp_ord_or_name, dst_ad=None): if not libad in viewvalues(self.name2off): raise ValueError('unknown lib base!', hex(libad)) # test if not ordinatl # if imp_ord_or_name >0x10000: # imp_ord_or_name = vm_get_str(imp_ord_or_name, 0x100) # imp_ord_or_name = imp_ord_or_name[:imp_ord_or_name.find('\x00')] #/!\ can have multiple dst ad if not imp_ord_or_name in self.lib_imp2dstad[libad]: self.lib_imp2dstad[libad][imp_ord_or_name] = set() if dst_ad is not None: self.lib_imp2dstad[libad][imp_ord_or_name].add(dst_ad) if imp_ord_or_name in self.lib_imp2ad[libad]: return self.lib_imp2ad[libad][imp_ord_or_name] log.debug('new imp %s %s' % (imp_ord_or_name, dst_ad)) ad = self.libbase2lastad[libad] self.libbase2lastad[libad] += 0x10 # arbitrary self.lib_imp2ad[libad][imp_ord_or_name] = ad name_inv = dict( (value, key) for key, value in viewitems(self.name2off) ) c_name = canon_libname_libfunc(name_inv[libad], imp_ord_or_name) self.fad2cname[ad] = c_name self.cname2addr[c_name] = ad self.fad2info[ad] = libad, imp_ord_or_name return ad