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

com.github.unidbg.ios.thread.DarwinThread Maven / Gradle / Ivy

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

import com.github.unidbg.AbstractEmulator;
import com.github.unidbg.Emulator;
import com.github.unidbg.arm.backend.Backend;
import com.github.unidbg.ios.struct.kernel.Pthread;
import com.github.unidbg.pointer.UnidbgPointer;
import com.github.unidbg.thread.ThreadTask;
import com.sun.jna.Pointer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import unicorn.Arm64Const;
import unicorn.ArmConst;

public class DarwinThread extends ThreadTask {

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

    private final UnidbgPointer start_routine;
    private final UnidbgPointer arg;
    private final Pthread pthread;
    private final int threadId;
    private final Pointer errno;

    public DarwinThread(Emulator emulator, UnidbgPointer start_routine, UnidbgPointer arg, Pthread pthread, int threadId, Pointer errno) {
        super(emulator.getPid(), emulator.getReturnAddress());

        this.start_routine = start_routine;
        this.arg = arg;
        this.pthread = pthread;
        this.threadId = threadId;
        this.errno = errno;
    }

    @Override
    public void setResult(Emulator emulator, Number ret) {
        super.setResult(emulator, ret);

        pthread.unpack();
        pthread.setExitValue(ret.intValue());
        pthread.pack();
    }

    public int getThreadId() {
        return threadId;
    }

    @Override
    public String toThreadString() {
        return "DarwinThread start_routine=" + start_routine + ", arg=" + arg;
    }

    @Override
    protected Number runThread(AbstractEmulator emulator) {
        Backend backend = emulator.getBackend();

        UnidbgPointer stack = allocateStack(emulator);
        pthread.setStack(stack, THREAD_STACK_SIZE);
        pthread.pack();

        backend.reg_write(emulator.is32Bit() ? ArmConst.UC_ARM_REG_R0 : Arm64Const.UC_ARM64_REG_X0, this.arg == null ? 0L : this.arg.peer);
        backend.reg_write(emulator.is32Bit() ? ArmConst.UC_ARM_REG_SP : Arm64Const.UC_ARM64_REG_SP, stack.peer);

        UnidbgPointer tsd = pthread.getTSD();
        tsd.setPointer(0, pthread.getPointer());
        tsd.setPointer(emulator.getPointerSize(), pthread.getErrno());
        pthread.getErrno().setPointer(0, errno);

        if (emulator.is32Bit()) {
            backend.reg_write(ArmConst.UC_ARM_REG_C13_C0_3, tsd.peer);
            backend.reg_write(ArmConst.UC_ARM_REG_LR, until);
        } else {
            backend.reg_write(Arm64Const.UC_ARM64_REG_TPIDRRO_EL0, tsd.peer);
            backend.reg_write(Arm64Const.UC_ARM64_REG_LR, until);
        }

        return emulator.emulate(this.start_routine.peer, until);
    }

    @Override
    public boolean setErrno(Emulator emulator, int errno) {
        this.errno.setInt(0, errno);
        return true;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy