All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.unidbg.ios.Dyld32 Maven / Gradle / Ivy

The newest version!
package com.github.unidbg.ios;

import com.github.unidbg.Emulator;
import com.github.unidbg.Module;
import com.github.unidbg.Symbol;
import com.github.unidbg.arm.ArmHook;
import com.github.unidbg.arm.ArmSvc;
import com.github.unidbg.arm.HookStatus;
import com.github.unidbg.arm.backend.Backend;
import com.github.unidbg.arm.context.Arm32RegisterContext;
import com.github.unidbg.arm.context.EditableArm32RegisterContext;
import com.github.unidbg.arm.context.RegisterContext;
import com.github.unidbg.memory.Memory;
import com.github.unidbg.memory.SvcMemory;
import com.github.unidbg.pointer.UnidbgPointer;
import com.github.unidbg.pointer.UnidbgStructure;
import com.github.unidbg.spi.InitFunction;
import com.github.unidbg.unix.struct.DlInfo32;
import com.sun.jna.Pointer;
import keystone.Keystone;
import keystone.KeystoneArchitecture;
import keystone.KeystoneEncoded;
import keystone.KeystoneMode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import unicorn.ArmConst;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Dyld32 extends Dyld {

    private static final Log log = LogFactory.getLog(Dyld32.class);

    Dyld32(final MachOLoader loader, final SvcMemory svcMemory) {
        super(svcMemory);

        __dyld_image_count = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                int ret = loader.getLoadedModulesNoVirtual().size();
                if (log.isDebugEnabled()) {
                    log.debug("__dyld_image_count size=" + ret);
                }
                return ret;
            }
        });
        __dyld_get_image_name = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                int image_index = emulator.getBackend().reg_read(ArmConst.UC_ARM_REG_R0).intValue();
                Module[] modules = loader.getLoadedModulesNoVirtual().toArray(new Module[0]);
                long ret;
                if (image_index < 0 || image_index >= modules.length) {
                    ret = 0;
                } else {
                    MachOModule module = (MachOModule) modules[image_index];
                    ret = module.createPathMemory(svcMemory).peer;
                }
                if (log.isDebugEnabled()) {
                    log.debug("__dyld_get_image_name ret=0x" + Long.toHexString(ret));
                }
                return ret;
            }
        });
        __dyld_get_image_header = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                int image_index = emulator.getBackend().reg_read(ArmConst.UC_ARM_REG_R0).intValue();
                Module[] modules = loader.getLoadedModulesNoVirtual().toArray(new Module[0]);
                long ret;
                if (image_index < 0 || image_index >= modules.length) {
                    ret = 0;
                } else {
                    MachOModule module = (MachOModule) modules[image_index];
                    ret = module.machHeader;
                }
                if (log.isDebugEnabled()) {
                    log.debug("__dyld_get_image_header machHeader=0x" + Long.toHexString(ret));
                }
                return ret;
            }
        });
        __dyld_get_image_vmaddr_slide = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                int image_index = emulator.getBackend().reg_read(ArmConst.UC_ARM_REG_R0).intValue();
                Module[] modules = loader.getLoadedModulesNoVirtual().toArray(new Module[0]);
                long ret;
                if (image_index < 0 || image_index >= modules.length) {
                    ret = 0;
                } else {
                    MachOModule module = (MachOModule) modules[image_index];
                    ret = computeSlide(emulator, module.machHeader);
                }
                log.debug("__dyld_get_image_vmaddr_slide index=" + image_index + ", ret=0x" + Long.toHexString(ret));
                return ret;
            }
        });
        __dyld_get_image_slide = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                UnidbgPointer mh = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_R0);
                if (log.isDebugEnabled()) {
                    log.debug("__dyld_get_image_slide mh=" + mh);
                }
                return mh == null ? 0 : computeSlide(emulator, mh.peer);
            }
        });

        /*
         * _dyld_register_func_for_add_image registers the specified function to be
         * called when a new image is added (a bundle or a dynamic shared library) to
         * the program.  When this function is first registered it is called for once
         * for each image that is currently part of the program.
         */
        __dyld_register_func_for_add_image = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public UnidbgPointer onRegister(SvcMemory svcMemory, int svcNumber) {
                try (Keystone keystone = new Keystone(KeystoneArchitecture.Arm, KeystoneMode.Arm)) {
                    KeystoneEncoded encoded = keystone.assemble(Arrays.asList(
                            "push {r4-r7, lr}",
                            "svc #0x" + Integer.toHexString(svcNumber),
                            "pop {r7}", // manipulated stack in dlopen
                            "cmp r7, #0",
                            "subne lr, pc, #16", // jump to pop {r7}
                            "popne {r0-r1}", // (headerType *mh, unsigned long	vmaddr_slide)
                            "bxne r7", // call init array
                            "pop {r0, r4-r7, pc}")); // with return address
                    byte[] code = encoded.getMachineCode();
                    UnidbgPointer pointer = svcMemory.allocate(code.length, "__dyld_register_func_for_add_image");
                    pointer.write(0, code, 0, code.length);
                    return pointer;
                }
            }

            @Override
            public long handle(Emulator emulator) {
                final Backend backend = emulator.getBackend();

                UnidbgPointer callback = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_R0);
                if (log.isDebugEnabled()) {
                    log.debug("__dyld_register_func_for_add_image callback=" + callback);
                }

                Pointer pointer = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_SP);
                try {
                    pointer = pointer.share(-4); // return value
                    pointer.setInt(0, 0);

                    pointer = pointer.share(-4); // NULL-terminated
                    pointer.setInt(0, 0);

                    if (callback != null && !loader.addImageCallbacks.contains(callback)) {
                        loader.addImageCallbacks.add(callback);

                        List modules = loader.getLoadedModulesNoVirtual();
                        Collections.reverse(modules);
                        for (Module md : modules) {
                            Log log = LogFactory.getLog("com.github.unidbg.ios." + md.name);
                            MachOModule mm = (MachOModule) md;
                            if (mm.executable) {
                                continue;
                            }
                            mm.addImageCallSet.add(callback);

                            // (headerType *mh, unsigned long	vmaddr_slide)
                            pointer = pointer.share(-4);
                            pointer.setInt(0, (int) mm.machHeader);
                            pointer = pointer.share(-4);
                            pointer.setInt(0, (int) computeSlide(emulator, mm.machHeader));

                            String str = "[" + md.name + "]PushAddImageFunction: 0x" + Long.toHexString(mm.machHeader);
                            if (log.isDebugEnabled()) {
                                log.debug(str);
                            } else if (Dyld32.log.isDebugEnabled()) {
                                Dyld32.log.debug(str);
                            }
                            pointer = pointer.share(-4); // callback
                            pointer.setPointer(0, callback);
                        }
                    }

                    return 0;
                } finally {
                    backend.reg_write(ArmConst.UC_ARM_REG_SP, ((UnidbgPointer) pointer).peer);
                }
            }
        });

        /*
         * _dyld_register_func_for_remove_image registers the specified function to be
         * called when an image is removed (a bundle or a dynamic shared library) from
         * the program.
         */
        __dyld_register_func_for_remove_image = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                Pointer callback = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_R0);
                if (log.isDebugEnabled()) {
                    log.debug("__dyld_register_func_for_remove_image callback=" + callback);
                }
                return 0;
            }
        });
        __dyld_register_thread_helpers = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                // the table passed to dyld containing thread helpers
                Pointer helpers = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_R0);
                if (log.isDebugEnabled()) {
                    log.debug("registerThreadHelpers helpers=" + helpers + ", version=" + helpers.getInt(0));
                }
                return 0;
            }
        });
        __dyld_dyld_register_image_state_change_handler = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public UnidbgPointer onRegister(SvcMemory svcMemory, int svcNumber) {
                try (Keystone keystone = new Keystone(KeystoneArchitecture.Arm, KeystoneMode.Arm)) {
                    KeystoneEncoded encoded = keystone.assemble(Arrays.asList(
                            "push {r4-r7, lr}",
                            "svc #0x" + Integer.toHexString(svcNumber),
                            "pop {r7}", // manipulated stack in dyld_image_state_change_handler
                            "cmp r7, #0",
                            "subne lr, pc, #16", // jump to pop {r7}
                            "popne {r0-r2}", // const char* (*dyld_image_state_change_handler)(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info info[])
                            "bxne r7", // call init array
                            "pop {r0, r4-r7, pc}")); // with return address
                    byte[] code = encoded.getMachineCode();
                    UnidbgPointer pointer = svcMemory.allocate(code.length, "dyld_image_state_change_handler");
                    pointer.write(0, code, 0, code.length);
                    return pointer;
                }
            }
            @Override
            public long handle(Emulator emulator) {
                Backend backend = emulator.getBackend();
                int state = backend.reg_read(ArmConst.UC_ARM_REG_R0).intValue();
                int batch = backend.reg_read(ArmConst.UC_ARM_REG_R1).intValue();
                UnidbgPointer handler = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_R2);
                UnidbgStructure[] imageInfos;
                if (batch == 1) {
                    imageInfos = registerImageStateBatchChangeHandler(loader, state, handler, emulator);
                } else {
                    imageInfos = registerImageStateSingleChangeHandler(loader, state, handler, emulator);
                }

                Pointer pointer = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_SP);
                try {
                    pointer = pointer.share(-4); // return value
                    pointer.setInt(0, 0);

                    pointer = pointer.share(-4); // NULL-terminated
                    pointer.setInt(0, 0);

                    if (handler != null && imageInfos != null) {
                        // (*dyld_image_state_change_handler)(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info info[])
                        pointer = pointer.share(-4);
                        pointer.setPointer(0, imageInfos.length == 0 ? null : imageInfos[0].getPointer());
                        pointer = pointer.share(-4);
                        pointer.setInt(0, imageInfos.length);
                        pointer = pointer.share(-4);
                        pointer.setInt(0, state);

                        if (log.isDebugEnabled()) {
                            log.debug("PushImageHandlerFunction: " + handler + ", imageSize=" + imageInfos.length + ", batch=" + batch);
                        }
                        pointer = pointer.share(-4); // handler
                        pointer.setPointer(0, handler);
                    }

                    return 0;
                } finally {
                    backend.reg_write(ArmConst.UC_ARM_REG_SP, ((UnidbgPointer) pointer).peer);
                }
            }
        });
        __dyld_image_path_containing_address = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                UnidbgPointer address = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_R0);
                MachOModule module = (MachOModule) loader.findModuleByAddress(address.peer);
                if (log.isDebugEnabled()) {
                    log.debug("__dyld_image_path_containing_address address=" + address + ", module=" + module);
                }
                if (module != null) {
                    return module.createPathMemory(svcMemory).peer;
                } else {
                    return 0;
                }
            }
        });
        __dyld__NSGetExecutablePath = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                RegisterContext context = emulator.getContext();
                Pointer buf = context.getPointerArg(0);
                Pointer bufSize = context.getPointerArg(1);
                if (log.isDebugEnabled()) {
                    log.debug("__dyld__NSGetExecutablePath buf=" + buf + ", bufSize=" + bufSize);
                }
                byte[] str = emulator.getProcessName().getBytes(StandardCharsets.UTF_8);
                byte[] data = Arrays.copyOf(str, str.length + 1);
                if (bufSize.getInt(0) >= data.length) {
                    buf.write(0, data, 0, data.length);
                    return 0;
                }
                bufSize.setInt(0, data.length);
                return -1;
            }
        });
        __dyld_fast_stub_entry = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                RegisterContext context = emulator.getContext();
                UnidbgPointer imageLoaderCache = context.getPointerArg(0);
                int lazyBindingInfoOffset = context.getIntArg(1);
                MachOModule mm = (MachOModule) emulator.getMemory().findModuleByAddress(imageLoaderCache.peer);
                long result = mm.doBindFastLazySymbol(emulator, lazyBindingInfoOffset);
                if (log.isDebugEnabled()) {
                    log.info("__dyld_fast_stub_entry imageLoaderCache=" + imageLoaderCache + ", lazyBindingInfoOffset=0x" + Long.toHexString(lazyBindingInfoOffset) + ", result=0x" + Long.toHexString(result));
                }
                return result;
            }
        });

        __dyld_dlopen = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public UnidbgPointer onRegister(SvcMemory svcMemory, int svcNumber) {
                try (Keystone keystone = new Keystone(KeystoneArchitecture.Arm, KeystoneMode.Arm)) {
                    KeystoneEncoded encoded = keystone.assemble(Arrays.asList(
                            "push {r4-r7, lr}",
                            "svc #0x" + Integer.toHexString(svcNumber),
                            "pop {r7}", // manipulated stack in dlopen
                            "cmp r7, #0",
                            "subne lr, pc, #16", // jump to pop {r7}
                            "bxne r7", // call init array
                            "pop {r0, r4-r7, pc}")); // with return address
                    byte[] code = encoded.getMachineCode();
                    UnidbgPointer pointer = svcMemory.allocate(code.length, "__dyld_dlopen");
                    pointer.write(0, code, 0, code.length);
                    return pointer;
                }
            }
            @Override
            public long handle(Emulator emulator) {
                Pointer path = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_R0);
                int mode = emulator.getBackend().reg_read(ArmConst.UC_ARM_REG_R1).intValue();
                String str = path == null ? null : path.getString(0);
                if (log.isDebugEnabled()) {
                    log.debug("__dyld_dlopen path=" + str + ", mode=0x" + Integer.toHexString(mode));
                }
                return dlopen(emulator, str, mode);
            }
        });
        __dyld_dlsym = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                long handle = emulator.getBackend().reg_read(ArmConst.UC_ARM_REG_R0).intValue() & 0xffffffffL;
                Pointer symbol = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_R1);
                if (log.isDebugEnabled()) {
                    log.debug("__dyld_dlsym handle=0x" + Long.toHexString(handle) + ", symbol=" + symbol.getString(0));
                }

                String symbolName = symbol.getString(0);
                if ((int) handle == Dyld.RTLD_MAIN_ONLY && "_os_trace_redirect_func".equals(symbolName)) {
                    return _os_trace_redirect_func;
                }

                return dlsym(emulator, (int) handle, "_" + symbolName);
            }
        });
        __dyld_dladdr = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                long addr = emulator.getBackend().reg_read(ArmConst.UC_ARM_REG_R0).intValue() & 0xffffffffL;
                Pointer info = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_R1);
                if (log.isDebugEnabled()) {
                    log.debug("__dyld_dladdr addr=0x" + Long.toHexString(addr) + ", info=" + info);
                }
                MachOModule module = (MachOModule) loader.findModuleByAddress(addr);
                if (module == null) {
                    return 0;
                }

                Symbol symbol = module.findClosestSymbolByAddress(addr, true);

                DlInfo32 dlInfo = new DlInfo32(info);
                dlInfo.dli_fname = (int) UnidbgPointer.nativeValue(module.createPathMemory(svcMemory));
                dlInfo.dli_fbase = (int) module.machHeader;
                if (symbol != null) {
                    dlInfo.dli_sname = (int) UnidbgPointer.nativeValue(symbol.createNameMemory(svcMemory));
                    dlInfo.dli_saddr = (int) symbol.getAddress();
                }
                dlInfo.pack();
                return 1;
            }
        });
        __dyld_dlclose = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                Arm32RegisterContext context = emulator.getContext();
                long handler = context.getR0Long();
                log.info("__dyld_dlclose handler=0x" + Long.toHexString(handler));
                return 0;
            }
        });
        __dyld_dlopen_preflight = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                RegisterContext context = emulator.getContext();
                Pointer path = context.getPointerArg(0);
                String pathname = path.getString(0);
                MachOLoader loader = (MachOLoader) emulator.getMemory();
                boolean canLoad = loader.dlopen_preflight(pathname);
                if (log.isDebugEnabled()) {
                    log.debug("dlopen_preflight path=" + pathname + ", canLoad=" + canLoad);
                }
                return canLoad ? 1 : 0;
            }
        });
        _os_trace_redirect_func = svcMemory.registerSvc(new ArmSvc() {
            @Override
            public long handle(Emulator emulator) {
                Pointer msg = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_R0);
//                                            Inspector.inspect(msg.getByteArray(0, 16), "_os_trace_redirect_func msg=" + msg);
                System.err.println("_os_trace_redirect_func msg=" + msg.getString(0));
                return 1;
            }
        }).peer;
    }

    private final Pointer __dyld_image_count;
    private final Pointer __dyld_get_image_name;
    private final Pointer __dyld_get_image_header;
    private final Pointer __dyld_get_image_vmaddr_slide;
    private final Pointer __dyld_get_image_slide;
    private final Pointer __dyld_register_func_for_add_image;
    private final Pointer __dyld_register_func_for_remove_image;
    private final Pointer __dyld_register_thread_helpers;
    private final Pointer __dyld_dyld_register_image_state_change_handler;
    private final Pointer __dyld_image_path_containing_address;
    private final Pointer __dyld__NSGetExecutablePath;
    private final Pointer __dyld_fast_stub_entry;

    @Override
    final int _stub_binding_helper() {
        log.info("dyldLazyBinder");
        return 0;
    }

    private final Pointer __dyld_dlopen;
    private final Pointer __dyld_dlsym;
    private final Pointer __dyld_dladdr;
    private final Pointer __dyld_dlclose;
    private final Pointer __dyld_dlopen_preflight;
    private final long _os_trace_redirect_func;

    @Override
    final int _dyld_func_lookup(Emulator emulator, String name, Pointer address) {
        switch (name) {
            case "__dyld__NSGetExecutablePath":
                address.setPointer(0, __dyld__NSGetExecutablePath);
                return 1;
            case "__dyld_get_image_name":
                address.setPointer(0, __dyld_get_image_name);
                return 1;
            case "__dyld_get_image_header":
                address.setPointer(0, __dyld_get_image_header);
                return 1;
            case "__dyld_fast_stub_entry": // fastBindLazySymbol
                address.setPointer(0, __dyld_fast_stub_entry);
                return 1;
            case "__dyld_get_image_slide":
                address.setPointer(0, __dyld_get_image_slide);
                return 1;
            case "__dyld_get_image_vmaddr_slide":
                address.setPointer(0, __dyld_get_image_vmaddr_slide);
                return 1;
            case "__dyld_image_count":
                address.setPointer(0, __dyld_image_count);
                return 1;
            case "__dyld_dlopen_preflight":
                address.setPointer(0, __dyld_dlopen_preflight);
                return 1;
            case "__dyld_dlopen":
                address.setPointer(0, __dyld_dlopen);
                return 1;
            case "__dyld_dladdr":
                address.setPointer(0, __dyld_dladdr);
                return 1;
            case "__dyld_dlclose":
                address.setPointer(0, __dyld_dlclose);
                return 1;
            case "__dyld_dlsym":
                address.setPointer(0, __dyld_dlsym);
                return 1;
            case "__dyld_register_thread_helpers":
                address.setPointer(0, __dyld_register_thread_helpers);
                return 1;
            case "__dyld_image_path_containing_address":
                address.setPointer(0, __dyld_image_path_containing_address);
                return 1;
            case "__dyld_register_func_for_remove_image":
                address.setPointer(0, __dyld_register_func_for_remove_image);
                return 1;
            case "__dyld_register_func_for_add_image":
                address.setPointer(0, __dyld_register_func_for_add_image);
                return 1;
            case "__dyld_dyld_register_image_state_change_handler":
                address.setPointer(0, __dyld_dyld_register_image_state_change_handler);
                return 1;
            default:
                log.info("_dyld_func_lookup name=" + name + ", address=" + address);
                break;
        }
        address.setPointer(0, null);
        return 0;
    }

    /**
     * @param path passing NULL for path means return magic object
     */
    private long dlopen(Emulator emulator, String path, int mode) {
        Memory memory = emulator.getMemory();
        Backend backend = emulator.getBackend();
        Pointer pointer = UnidbgPointer.register(emulator, ArmConst.UC_ARM_REG_SP);
        try {
            Collection loaded = memory.getLoadedModules();
            Module module = path == null ? null : memory.dlopen(path, false);
            if (module == null) {
                int ret;
                if (path == null) {
                    if ((mode & RTLD_FIRST) != 0) {
                        ret = RTLD_MAIN_ONLY;
                    } else {
                        ret = RTLD_DEFAULT;
                    }
                } else {
                    ret = 0;
                }

                pointer = pointer.share(-4); // return value
                pointer.setInt(0, ret);

                pointer = pointer.share(-4); // NULL-terminated
                pointer.setInt(0, 0);

                if (ret == 0) {
                    this.error.setString(0, "Resolve library " + path + " failed");
                    if ("/usr/sbin/aslmanager".equals(path)) {
                        return 0;
                    }
                    log.info("dlopen failed: " + path);
                    if (log.isDebugEnabled()) {
                        emulator.attach().debug();
                    }
                }
                return 0;
            } else {
                pointer = pointer.share(-4); // return value
                pointer.setInt(0, (int) module.base);

                pointer = pointer.share(-4); // NULL-terminated
                pointer.setInt(0, 0);

                Set newLoaded = new HashSet<>(memory.getLoadedModules());
                newLoaded.removeAll(loaded);
                if (log.isDebugEnabled()) {
                    log.debug("newLoaded=" + newLoaded + ", contains=" + loaded.contains(module));
                }
                for (Module m : newLoaded) {
                    MachOModule mm = (MachOModule) m;
                    if (mm.hasUnresolvedSymbol()) {
                        continue;
                    }
                    for (InitFunction initFunction : mm.routines) {
                        if (log.isDebugEnabled()) {
                            log.debug("[" + mm.name + "]PushRoutineFunction: 0x" + Long.toHexString(initFunction.getAddress()));
                        }
                        pointer = pointer.share(-4); // routine
                        pointer.setInt(0, (int) initFunction.getAddress());
                    }
                    mm.routines.clear();
                    for (InitFunction initFunction : mm.initFunctionList) {
                        if (log.isDebugEnabled()) {
                            log.debug("[" + mm.name + "]PushModInitFunction: 0x" + Long.toHexString(initFunction.getAddress()));
                        }
                        pointer = pointer.share(-4); // init array
                        pointer.setInt(0, (int) initFunction.getAddress());
                    }
                    mm.initFunctionList.clear();
                }

                return ((MachOModule) module).machHeader;
            }
        } finally {
            backend.reg_write(ArmConst.UC_ARM_REG_SP, ((UnidbgPointer) pointer).peer);
        }
    }

    private long _abort;

    @Override
    public long hook(SvcMemory svcMemory, String libraryName, String symbolName, final long old) {
        if ("libsystem_c.dylib".equals(libraryName)) {
            if ("_abort".equals(symbolName)) {
                if (_abort == 0) {
                    _abort = svcMemory.registerSvc(new ArmSvc() {
                        @Override
                        public long handle(Emulator emulator) {
                            System.err.println("abort");
                            emulator.attach().debug();
                            emulator.getBackend().reg_write(ArmConst.UC_ARM_REG_LR, emulator.getReturnAddress());
                            return 0;
                        }
                    }).peer;
                }
                return _abort;
            }
        } else if ("libsystem_asl.dylib".equals(libraryName)) {
            if ("_asl_open".equals(symbolName)) {
                if (_asl_open == 0) {
                    _asl_open = svcMemory.registerSvc(new ArmHook() {
                        @Override
                        protected HookStatus hook(Emulator emulator) {
                            EditableArm32RegisterContext context = emulator.getContext();
                            Pointer ident = context.getR0Pointer();
                            Pointer facility = context.getR1Pointer();
                            int opts = context.getR2Int();
                            if (log.isDebugEnabled()) {
                                log.debug("_asl_open ident=" + (ident == null ? null : ident.getString(0)) + ", facility=" + facility.getString(0) + ", opts=0x" + Integer.toHexString(opts));
                            }
                            context.setR2(opts | ASL_OPT_STDERR);
                            return HookStatus.RET(emulator, old);
                        }
                    }).peer;
                }
                return _asl_open;
            }
        }
        return 0;
    }

    private long _asl_open;

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy