From 9506c0d347a2662f8aa5e870e30c6fbaceef78e3 Mon Sep 17 00:00:00 2001 From: zhkl0228 Date: Fri, 29 Jul 2022 17:05:33 +0800 Subject: [PATCH] api: Update capstone. --- .../unidbg/arm/backend/HypervisorBackend.java | 6 +- .../hypervisor/HypervisorBackend64.java | 51 ++++++++++++++--- .../unidbg/arm/backend/kvm/KvmBackend64.java | 6 +- unidbg-api/pom.xml | 4 +- .../com/github/unidbg/RegAccessPrinter.java | 27 ++++----- .../main/java/com/github/unidbg/arm/ARM.java | 57 ++++++++++--------- .../com/github/unidbg/arm/CodeHistory.java | 1 - .../unidbg/arm/TraceFunctionCall32.java | 7 +-- .../unidbg/arm/TraceFunctionCall64.java | 7 +-- .../test/java/com/github/unidbg/HexTest.java | 19 ++++--- .../com/github/unidbg/ios/MachOLoader.java | 5 +- .../com/github/unidbg/ios/MachOModule.java | 9 +-- .../java/com/github/unidbg/ios/A12ZTest.java | 2 +- 13 files changed, 119 insertions(+), 82 deletions(-) diff --git a/backend/hypervisor/src/main/java/com/github/unidbg/arm/backend/HypervisorBackend.java b/backend/hypervisor/src/main/java/com/github/unidbg/arm/backend/HypervisorBackend.java index b62692dda..588c9954e 100644 --- a/backend/hypervisor/src/main/java/com/github/unidbg/arm/backend/HypervisorBackend.java +++ b/backend/hypervisor/src/main/java/com/github/unidbg/arm/backend/HypervisorBackend.java @@ -138,14 +138,14 @@ public EventMemHookNotifier(EventMemHook callback, int type, Object user) { this.type = type; this.user = user; } - public void notifyDataAbort(boolean isWrite, long address) { + public void notifyDataAbort(boolean isWrite, int size, long address) { if (isWrite) { if ((type & UnicornConst.UC_HOOK_MEM_WRITE_UNMAPPED) != 0) { - callback.hook(HypervisorBackend.this, address, 0, 0L, user, EventMemHook.UnmappedType.Write); + callback.hook(HypervisorBackend.this, address, size, 0L, user, EventMemHook.UnmappedType.Write); } } else { if ((type & UnicornConst.UC_HOOK_MEM_READ_UNMAPPED) != 0) { - callback.hook(HypervisorBackend.this, address, 0, 0L, user, EventMemHook.UnmappedType.Read); + callback.hook(HypervisorBackend.this, address, size, 0L, user, EventMemHook.UnmappedType.Read); } } } diff --git a/backend/hypervisor/src/main/java/com/github/unidbg/arm/backend/hypervisor/HypervisorBackend64.java b/backend/hypervisor/src/main/java/com/github/unidbg/arm/backend/hypervisor/HypervisorBackend64.java index ddead0fb2..ce45444cf 100644 --- a/backend/hypervisor/src/main/java/com/github/unidbg/arm/backend/hypervisor/HypervisorBackend64.java +++ b/backend/hypervisor/src/main/java/com/github/unidbg/arm/backend/hypervisor/HypervisorBackend64.java @@ -123,9 +123,22 @@ public boolean removeBreakPoint(long address) { public void handleUnknownException(int ec, long esr, long far, long virtualAddress) { switch (ec) { case EC_DATAABORT: + boolean isv = (esr & ARM_EL_ISV) != 0; // Instruction Syndrome Valid. Indicates whether the syndrome information in ISS[23:14] is valid. boolean isWrite = ((esr >> 6) & 1) != 0; + int sas = (int) ((esr >> 22) & 3); // Syndrome Access Size. Indicates the size of the access attempted by the faulting operation. + int accessSize = isv ? 1 << sas : 0; + int srt = (int) ((esr >> 16) & 0x1f); // Syndrome Register Transfer. The register number of the Wt/Xt/Rt operand of the faulting instruction. + /* + * Width of the register accessed by the instruction is Sixty-Four. + * 0b0 Instruction loads/stores a 32-bit wide register. + * 0b1 Instruction loads/stores a 64-bit wide register. + */ + boolean sf = ((esr >> 15) & 1) != 0; + if (log.isDebugEnabled()) { + log.debug("handleDataAbort srt=" + srt + ", sf=" + sf + ", accessSize=" + accessSize); + } if (eventMemHookNotifier != null) { - eventMemHookNotifier.notifyDataAbort(isWrite, virtualAddress); + eventMemHookNotifier.notifyDataAbort(isWrite, accessSize, virtualAddress); } break; case EC_INSNABORT: @@ -188,7 +201,7 @@ public void onException() { return true; } case EC_DATAABORT: { - boolean isv = (esr & ARM_EL_ISV) != 0; + boolean isv = (esr & ARM_EL_ISV) != 0; // Instruction Syndrome Valid. Indicates whether the syndrome information in ISS[23:14] is valid. boolean isWrite = ((esr >> 6) & 1) != 0; boolean s1ptw = ((esr >> 7) & 1) != 0; int sas = (int) ((esr >> 22) & 3); @@ -199,7 +212,8 @@ public void onException() { log.debug("handle EC_DATAABORT isv=" + isv + ", isWrite=" + isWrite + ", s1ptw=" + s1ptw + ", len=" + len + ", srt=" + srt + ", dfsc=0x" + Integer.toHexString(dfsc) + ", vaddr=0x" + Long.toHexString(far)); } if (dfsc == 0x00 && emulator.getFamily() == Family.iOS) { - return handleCommRead(far, elr); + int accessSize = isv ? 1 << sas : 0; + return handleCommRead(far, elr, accessSize); } throw new UnsupportedOperationException("handleException ec=0x" + Integer.toHexString(ec) + ", dfsc=0x" + Integer.toHexString(dfsc)); } @@ -247,8 +261,16 @@ public void hook_add_new(WriteHook callback, long begin, long end, Object user_d private void onWatchpoint(long esr, long address) { boolean write = ((esr >> 6) & 1) == 1; int status = (int) (esr & 0x3f); + /* + * Cache maintenance. Indicates whether the Watchpoint exception came from a cache maintenance or address translation instruction: + * 0b0 The Watchpoint exception was not generated by the execution of one of the System instructions identified in the description of value 1. + * 0b1 The Watchpoint exception was generated by either the execution of a cache maintenance instruction or by a synchronous Watchpoint exception on the execution of an address translation instruction. The DC ZVA, DC GVA, and DC GZVA instructions are not classified as a cache maintenance instructions, and therefore their execution cannot cause this field to be set to 1. + */ + boolean cm = ((esr >> 8) & 1) == 1; + int wpt = (int) ((esr >> 18) & 0x3f); // Watchpoint number, 0 to 15 inclusive. + boolean wptv = ((esr >> 17) & 1) == 1; // The WPT field is valid, and holds the number of a watchpoint that triggered a Watchpoint exception. if (log.isDebugEnabled()) { - log.debug("onWatchpoint write=" + write + ", address=0x" + Long.toHexString(address) + ", status=0x" + Integer.toHexString(status)); + log.debug("onWatchpoint write=" + write + ", address=0x" + Long.toHexString(address) + ", cm=" + cm + ", wpt=" + wpt + ", wptv=" + wptv + ", status=0x" + Integer.toHexString(status)); } boolean hit = false; for (int i = 0; i < watchpoints.length; i++) { @@ -310,6 +332,17 @@ public void unhook() { private CodeHookNotifier codeHookNotifier; + /** + * The local exclusive monitor gets cleared on every exception return,that is, on execution of the ERET instruction. + * + * from: ... + * LDAXR sets the 'exclusive monitor' and STXR only succeeds if the exclusive + * monitor is still set. If another CPU accesses the memory protected by the + * exclusive monitor, the monitor is cleared. This is how the spinlock code knows + * it has to re-read its value and try to take the lock again. + * Changing exception level also clears the exclusive monitor, so taking + * single-step exception between a LDAXR/STXR pair means the loop has to be retried. + */ @Override public void hook_add_new(CodeHook callback, long begin, long end, Object user_data) throws BackendException { if (codeHookNotifier != null) { @@ -341,7 +374,7 @@ private void onSoftwareStep(long esr, long address, long spsr) { } } - private boolean handleCommRead(long vaddr, long elr) { + private boolean handleCommRead(long vaddr, long elr, int accessSize) { Pointer pointer = UnidbgPointer.pointer(emulator, vaddr); assert pointer != null; Pointer pc = UnidbgPointer.pointer(emulator, elr); @@ -354,7 +387,7 @@ private boolean handleCommRead(long vaddr, long elr) { OpInfo opInfo = (OpInfo) insn.getOperands(); if (opInfo.isUpdateFlags() || opInfo.isWriteBack() || !insn.getMnemonic().startsWith("ldr") || vaddr < _COMM_PAGE64_BASE_ADDRESS) { if (eventMemHookNotifier != null) { - eventMemHookNotifier.notifyDataAbort(false, vaddr); + eventMemHookNotifier.notifyDataAbort(false, accessSize, vaddr); } return false; } @@ -366,7 +399,7 @@ private boolean handleCommRead(long vaddr, long elr) { case 0x58: { Operand operand = op[0]; OpValue value = operand.getValue(); - reg_write(value.getUnicornReg(), 0x0L); + reg_write(insn.mapToUnicornReg(value.getReg()), 0x0L); hypervisor.reg_set_elr_el1(elr + 4); return true; } @@ -378,7 +411,7 @@ private boolean handleCommRead(long vaddr, long elr) { case 0x90: { Operand operand = op[0]; OpValue value = operand.getValue(); - reg_write(value.getUnicornReg(), 0x0); + reg_write(insn.mapToUnicornReg(value.getReg()), 0x0); hypervisor.reg_set_elr_el1(elr + 4); return true; } @@ -388,7 +421,7 @@ private boolean handleCommRead(long vaddr, long elr) { case 0x36: { // uint8_t number of logical CPUs (hw.logicalcpu_max) Operand operand = op[0]; OpValue value = operand.getValue(); - reg_write(value.getUnicornReg(), 1); + reg_write(insn.mapToUnicornReg(value.getReg()), 1); hypervisor.reg_set_elr_el1(elr + 4); return true; } diff --git a/backend/kvm/src/main/java/com/github/unidbg/arm/backend/kvm/KvmBackend64.java b/backend/kvm/src/main/java/com/github/unidbg/arm/backend/kvm/KvmBackend64.java index 1f19a7a68..4606c7015 100644 --- a/backend/kvm/src/main/java/com/github/unidbg/arm/backend/kvm/KvmBackend64.java +++ b/backend/kvm/src/main/java/com/github/unidbg/arm/backend/kvm/KvmBackend64.java @@ -95,7 +95,7 @@ private boolean handleCommRead(long vaddr, long elr) { case 0x58: { Operand operand = op[0]; OpValue value = operand.getValue(); - reg_write(value.getUnicornReg(), 0x0L); + reg_write(insn.mapToUnicornReg(value.getReg()), 0x0L); kvm.reg_set_elr_el1(elr + 4); return true; } @@ -107,7 +107,7 @@ private boolean handleCommRead(long vaddr, long elr) { case 0x90: { Operand operand = op[0]; OpValue value = operand.getValue(); - reg_write(value.getUnicornReg(), 0x0); + reg_write(insn.mapToUnicornReg(value.getReg()), 0x0); kvm.reg_set_elr_el1(elr + 4); return true; } @@ -117,7 +117,7 @@ private boolean handleCommRead(long vaddr, long elr) { case 0x36: { // uint8_t number of logical CPUs (hw.logicalcpu_max) Operand operand = op[0]; OpValue value = operand.getValue(); - reg_write(value.getUnicornReg(), 1); + reg_write(insn.mapToUnicornReg(value.getReg()), 1); kvm.reg_set_elr_el1(elr + 4); return true; } diff --git a/unidbg-api/pom.xml b/unidbg-api/pom.xml index b8a4da0f6..8c2198ea7 100644 --- a/unidbg-api/pom.xml +++ b/unidbg-api/pom.xml @@ -20,7 +20,7 @@ com.github.zhkl0228 capstone - 3.1.7 + 3.1.8 com.github.zhkl0228 @@ -55,7 +55,7 @@ com.github.zhkl0228 demumble - 1.0.3 + 1.0.4 diff --git a/unidbg-api/src/main/java/com/github/unidbg/RegAccessPrinter.java b/unidbg-api/src/main/java/com/github/unidbg/RegAccessPrinter.java index 62edd449a..d03d37ebf 100644 --- a/unidbg-api/src/main/java/com/github/unidbg/RegAccessPrinter.java +++ b/unidbg-api/src/main/java/com/github/unidbg/RegAccessPrinter.java @@ -1,10 +1,10 @@ package com.github.unidbg; -import capstone.Arm64_const; -import capstone.Arm_const; import capstone.api.Instruction; import com.github.unidbg.arm.Cpsr; import com.github.unidbg.arm.backend.Backend; +import unicorn.Arm64Const; +import unicorn.ArmConst; import java.util.Locale; @@ -27,15 +27,16 @@ public void print(Emulator emulator, Backend backend, StringBuilder builder, return; } for (short reg : accessRegs) { + int regId = instruction.mapToUnicornReg(reg); if (emulator.is32Bit()) { - if ((reg >= Arm_const.ARM_REG_R0 && reg <= Arm_const.ARM_REG_R12) || - reg == Arm_const.ARM_REG_LR || reg == Arm_const.ARM_REG_SP || - reg == Arm_const.ARM_REG_CPSR) { + if ((regId >= ArmConst.UC_ARM_REG_R0 && regId <= ArmConst.UC_ARM_REG_R12) || + regId == ArmConst.UC_ARM_REG_LR || regId == ArmConst.UC_ARM_REG_SP || + regId == ArmConst.UC_ARM_REG_CPSR) { if (forWriteRegs) { builder.append(" =>"); forWriteRegs = false; } - if (reg == Arm_const.ARM_REG_CPSR) { + if (regId == ArmConst.UC_ARM_REG_CPSR) { Cpsr cpsr = Cpsr.getArm(backend); builder.append(String.format(Locale.US, " cpsr: N=%d, Z=%d, C=%d, V=%d", cpsr.isNegative() ? 1 : 0, @@ -43,18 +44,18 @@ public void print(Emulator emulator, Backend backend, StringBuilder builder, cpsr.hasCarry() ? 1 : 0, cpsr.isOverflow() ? 1 : 0)); } else { - int value = backend.reg_read(reg).intValue(); + int value = backend.reg_read(regId).intValue(); builder.append(' ').append(instruction.regName(reg)).append("=0x").append(Long.toHexString(value & 0xffffffffL)); } } } else { - if ((reg >= Arm64_const.ARM64_REG_X0 && reg <= Arm64_const.ARM64_REG_X28) || - (reg >= Arm64_const.ARM64_REG_X29 && reg <= Arm64_const.ARM64_REG_SP)) { + if ((regId >= Arm64Const.UC_ARM64_REG_X0 && regId <= Arm64Const.UC_ARM64_REG_X28) || + (regId >= Arm64Const.UC_ARM64_REG_X29 && regId <= Arm64Const.UC_ARM64_REG_SP)) { if (forWriteRegs) { builder.append(" =>"); forWriteRegs = false; } - if (reg == Arm64_const.ARM64_REG_NZCV) { + if (regId == Arm64Const.UC_ARM64_REG_NZCV) { Cpsr cpsr = Cpsr.getArm64(backend); if (cpsr.isA32()) { builder.append(String.format(Locale.US, " cpsr: N=%d, Z=%d, C=%d, V=%d", @@ -70,15 +71,15 @@ public void print(Emulator emulator, Backend backend, StringBuilder builder, cpsr.isOverflow() ? 1 : 0)); } } else { - long value = backend.reg_read(reg).longValue(); + long value = backend.reg_read(regId).longValue(); builder.append(' ').append(instruction.regName(reg)).append("=0x").append(Long.toHexString(value)); } - } else if (reg >= Arm64_const.ARM64_REG_W0 && reg <= Arm64_const.ARM64_REG_W30) { + } else if (regId >= Arm64Const.UC_ARM64_REG_W0 && regId <= Arm64Const.UC_ARM64_REG_W30) { if (forWriteRegs) { builder.append(" =>"); forWriteRegs = false; } - int value = backend.reg_read(reg).intValue(); + int value = backend.reg_read(regId).intValue(); builder.append(' ').append(instruction.regName(reg)).append("=0x").append(Long.toHexString(value & 0xffffffffL)); } } diff --git a/unidbg-api/src/main/java/com/github/unidbg/arm/ARM.java b/unidbg-api/src/main/java/com/github/unidbg/arm/ARM.java index 089f75706..6812bf1fe 100644 --- a/unidbg-api/src/main/java/com/github/unidbg/arm/ARM.java +++ b/unidbg-api/src/main/java/com/github/unidbg/arm/ARM.java @@ -1,7 +1,5 @@ package com.github.unidbg.arm; -import capstone.Arm64_const; -import capstone.Arm_const; import capstone.api.Instruction; import capstone.api.OpShift; import capstone.api.arm.MemType; @@ -885,12 +883,12 @@ private static void appendMemoryDetails32(Emulator emulator, Instruction ins, // ldr rx, [pc, #0xab] or ldr.w rx, [pc, #0xcd] based capstone.setDetail(Capstone.CS_OPT_ON); if (op.length == 2 && - op[0].getType() == Arm_const.ARM_OP_REG && - op[1].getType() == Arm_const.ARM_OP_MEM) { + op[0].getType() == capstone.Arm_const.ARM_OP_REG && + op[1].getType() == capstone.Arm_const.ARM_OP_MEM) { mem = op[1].getValue().getMem(); if (mem.getIndex() == 0 && mem.getScale() == 1 && mem.getLshift() == 0) { - UnidbgPointer base = UnidbgPointer.register(emulator, mem.getUnicornBaseReg()); + UnidbgPointer base = UnidbgPointer.register(emulator, ins.mapToUnicornReg(mem.getBase())); long base_value = base == null ? 0L : base.peer; addr = base_value + mem.getDisp(); } @@ -899,13 +897,13 @@ private static void appendMemoryDetails32(Emulator emulator, Instruction ins, OpShift shift; if (mem.getIndex() > 0 && mem.getScale() == 1 && mem.getLshift() == 0 && mem.getDisp() == 0 && (shift = op[1].getShift()) != null) { - UnidbgPointer base = UnidbgPointer.register(emulator, mem.getUnicornBaseReg()); + UnidbgPointer base = UnidbgPointer.register(emulator, ins.mapToUnicornReg(mem.getBase())); long base_value = base == null ? 0L : base.peer; - UnidbgPointer index = UnidbgPointer.register(emulator, mem.getIndex()); + UnidbgPointer index = UnidbgPointer.register(emulator, ins.mapToUnicornReg(mem.getIndex())); int index_value = index == null ? 0 : (int) index.peer; - if (shift.getType() == Arm_const.ARM_OP_IMM) { + if (shift.getType() == capstone.Arm_const.ARM_OP_IMM) { addr = base_value + ((long) index_value << shift.getValue()); - } else if (shift.getType() == Arm_const.ARM_OP_INVALID) { + } else if (shift.getType() == capstone.Arm_const.ARM_OP_INVALID) { addr = base_value + index_value; } } @@ -913,17 +911,17 @@ private static void appendMemoryDetails32(Emulator emulator, Instruction ins, // ldrb r0, [r1], #1 if (op.length == 3 && - op[0].getType() == Arm_const.ARM_OP_REG && - op[1].getType() == Arm_const.ARM_OP_MEM && - op[2].getType() == Arm_const.ARM_OP_IMM) { + op[0].getType() == capstone.Arm_const.ARM_OP_REG && + op[1].getType() == capstone.Arm_const.ARM_OP_MEM && + op[2].getType() == capstone.Arm_const.ARM_OP_IMM) { mem = op[1].getValue().getMem(); if (mem.getIndex() == 0 && mem.getScale() == 1 && mem.getLshift() == 0) { - UnidbgPointer base = UnidbgPointer.register(emulator, mem.getUnicornBaseReg()); + UnidbgPointer base = UnidbgPointer.register(emulator, ins.mapToUnicornReg(mem.getBase())); addr = base == null ? 0L : base.peer; } } if (addr != -1) { - if (mem.getUnicornBaseReg() == Arm_const.ARM_REG_PC) { + if (ins.mapToUnicornReg(mem.getBase()) == ArmConst.UC_ARM_REG_PC) { addr += (thumb ? 4 : 8); } int bytesRead = 4; @@ -939,15 +937,16 @@ private static void appendMemoryDetails32(Emulator emulator, Instruction ins, // ldrd r2, r1, [r5, #4] if ("ldrd".equals(ins.getMnemonic()) && op.length == 3 && - op[0].getType() == Arm_const.ARM_OP_REG && - op[1].getType() == Arm_const.ARM_OP_REG && - op[2].getType() == Arm_const.ARM_OP_MEM) { + op[0].getType() == capstone.Arm_const.ARM_OP_REG && + op[1].getType() == capstone.Arm_const.ARM_OP_REG && + op[2].getType() == capstone.Arm_const.ARM_OP_MEM) { mem = op[2].getValue().getMem(); if (mem.getIndex() == 0 && mem.getScale() == 1 && mem.getLshift() == 0) { - UnidbgPointer base = UnidbgPointer.register(emulator, mem.getUnicornBaseReg()); + int regId = ins.mapToUnicornReg(mem.getBase()); + UnidbgPointer base = UnidbgPointer.register(emulator, regId); long base_value = base == null ? 0L : base.peer; addr = base_value + mem.getDisp(); - if (mem.getUnicornBaseReg() == Arm_const.ARM_REG_PC) { + if (regId == ArmConst.UC_ARM_REG_PC) { addr += (thumb ? 4 : 8); } appendAddrValue(sb, addr, memory, emulator.is64Bit(), 4); @@ -965,15 +964,16 @@ private static void appendMemoryDetails64(Emulator emulator, Instruction ins, // str w9, [sp, #0xab] based capstone.setDetail(Capstone.CS_OPT_ON); if (op.length == 2 && - op[0].getType() == Arm64_const.ARM64_OP_REG && - op[1].getType() == Arm64_const.ARM64_OP_MEM) { - if (op[0].getValue().getUnicornReg() >= Arm64Const.UC_ARM64_REG_W0 && op[0].getValue().getUnicornReg() <= Arm64Const.UC_ARM64_REG_W30) { + op[0].getType() == capstone.Arm64_const.ARM64_OP_REG && + op[1].getType() == capstone.Arm64_const.ARM64_OP_MEM) { + int regId = ins.mapToUnicornReg(op[0].getValue().getReg()); + if (regId >= Arm64Const.UC_ARM64_REG_W0 && regId <= Arm64Const.UC_ARM64_REG_W30) { bytesRead = 4; } mem = op[1].getValue().getMem(); if (mem.getIndex() == 0) { - UnidbgPointer base = UnidbgPointer.register(emulator, mem.getUnicornBaseReg()); + UnidbgPointer base = UnidbgPointer.register(emulator, ins.mapToUnicornReg(mem.getBase())); long base_value = base == null ? 0L : base.peer; addr = base_value + mem.getDisp(); } @@ -981,15 +981,16 @@ private static void appendMemoryDetails64(Emulator emulator, Instruction ins, // ldrb r0, [r1], #1 if (op.length == 3 && - op[0].getType() == Arm64_const.ARM64_OP_REG && - op[1].getType() == Arm64_const.ARM64_OP_MEM && - op[2].getType() == Arm64_const.ARM64_OP_IMM) { - if (op[0].getValue().getUnicornReg() >= Arm64Const.UC_ARM64_REG_W0 && op[0].getValue().getUnicornReg() <= Arm64Const.UC_ARM64_REG_W30) { + op[0].getType() == capstone.Arm64_const.ARM64_OP_REG && + op[1].getType() == capstone.Arm64_const.ARM64_OP_MEM && + op[2].getType() == capstone.Arm64_const.ARM64_OP_IMM) { + int regId = ins.mapToUnicornReg(op[0].getValue().getReg()); + if (regId >= Arm64Const.UC_ARM64_REG_W0 && regId <= Arm64Const.UC_ARM64_REG_W30) { bytesRead = 4; } mem = op[1].getValue().getMem(); if (mem.getIndex() == 0) { - UnidbgPointer base = UnidbgPointer.register(emulator, mem.getUnicornBaseReg()); + UnidbgPointer base = UnidbgPointer.register(emulator, ins.mapToUnicornReg(mem.getBase())); addr = base == null ? 0L : base.peer; addr += mem.getDisp(); } diff --git a/unidbg-api/src/main/java/com/github/unidbg/arm/CodeHistory.java b/unidbg-api/src/main/java/com/github/unidbg/arm/CodeHistory.java index f3790976c..3edb7a189 100644 --- a/unidbg-api/src/main/java/com/github/unidbg/arm/CodeHistory.java +++ b/unidbg-api/src/main/java/com/github/unidbg/arm/CodeHistory.java @@ -1,6 +1,5 @@ package com.github.unidbg.arm; -import capstone.Capstone; import capstone.api.Instruction; import com.github.unidbg.Emulator; import com.github.unidbg.arm.backend.Backend; diff --git a/unidbg-api/src/main/java/com/github/unidbg/arm/TraceFunctionCall32.java b/unidbg-api/src/main/java/com/github/unidbg/arm/TraceFunctionCall32.java index eae3bf19f..75af88d9d 100644 --- a/unidbg-api/src/main/java/com/github/unidbg/arm/TraceFunctionCall32.java +++ b/unidbg-api/src/main/java/com/github/unidbg/arm/TraceFunctionCall32.java @@ -1,6 +1,5 @@ package com.github.unidbg.arm; -import capstone.Arm_const; import capstone.api.Instruction; import capstone.api.arm.OpInfo; import capstone.api.arm.Operand; @@ -93,11 +92,11 @@ protected void onInstruction(Instruction instruction) { Operand operand = operands.getOperands()[0]; final long functionAddress; switch (operand.getType()) { - case Arm_const.ARM_OP_IMM: + case capstone.Arm_const.ARM_OP_IMM: functionAddress = operand.getValue().getImm(); break; - case Arm_const.ARM_OP_REG: - functionAddress = context.getIntByReg(operand.getValue().getUnicornReg()); + case capstone.Arm_const.ARM_OP_REG: + functionAddress = context.getIntByReg(instruction.mapToUnicornReg(operand.getValue().getReg())); break; default: throw new UnsupportedOperationException("type=" + operand.getType()); diff --git a/unidbg-api/src/main/java/com/github/unidbg/arm/TraceFunctionCall64.java b/unidbg-api/src/main/java/com/github/unidbg/arm/TraceFunctionCall64.java index 63bab9c85..82a77e36d 100644 --- a/unidbg-api/src/main/java/com/github/unidbg/arm/TraceFunctionCall64.java +++ b/unidbg-api/src/main/java/com/github/unidbg/arm/TraceFunctionCall64.java @@ -1,6 +1,5 @@ package com.github.unidbg.arm; -import capstone.Arm64_const; import capstone.api.Instruction; import capstone.api.arm64.OpInfo; import capstone.api.arm64.Operand; @@ -51,11 +50,11 @@ protected void onInstruction(Instruction instruction) { Operand operand = operands.getOperands()[0]; final long functionAddress; switch (operand.getType()) { - case Arm64_const.ARM64_OP_IMM: + case capstone.Arm64_const.ARM64_OP_IMM: functionAddress = operand.getValue().getImm(); break; - case Arm64_const.ARM64_OP_REG: - functionAddress = context.getLongByReg(operand.getValue().getUnicornReg()); + case capstone.Arm64_const.ARM64_OP_REG: + functionAddress = context.getLongByReg(instruction.mapToUnicornReg(operand.getValue().getReg())); break; default: throw new UnsupportedOperationException("type=" + operand.getType()); diff --git a/unidbg-api/src/test/java/com/github/unidbg/HexTest.java b/unidbg-api/src/test/java/com/github/unidbg/HexTest.java index ceb6a0549..a105ebc6c 100644 --- a/unidbg-api/src/test/java/com/github/unidbg/HexTest.java +++ b/unidbg-api/src/test/java/com/github/unidbg/HexTest.java @@ -28,15 +28,16 @@ public void testHex() throws Exception { } public void testDisassembler() throws Exception { - Disassembler disassembler = DisassemblerFactory.createArm64Disassembler(); - disassembler.setDetail(true); - byte[] code = Hex.decodeHex("017544bd".toCharArray()); - Instruction instruction = disassembler.disasm(code, 0)[0]; - assertNotNull(instruction); - RegsAccess regsAccess = instruction.regsAccess(); - assertNotNull(regsAccess); - System.out.println("regsRead=" + Arrays.toString(regsAccess.getRegsRead())); - System.out.println("regsWrite=" + Arrays.toString(regsAccess.getRegsWrite())); + try (Disassembler disassembler = DisassemblerFactory.createArm64Disassembler()) { + disassembler.setDetail(true); + byte[] code = Hex.decodeHex("017544bd".toCharArray()); + Instruction instruction = disassembler.disasm(code, 0)[0]; + assertNotNull(instruction); + RegsAccess regsAccess = instruction.regsAccess(); + assertNotNull(regsAccess); + System.out.println("regsRead=" + Arrays.toString(regsAccess.getRegsRead())); + System.out.println("regsWrite=" + Arrays.toString(regsAccess.getRegsWrite())); + } } public void testStream() throws Exception { diff --git a/unidbg-ios/src/main/java/com/github/unidbg/ios/MachOLoader.java b/unidbg-ios/src/main/java/com/github/unidbg/ios/MachOLoader.java index ab266445e..f421ecc7a 100644 --- a/unidbg-ios/src/main/java/com/github/unidbg/ios/MachOLoader.java +++ b/unidbg-ios/src/main/java/com/github/unidbg/ios/MachOLoader.java @@ -179,7 +179,7 @@ private void initializeTSD(String[] envs) { /* 0xa4必须固定,否则初始化objc会失败 */ final UnidbgPointer tsd = pthread.getTSD(); // tsd size assert tsd != null; - tsd.setPointer(__TSD_THREAD_SELF * emulator.getPointerSize(), thread); + tsd.setPointer(__TSD_THREAD_SELF, thread); tsd.setPointer(__TSD_ERRNO * emulator.getPointerSize(), errno); tsd.setPointer(__TSD_MIG_REPLY * emulator.getPointerSize(), null); @@ -741,6 +741,9 @@ private MachOModule loadInternalPhase(LibraryFile libraryFile, ByteBuffer buffer needed.addReferenceCount(); neededLibraries.put(FilenameUtils.getBaseName(needed.name), needed); } else if(!library.weak) { + if ("/usr/lib/libnetwork.dylib".equals(neededLibrary)) { + continue; + } log.info("Module \"" + dyId + "\" load dependency " + neededLibrary + " failed: rpath=" + rpathSet); } } diff --git a/unidbg-ios/src/main/java/com/github/unidbg/ios/MachOModule.java b/unidbg-ios/src/main/java/com/github/unidbg/ios/MachOModule.java index 5666a281a..3f03f5006 100644 --- a/unidbg-ios/src/main/java/com/github/unidbg/ios/MachOModule.java +++ b/unidbg-ios/src/main/java/com/github/unidbg/ios/MachOModule.java @@ -10,7 +10,6 @@ import com.github.unidbg.hook.HookListener; import com.github.unidbg.ios.objc.ObjectiveCProcessor; import com.github.unidbg.ios.objc.processor.CDObjectiveC2Processor; -import com.github.unidbg.ios.objc.processor.UniObjectiveProcessor; import com.github.unidbg.ios.struct.DyldUnwindSections; import com.github.unidbg.memory.MemRegion; import com.github.unidbg.memory.Memory; @@ -135,7 +134,7 @@ public final int virtualMemoryAddressToFileOffset(long address) { throw new IllegalStateException("Cannot find segment for address: 0x" + Long.toHexString(address)); } - private final List allInitFunctionList = new ArrayList<>(); + private final List allInitFunctionList; MachOModule(MachO machO, String name, long base, long size, Map neededLibraries, List regions, MachO.SymtabCommand symtabCommand, MachO.DysymtabCommand dysymtabCommand, ByteBuffer buffer, @@ -173,8 +172,10 @@ public final int virtualMemoryAddressToFileOffset(long address) { this.log = LogFactory.getLog("com.github.unidbg.ios." + name); this.routines = machO == null ? Collections.emptyList() : parseRoutines(machO); this.initFunctionList = machO == null ? Collections.emptyList() : parseInitFunction(machO, buffer.duplicate(), name, emulator); - this.allInitFunctionList.addAll(routines); - this.allInitFunctionList.addAll(initFunctionList); + List allInitFunctionList = new ArrayList<>(routines.size() + initFunctionList.size()); + allInitFunctionList.addAll(routines); + allInitFunctionList.addAll(initFunctionList); + this.allInitFunctionList = Collections.unmodifiableList(allInitFunctionList); if (machO == null) { exportSymbols = Collections.emptyMap(); diff --git a/unidbg-ios/src/test/java/com/github/unidbg/ios/A12ZTest.java b/unidbg-ios/src/test/java/com/github/unidbg/ios/A12ZTest.java index ebbb16bc4..6d4c525df 100644 --- a/unidbg-ios/src/test/java/com/github/unidbg/ios/A12ZTest.java +++ b/unidbg-ios/src/test/java/com/github/unidbg/ios/A12ZTest.java @@ -30,7 +30,7 @@ public static void main(String[] args) throws IOException { Module module = emulator.loadLibrary(new File("unidbg-ios/src/test/resources/example_binaries/a12z_osx")); long start = System.currentTimeMillis(); - emulator.traceRead(0xfbffffda0L, 0xfbffffda0L + 0x8); + emulator.traceRead(0xfbffffd30L, 0xfbffffd30L + 0x8); int ret = module.callEntry(emulator); System.err.println("testA12Z backend=" + emulator.getBackend() + ", ret=0x" + Integer.toHexString(ret) + ", offset=" + (System.currentTimeMillis() - start) + "ms"); }