예제 #1
0
for module in emulator.modules:
    logger.info("=> 0x%08x - %s" % (module.base, module.filename))

try:
    # Run JNI_OnLoad.
    #   JNI_OnLoad will call 'RegisterNatives'.
    emulator.call_symbol(lib_module, 'JNI_OnLoad',
                         emulator.java_vm.address_ptr, 0x00)

    # bypass douyin checks

    path = "vfs/system/bin/app_process32"
    sz = os.path.getsize(path)
    vf = VirtualFile("/system/bin/app_process32",
                     misc_utils.my_open(path, os.O_RDONLY), path)
    emulator.memory.map(0xab006000, sz, UC_PROT_WRITE | UC_PROT_READ, vf, 0)

    x = XGorgen()
    data = 'acde74a94e6b493a3399fac83c7c08b35D58B21D9582AF77647FC9902E36AE70f9c001e9334e6e94916682224fbe4e5f00000000000000000000000000000000'
    data = bytearray(bytes.fromhex(data))
    arr = Array("B", data)
    result = x.leviathan(emulator, 1562848170, arr)

    print(''.join(['%02x' % b for b in result]))

    # 037d560d0000903e34fb093f1d21e78f3bdf3fbebe00b124becc
    # 036d2a7b000010f4d05395b7df8b0ec2b5ec085b938a473a6a51
    # 036d2a7b000010f4d05395b7df8b0ec2b5ec085b938a473a6a51

    # 0300000000002034d288fe8d6b95b778105cc36eade709d2b500
예제 #2
0
#lib_module = emulator.load_library("tests/bin/libcms1050.so")
# lib_module = emulator.load_library("../deobf/tests/bin/libcms2.so")
# lib_module = emulator.load_library("../deobf/cms.so")

# Show loaded modules.
logger.info("Loaded modules:")

for module in emulator.modules:
    logger.info("=> 0x%08x - %s" % (module.base, module.filename))

try:
    # bypass douyin checks

    path = "vfs/system/bin/app_process32"
    sz = os.path.getsize(path)
    vf = VirtualFile("/system/bin/app_process32", misc_utils.my_open(path, os.O_RDONLY), path)
    emulator.memory.map(0xab006000, sz, UC_PROT_WRITE | UC_PROT_READ, vf, 0)

    # Run JNI_OnLoad.
    #   JNI_OnLoad will call 'RegisterNatives'.
    emulator.call_symbol(lib_module, 'JNI_OnLoad', emulator.java_vm.address_ptr, 0x00)


    #8.5 xg基本检测流程
    #1.调用meta,传入以下参数,如果不调用meta,leviathan将会返回null,meta的参数直接影响leviathan的结果
    print("begin meta")
    
    XGorgen.meta(emulator, 101, 0, String("0"))
    XGorgen.meta(emulator, 102, 0, String("1128"))
    XGorgen.meta(emulator, 1020, 0, String(""))
