def load_module(self, filename): logger.debug("Loading module '%s'." % filename) with open(filename, 'rb') as fstream: elf = ELFFile(fstream) dynamic = elf.header.e_type == 'ET_DYN' if not dynamic: raise NotImplementedError( "Only ET_DYN is supported at the moment.") # Parse program header (Execution view). # - LOAD (determinate what parts of the ELF file get mapped into memory) load_segments = [ x for x in elf.iter_segments() if x.header.p_type == 'PT_LOAD' ] # Find bounds of the load segments. bound_low = 0 bound_high = 0 for segment in load_segments: if segment.header.p_memsz == 0: continue if bound_low > segment.header.p_vaddr: bound_low = segment.header.p_vaddr high = segment.header.p_vaddr + segment.header.p_memsz if bound_high < high: bound_high = high # Retrieve a base address for this module. load_base = self.emu.memory.mem_reserve(bound_high - bound_low) for segment in load_segments: prot = get_segment_protection(segment.header.p_flags) prot = prot if prot is not 0 else UC_PROT_ALL self.emu.memory.mem_map(load_base + segment.header.p_vaddr, segment.header.p_memsz, prot) self.emu.memory.mem_write(load_base + segment.header.p_vaddr, segment.data()) # Parse section header (Linking view). dynsym = elf.get_section_by_name(".dynsym") dynstr = elf.get_section_by_name(".dynstr") # Resolve all symbols. symbols_resolved = dict() for section in elf.iter_sections(): if not isinstance(section, SymbolTableSection): continue itersymbols = section.iter_symbols() next(itersymbols) # Skip first symbol which is always NULL. for symbol in itersymbols: symbol_address = self._elf_get_symval( elf, load_base, symbol) if symbol_address is not None: symbols_resolved[symbol.name] = SymbolResolved( symbol_address, symbol) # Relocate. for section in elf.iter_sections(): if not isinstance(section, RelocationSection): continue for rel in section.iter_relocations(): sym = dynsym.get_symbol(rel['r_info_sym']) sym_value = sym['st_value'] rel_addr = load_base + rel[ 'r_offset'] # Location where relocation should happen rel_info_type = rel['r_info_type'] # Relocation table for ARM if rel_info_type == arm.R_ARM_ABS32: # Create the new value. value = load_base + sym_value # Write the new value self.emu.mu.mem_write( rel_addr, value.to_bytes(4, byteorder='little')) elif rel_info_type == arm.R_ARM_GLOB_DAT or rel_info_type == arm.R_ARM_JUMP_SLOT: # Resolve the symbol. if sym.name in symbols_resolved: value = symbols_resolved[sym.name].address # Write the new value self.emu.mu.mem_write( rel_addr, value.to_bytes(4, byteorder='little')) elif rel_info_type == arm.R_ARM_RELATIVE: if sym_value == 0: # Load address at which it was linked originally. value_orig_bytes = self.emu.mu.mem_read( rel_addr, 4) value_orig = int.from_bytes(value_orig_bytes, byteorder='little') # Create the new value value = load_base + value_orig # Write the new value self.emu.mu.mem_write( rel_addr, value.to_bytes(4, byteorder='little')) else: raise NotImplementedError() else: logger.error("Unhandled relocation type %i." % rel_info_type) # Store information about loaded module. module = Module(filename, load_base, bound_high - bound_low, symbols_resolved) self.modules.append(module) return module
def load_module(self, filename, do_init=True): m = self.find_module_by_name(filename) if (m != None): return m # logger.debug("Loading module '%s'." % filename) #do sth like linker with open(filename, 'rb') as fstream: #TODO: load elf without Section Header,pyelftools do not support. reader = elf_reader.ELFReader(fstream) # Parse program header (Execution view). # - LOAD (determinate what parts of the ELF file get mapped into memory) load_segments = reader.get_load() # Find bounds of the load segments. bound_low = 0 bound_high = 0 for segment in load_segments: p_memsz = segment["p_memsz"] if p_memsz == 0: continue p_vaddr = segment["p_vaddr"] if bound_low > p_vaddr: bound_low = p_vaddr high = p_vaddr + p_memsz if bound_high < high: bound_high = high # # ''' // Segment addresses in memory. Elf32_Addr seg_start = phdr->p_vaddr + load_bias_; Elf32_Addr seg_end = seg_start + phdr->p_memsz; Elf32_Addr seg_page_start = PAGE_START(seg_start); Elf32_Addr seg_page_end = PAGE_END(seg_end); // File offsets. Elf32_Addr file_start = phdr->p_offset; Elf32_Addr file_end = file_start + phdr->p_filesz; Elf32_Addr seg_file_end = seg_start + phdr->p_filesz; Elf32_Addr file_page_start = PAGE_START(file_start); Elf32_Addr file_length = file_end - file_page_start; if (file_length != 0) { void* seg_addr = mmap((void*)seg_page_start, file_length, PFLAGS_TO_PROT(phdr->p_flags), MAP_FIXED|MAP_PRIVATE, fd_, file_page_start); ''' # Retrieve a base address for this module. load_base = self.mem_reserve(bound_low, bound_high) vf = VirtualFile( misc_utils.system_path_to_vfs_path(self.__vfs_root, filename), misc_utils.my_open(filename, os.O_RDONLY), filename) for segment in load_segments: p_flags = segment["p_flags"] prot = get_segment_protection(p_flags) prot = prot if prot is not 0 else UC_PROT_ALL p_vaddr = segment["p_vaddr"] seg_start = load_base + p_vaddr seg_page_start = page_start(seg_start) p_offset = segment["p_offset"] file_start = p_offset p_filesz = segment["p_filesz"] file_end = file_start + p_filesz file_page_start = page_start(file_start) file_length = file_end - file_page_start assert (file_length > 0) if (file_length > 0): self.emu.memory.map(seg_page_start, file_length, prot, vf, file_page_start) # p_memsz = segment["p_memsz"] seg_end = seg_start + p_memsz seg_page_end = page_end(seg_end) seg_file_end = seg_start + p_filesz seg_file_end = page_end(seg_file_end) ''' void* zeromap = mmap((void*)seg_file_end, seg_page_end - seg_file_end, PFLAGS_TO_PROT(phdr->p_flags), MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); ''' self.emu.memory.map(seg_file_end, seg_page_end - seg_file_end, prot) # # Find init array. init_array_offset, init_array_size = reader.get_init_array() init_array = [] init_offset = reader.get_init() so_needed = reader.get_so_need() for so_name in so_needed: path = misc_utils.vfs_path_to_system_path( self.__vfs_root, so_name) if (not os.path.exists(path)): logger.warn("%s needed by %s do not exist in vfs %s" % (so_name, filename, self.__vfs_root)) continue # libmod = self.load_module(path) # rels = reader.get_rels() symbols = reader.get_symbols() # Resolve all symbols. symbols_resolved = dict() for symbol in symbols: symbol_address = self._elf_get_symval(load_base, symbol) if symbol_address is not None: name = symbol["name"] symbols_resolved[name] = symbol_address # # # Relocate. for rel_name in rels: rel_tbl = rels[rel_name] for rel in rel_tbl: r_info_sym = rel["r_info_sym"] sym = symbols[r_info_sym] sym_value = sym['st_value'] rel_addr = load_base + rel[ 'r_offset'] # Location where relocation should happen rel_info_type = rel['r_info_type'] #print(filename) #print("%x"%rel_addr) # Relocation table for ARM sym_name = reader.get_dyn_string_by_rel_sym(r_info_sym) if rel_info_type == arm.R_ARM_ABS32: if sym_name in symbols_resolved: sym_addr = symbols_resolved[sym_name] value_orig_bytes = self.emu.mu.mem_read( rel_addr, 4) value_orig = int.from_bytes(value_orig_bytes, byteorder='little') #R_ARM_ABS32 how to relocate see android linker source code #*reinterpret_cast<Elf32_Addr*>(reloc) += sym_addr; value = sym_addr + value_orig # Write the new value #print(value) self.emu.mu.mem_write( rel_addr, value.to_bytes(4, byteorder='little')) # # elif rel_info_type in (arm.R_ARM_GLOB_DAT, arm.R_ARM_JUMP_SLOT, arm.R_AARCH64_GLOB_DAT, arm.R_AARCH64_JUMP_SLOT): # Resolve the symbol. #R_ARM_GLOB_DAT,R_ARM_JUMP_SLOT how to relocate see android linker source code #*reinterpret_cast<Elf32_Addr*>(reloc) = sym_addr; if sym_name in symbols_resolved: value = symbols_resolved[sym_name] # Write the new value #print(value) self.emu.mu.mem_write( rel_addr, value.to_bytes(4, byteorder='little')) # # elif rel_info_type in (arm.R_ARM_RELATIVE, arm.R_AARCH64_RELATIVE): if sym_value == 0: # Load address at which it was linked originally. value_orig_bytes = self.emu.mu.mem_read( rel_addr, 4) value_orig = int.from_bytes(value_orig_bytes, byteorder='little') # Create the new value value = load_base + value_orig #print(value) # Write the new value self.emu.mu.mem_write( rel_addr, value.to_bytes(4, byteorder='little')) else: raise NotImplementedError() else: logger.error("Unhandled relocation type %i." % rel_info_type) # # # if (init_offset != 0): init_array.appen(load_base + init_offset) # for _ in range(int(init_array_size / 4)): b = self.emu.mu.mem_read(load_base + init_array_offset, 4) fun_ptr = int.from_bytes(b, byteorder='little', signed=False) if (fun_ptr != 0): init_array.append(fun_ptr) # init_array_offset += 4 # # Store information about loaded module. module = Module(filename, load_base, bound_high - bound_low, symbols_resolved, init_array) self.modules.append(module) #TODO init tls like linker ''' void __libc_init_tls(KernelArgumentBlock& args) { __libc_auxv = args.auxv; unsigned stack_top = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE; unsigned stack_size = 128 * 1024; unsigned stack_bottom = stack_top - stack_size; static void* tls[BIONIC_TLS_SLOTS]; static pthread_internal_t thread; thread.tid = gettid(); thread.tls = tls; pthread_attr_init(&thread.attr); pthread_attr_setstack(&thread.attr, (void*) stack_bottom, stack_size); _init_thread(&thread, false); __init_tls(&thread); tls[TLS_SLOT_BIONIC_PREINIT] = &args; } ''' if do_init: ''' for r in self.emu.mu.mem_regions(): print("region begin :0x%08X end:0x%08X, prot:%d"%(r[0], r[1], r[2])) # ''' module.call_init(self.emu) # logger.info("finish load lib %s" % filename) return module
def load_module(self, filename): logger.debug("Loading module '%s'." % filename) with open(filename, 'rb') as fstream: elf = MyElffile(fstream) dynamic = elf.header.e_type == 'ET_DYN' if not dynamic: raise NotImplementedError( "Only ET_DYN is supported at the moment.") # Parse program header (Execution view). # - LOAD (determinate what parts of the ELF file get mapped into memory) load_segments = [ x for x in elf.iter_segments() if x.header.p_type == 'PT_LOAD' ] # Find bounds of the load segments. bound_low = 0 bound_high = 0 for segment in load_segments: if segment.header.p_memsz == 0: continue if bound_low > segment.header.p_vaddr: bound_low = segment.header.p_vaddr high = segment.header.p_vaddr + segment.header.p_memsz if bound_high < high: bound_high = high # Retrieve a base address for this module. load_base = self.emu.memory.mem_reserve(bound_high - bound_low) for segment in load_segments: #prot = get_segment_protection(segment.header.p_flags) #prot = prot if prot is not 0 else UC_PROT_ALL prot = UC_PROT_ALL self.emu.memory.mem_map(load_base + segment.header.p_vaddr, segment.header.p_memsz, prot) self.emu.memory.mem_write(load_base + segment.header.p_vaddr, segment.data()) rel_section = None for section in elf.iter_sections(): if not isinstance(section, RelocationSection): continue rel_section = section break #rel_section = elf.get_dynmic_rel() # Parse section header (Linking view). dynsym = elf.get_section_by_name(".dynsym") #dynsym = elf.get_dynmic_symbol() dynsym_off = 0 dynstr_off = 0 # Find init array. init_array_size = 0 init_array_offset = 0 init_array = [] for x in elf.iter_segments(): if x.header.p_type == "PT_DYNAMIC": try: for tag in x.iter_tags(): if tag.entry.d_tag == "DT_INIT_ARRAYSZ": init_array_size = tag.entry.d_val elif tag.entry.d_tag == "DT_INIT_ARRAY": init_array_offset = tag.entry.d_val elif tag.entry.d_tag == "DT_SYMTAB": dynsym_off = tag.entry.d_val elif tag.entry.d_tag == "DT_STRTAB": dynstr_off = tag.entry.d_val except UnicodeDecodeError: pass for _ in range(int(init_array_size / 4)): # covert va to file offset for seg in load_segments: if seg.header.p_vaddr <= init_array_offset < seg.header.p_vaddr + seg.header.p_memsz: init_array_foffset = init_array_offset - seg.header.p_vaddr + seg.header.p_offset fstream.seek(init_array_foffset) data = fstream.read(4) fun_ptr = struct.unpack('I', data)[0] if fun_ptr != 0: # fun_ptr += load_base init_array.append(fun_ptr + load_base) print("find init array for :%s %x" % (filename, fun_ptr)) else: # search in reloc for rel in rel_section.iter_relocations(): rel_info_type = rel['r_info_type'] rel_addr = rel['r_offset'] if rel_info_type == arm.R_ARM_ABS32 and rel_addr == init_array_offset: sym = dynsym.get_symbol(rel['r_info_sym']) sym_value = sym['st_value'] init_array.append(load_base + sym_value) #print ("find init array for :%s %x" % (filename, sym_value)) break init_array_offset += 4 # Resolve all symbols. symbols_resolved = dict() for section in elf.iter_sections(): if not isinstance(section, SymbolTableSection): continue itersymbols = section.iter_symbols() next(itersymbols) # Skip first symbol which is always NULL. for symbol in itersymbols: symbol_address = self._elf_get_symval( elf, load_base, symbol) if symbol_address is not None: symbols_resolved[symbol.name] = SymbolResolved( symbol_address, symbol) #print ("symbol:%s addr:%x" % (symbol.name, symbol_address)) # Relocate. for section in elf.iter_sections(): if not isinstance(section, RelocationSection): continue #for relsection in elf.get_dynmic_rel(): for rel in section.iter_relocations(): sym = dynsym.get_symbol(rel['r_info_sym']) sym_value = sym['st_value'] rel_addr = load_base + rel[ 'r_offset'] # Location where relocation should happen rel_info_type = rel['r_info_type'] # Relocation table for ARM if rel_info_type == arm.R_ARM_ABS32: # Create the new value. value = load_base + sym_value # Write the new value self.emu.mu.mem_write( rel_addr, value.to_bytes(4, byteorder='little')) elif rel_info_type == arm.R_ARM_GLOB_DAT or \ rel_info_type == arm.R_ARM_JUMP_SLOT or \ rel_info_type == arm.R_AARCH64_GLOB_DAT or \ rel_info_type == arm.R_AARCH64_JUMP_SLOT: # Resolve the symbol. if sym.name in symbols_resolved: value = symbols_resolved[sym.name].address # Write the new value self.emu.mu.mem_write( rel_addr, value.to_bytes(4, byteorder='little')) elif rel_info_type == arm.R_ARM_RELATIVE or \ rel_info_type == arm.R_AARCH64_RELATIVE: if sym_value == 0: # Load address at which it was linked originally. value_orig_bytes = self.emu.mu.mem_read( rel_addr, 4) value_orig = int.from_bytes(value_orig_bytes, byteorder='little') # Create the new value value = load_base + value_orig # Write the new value self.emu.mu.mem_write( rel_addr, value.to_bytes(4, byteorder='little')) else: raise NotImplementedError() else: logger.error("Unhandled relocation type %i." % rel_info_type) # Store information about loaded module. module = Module(filename, load_base, bound_high - bound_low, symbols_resolved, init_array) self.modules.append(module) #do init return module
def load_module(self, filename, do_init=True): m = self.find_module_by_name(filename) if (m != None): return m # logger.debug("Loading module '%s'." % filename) #do sth like linker with open(filename, 'rb') as fstream: #TODO: load elf without Section Header,pyelftools do not support. elf = ELFFile(fstream) dynamic = elf.header.e_type == 'ET_DYN' if not dynamic: raise NotImplementedError( "Only ET_DYN is supported at the moment.") # Parse program header (Execution view). # - LOAD (determinate what parts of the ELF file get mapped into memory) load_segments = [ x for x in elf.iter_segments() if x.header.p_type == 'PT_LOAD' ] # Find bounds of the load segments. bound_low = 0 bound_high = 0 for segment in load_segments: if segment.header.p_memsz == 0: continue if bound_low > segment.header.p_vaddr: bound_low = segment.header.p_vaddr high = segment.header.p_vaddr + segment.header.p_memsz if bound_high < high: bound_high = high ''' // Segment addresses in memory. Elf32_Addr seg_start = phdr->p_vaddr + load_bias_; Elf32_Addr seg_end = seg_start + phdr->p_memsz; Elf32_Addr seg_page_start = PAGE_START(seg_start); Elf32_Addr seg_page_end = PAGE_END(seg_end); // File offsets. Elf32_Addr file_start = phdr->p_offset; Elf32_Addr file_end = file_start + phdr->p_filesz; Elf32_Addr seg_file_end = seg_start + phdr->p_filesz; Elf32_Addr file_page_start = PAGE_START(file_start); Elf32_Addr file_length = file_end - file_page_start; if (file_length != 0) { void* seg_addr = mmap((void*)seg_page_start, file_length, PFLAGS_TO_PROT(phdr->p_flags), MAP_FIXED|MAP_PRIVATE, fd_, file_page_start); ''' # Retrieve a base address for this module. load_base = self.mem_reserve(bound_low, bound_high) vf = VirtualFile( misc_utils.system_path_to_vfs_path(self.__vfs_root, filename), misc_utils.my_open(filename, os.O_RDONLY), filename) for segment in load_segments: prot = get_segment_protection(segment.header.p_flags) prot = prot if prot is not 0 else UC_PROT_ALL #self.emu.memory.map(load_base + segment.header.p_vaddr, segment.header.p_memsz, prot) #self.emu.mu.mem_write(load_base + segment.header.p_vaddr, segment.data()) seg_start = load_base + segment.header.p_vaddr seg_page_start = page_start(seg_start) file_start = segment.header.p_offset file_end = file_start + segment.header.p_filesz file_page_start = page_start(file_start) file_length = file_end - file_page_start assert (file_length > 0) if (file_length > 0): self.emu.memory.map(seg_page_start, file_length, prot, vf, file_page_start) # seg_end = seg_start + segment.header.p_memsz seg_page_end = page_end(seg_end) seg_file_end = seg_start + segment.header.p_filesz seg_file_end = page_end(seg_file_end) ''' void* zeromap = mmap((void*)seg_file_end, seg_page_end - seg_file_end, PFLAGS_TO_PROT(phdr->p_flags), MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); ''' self.emu.memory.map(seg_file_end, seg_page_end - seg_file_end, prot) # # Find init array. init_array_size = 0 init_array_offset = 0 init_array = [] init_addr = 0 dynstr_addr = 0 dt_needed = [] for x in elf.iter_segments(): if x.header.p_type == "PT_DYNAMIC": for tag in x.iter_tags(): if tag.entry.d_tag == "DT_INIT_ARRAYSZ": init_array_size = tag.entry.d_val elif tag.entry.d_tag == "DT_INIT_ARRAY": init_array_offset = tag.entry.d_val elif tag.entry.d_tag == "DT_INIT": init_addr = tag.entry.d_val + load_base elif tag.entry.d_tag == "DT_STRTAB": dynstr_addr = tag.entry.d_val + load_base elif tag.entry.d_tag == "DT_NEEDED": dt_needed.append(tag.entry.d_val) # # break # # so_needed = [] for str_off in dt_needed: str_addr = dynstr_addr + str_off so_name = memory_helpers.read_utf8(self.emu.mu, str_addr) so_needed.append(so_name) # for so_name in so_needed: path = misc_utils.vfs_path_to_system_path( self.__vfs_root, so_name) if (not os.path.exists(path)): logger.warn("%s needed by %s do not exist in vfs %s" % (so_name, filename, self.__vfs_root)) continue # libmod = self.load_module(path) # rel_section = None for section in elf.iter_sections(): if not isinstance(section, RelocationSection): continue rel_section = section break # # Parse section header (Linking view). dynsym = elf.get_section_by_name(".dynsym") for _ in range(int(init_array_size / 4)): b = self.emu.mu.mem_read(load_base + init_array_offset, 4) fun_ptr = int.from_bytes(b, byteorder='little', signed=False) if fun_ptr != 0: # fun_ptr += load_base init_array.append(fun_ptr + load_base) # print ("find init array for :%s %x" % (filename, fun_ptr)) else: # search in reloc for rel in rel_section.iter_relocations(): rel_info_type = rel['r_info_type'] rel_addr = rel['r_offset'] if rel_info_type == arm.R_ARM_ABS32 and rel_addr == init_array_offset: sym = dynsym.get_symbol(rel['r_info_sym']) sym_value = sym['st_value'] init_array.append(load_base + sym_value) # print ("find init array for :%s %x" % (filename, sym_value)) break # # init_array_offset += 4 # Resolve all symbols. symbols_resolved = dict() for section in elf.iter_sections(): if not isinstance(section, SymbolTableSection): continue itersymbols = section.iter_symbols() next(itersymbols) # Skip first symbol which is always NULL. for symbol in itersymbols: symbol_address = self._elf_get_symval( elf, load_base, symbol) if symbol_address is not None: symbols_resolved[symbol.name] = SymbolResolved( symbol_address, symbol) # Relocate. for section in elf.iter_sections(): if not isinstance(section, RelocationSection): continue for rel in section.iter_relocations(): sym = dynsym.get_symbol(rel['r_info_sym']) sym_value = sym['st_value'] rel_addr = load_base + rel[ 'r_offset'] # Location where relocation should happen rel_info_type = rel['r_info_type'] #print(filename) #print("%x"%rel_addr) # Relocation table for ARM if rel_info_type == arm.R_ARM_ABS32: if sym.name in symbols_resolved: sym_addr = symbols_resolved[sym.name].address value_orig_bytes = self.emu.mu.mem_read( rel_addr, 4) value_orig = int.from_bytes(value_orig_bytes, byteorder='little') #R_ARM_ABS32 how to relocate see android linker source code #*reinterpret_cast<Elf32_Addr*>(reloc) += sym_addr; value = sym_addr + value_orig # Write the new value #print(value) self.emu.mu.mem_write( rel_addr, value.to_bytes(4, byteorder='little')) # # elif rel_info_type in (arm.R_ARM_GLOB_DAT, arm.R_ARM_JUMP_SLOT, arm.R_AARCH64_GLOB_DAT, arm.R_AARCH64_JUMP_SLOT): # Resolve the symbol. #R_ARM_GLOB_DAT,R_ARM_JUMP_SLOT how to relocate see android linker source code #*reinterpret_cast<Elf32_Addr*>(reloc) = sym_addr; if sym.name in symbols_resolved: value = symbols_resolved[sym.name].address # Write the new value #print(value) self.emu.mu.mem_write( rel_addr, value.to_bytes(4, byteorder='little')) # # elif rel_info_type in (arm.R_ARM_RELATIVE, arm.R_AARCH64_RELATIVE): if sym_value == 0: # Load address at which it was linked originally. value_orig_bytes = self.emu.mu.mem_read( rel_addr, 4) value_orig = int.from_bytes(value_orig_bytes, byteorder='little') # Create the new value value = load_base + value_orig #print(value) # Write the new value self.emu.mu.mem_write( rel_addr, value.to_bytes(4, byteorder='little')) else: raise NotImplementedError() else: logger.error("Unhandled relocation type %i." % rel_info_type) # # Store information about loaded module. module = Module(filename, load_base, bound_high - bound_low, symbols_resolved, init_addr, init_array) self.modules.append(module) #TODO init tls like linker ''' void __libc_init_tls(KernelArgumentBlock& args) { __libc_auxv = args.auxv; unsigned stack_top = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE; unsigned stack_size = 128 * 1024; unsigned stack_bottom = stack_top - stack_size; static void* tls[BIONIC_TLS_SLOTS]; static pthread_internal_t thread; thread.tid = gettid(); thread.tls = tls; pthread_attr_init(&thread.attr); pthread_attr_setstack(&thread.attr, (void*) stack_bottom, stack_size); _init_thread(&thread, false); __init_tls(&thread); tls[TLS_SLOT_BIONIC_PREINIT] = &args; } ''' if do_init: ''' for r in self.emu.mu.mem_regions(): print("region begin :0x%08X end:0x%08X, prot:%d"%(r[0], r[1], r[2])) # ''' module.call_init(self.emu) # logger.info("finish load lib %s" % filename) return module