예제 #3
0
def sgmain_init(emulator):

    # Register Java class.
    emulator.java_classloader.add_class(HttpUtil)
    emulator.java_classloader.add_class(UmidAdapter)
    emulator.java_classloader.add_class(JNICLibrary)
    emulator.java_classloader.add_class(SPUtility2)
    emulator.java_classloader.add_class(DeviceInfoCapturer)

    emulator.java_classloader.add_class(DataReportJniBridge)

    emulator.java_classloader.add_class(ZipUtils)

    emulator.java_classloader.add_class(CallbackHelper)

    emulator.java_classloader.add_class(UserTrackMethodJniBridge)
    emulator.java_classloader.add_class(UMIDComponent)
    emulator.java_classloader.add_class(ECMiscInfo)
    emulator.java_classloader.add_class(MainApplication)
    emulator.java_classloader.add_class(JNIBridge)
    emulator.java_classloader.add_class(SecException)
    emulator.java_classloader.add_class(SGPluginExtras)
    emulator.java_classloader.add_class(MalDetect)
    emulator.java_classloader.add_class(NativeReflectUtils)
    emulator.java_classloader.add_class(SDKUtils)

    emulator.java_classloader.add_class(MiuiAd)
    emulator.java_classloader.add_class(TelephonyManagerEx)
    emulator.java_classloader.add_class(FtTelephonyAdapter)
    emulator.java_classloader.add_class(FtTelephony)
    emulator.java_classloader.add_class(FtDeviceInfo)
    emulator.java_classloader.add_class(ColorOSTelephonyManager)

    #map [vectors]
    path = "vfs/system/lib/vectors"
    vf = VirtualFile("[vectors]", misc_utils.my_open(path, os.O_RDONLY), path)
    emulator.memory.map(0xffff0000, 0x1000, UC_PROT_EXEC | UC_PROT_READ, vf, 0)

    # Load all libraries.
    lib_module = emulator.load_library(
        "vfs/data/data/fm.xiami.main/lib/libsgmainso-6.4.163.so")
    lib_module_secbody = emulator.load_library(
        "vfs/data/data/fm.xiami.main/lib/libsgsecuritybodyso-6.4.95.so")
    lib_module_avmp = emulator.load_library(
        "vfs/data/data/fm.xiami.main/lib/libsgavmpso-6.4.35.so")

    # Show loaded modules.
    logger.info("Loaded modules:")

    for module in emulator.modules:
        logger.info("=> 0x%08x - %s" % (module.base, module.filename))
    #

    act_thread = ActivityThread()
    app = act_thread.currentApplication(emulator)

    emulator.call_symbol(lib_module, 'JNI_OnLoad',
                         emulator.java_vm.address_ptr, 0x00)

    #10101 10102 sgmain
    o2 = Integer(1)
    o3 = String("")
    o4 = String("/data/data/fm.xiami.main/app_SGLib")
    o5 = String("")
    pyarr = [app, o2, o3, o4, o5]
    arr = Array(pyarr)
    #print(arr)

    JNICLibrary.doCommandNative(emulator, 10101, arr)

    o1 = String("main")
    o2 = String("6.4.163")
    o3 = String("/data/data/fm.xiami.main/lib/libsgmainso-6.4.163.so")

    print("begin 10102")
    arr = Array([o1, o2, o3])
    JNICLibrary.doCommandNative(emulator, 10102, arr)

    #10102 secbody
    print("secbody JNI_OnLoad")
    emulator.call_symbol(lib_module_secbody, 'JNI_OnLoad',
                         emulator.java_vm.address_ptr, 0x00)

    o1 = String("securitybody")
    o2 = String("6.4.95")
    o3 = String("/data/data/fm.xiami.main/lib/libsgsecuritybodyso-6.4.95.so")

    print("begin securitybodyso 10102")
    arr = Array([o1, o2, o3])
    JNICLibrary.doCommandNative(emulator, 10102, arr)

    #10102 avmp
    emulator.call_symbol(lib_module_avmp, 'JNI_OnLoad',
                         emulator.java_vm.address_ptr, 0x00)

    o1 = String("avmp")
    o2 = String("6.4.35")
    o3 = String("/data/data/fm.xiami.main/lib/libsgavmpso-6.4.35.so")

    print("begin avmp 10102")
    arr = Array([o1, o2, o3])
    JNICLibrary.doCommandNative(emulator, 10102, arr)
예제 #4
0
    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
예제 #5
0
    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
emulator.java_classloader.add_class(JNIBridge)
emulator.java_classloader.add_class(SecException)
emulator.java_classloader.add_class(SGPluginExtras)
emulator.java_classloader.add_class(MalDetect)
emulator.java_classloader.add_class(NativeReflectUtils)
emulator.java_classloader.add_class(SDKUtils)

emulator.java_classloader.add_class(MiuiAd)
emulator.java_classloader.add_class(TelephonyManagerEx)
emulator.java_classloader.add_class(FtTelephonyAdapter)
emulator.java_classloader.add_class(FtTelephony)
emulator.java_classloader.add_class(FtDeviceInfo)
emulator.java_classloader.add_class(ColorOSTelephonyManager)

path = "vfs/system/lib/vectors"
vf = VirtualFile("[vectors]", misc_utils.my_open(path, os.O_RDONLY), path)
emulator.memory.map(0xffff0000, 0x1000, UC_PROT_EXEC | UC_PROT_READ, vf, 0)

# Load all libraries.
lib_module = emulator.load_library(
    "vfs/data/data/fm.xiami.main/lib/libsgmainso-6.4.163.so")
lib_module_secbody = emulator.load_library(
    "vfs/data/data/fm.xiami.main/lib/libsgsecuritybodyso-6.4.95.so")
lib_module_avmp = emulator.load_library(
    "vfs/data/data/fm.xiami.main/lib/libsgavmpso-6.4.35.so")

#androidemu.utils.debug_utils.dump_symbols(emulator, sys.stdout)

# Show loaded modules.
logger.info("Loaded modules:")