都知道unidbg是基于unicorn开发的;
hook_add_new 第一个参数是Hook回调,我们这里选择CodeHook,它是逐条Hook,参数2是起始地址,参数3是结束地址,参数4一般填null。这意味着从起始地址到终止地址这个范围内的每条指令,我们都可以在其执行前处理它。
这一点的优点我很喜欢
package com.hookInUnidbg;import com.github.unidbg.AndroidEmulator;import com.github.unidbg.Emulator;import com.github.unidbg.Module;import com.github.unidbg.arm.backend.Backend;import com.github.unidbg.arm.backend.UnHook;import com.github.unidbg.arm.context.RegisterContext;import com.github.unidbg.debugger.BreakPointCallback;import com.github.unidbg.linux.android.AndroidEmulatorBuilder;import com.github.unidbg.linux.android.AndroidResolver;import com.github.unidbg.linux.android.dvm.*;import com.github.unidbg.memory.Memory;import com.github.unidbg.utils.Inspector;import keystone.Keystone;import keystone.KeystoneArchitecture;import keystone.KeystoneEncoded;import keystone.KeystoneMode;import unicorn.ArmConst;import com.github.unidbg.arm.backend.CodeHook;import unicorn.Unicorn;import java.io.File;public class crackDemo { private final AndroidEmulator emulator; private final VM vm; private final Module module; crackDemo() { // 创建模拟器实例 emulator = AndroidEmulatorBuilder.for32Bit().build(); // 模拟器的内存操作接口 final Memory memory = emulator.getMemory(); // 设置系统类库解析 memory.setLibraryResolver(new AndroidResolver(23)); // 创建Android虚拟机 vm = emulator.createDalvikVM(new File("unidbg-android/src/test/java/com/hookInUnidbg/app-debug.apk")); // 加载so到虚拟内存 DalvikModule dm = vm.loadLibrary("hookinunidbg", true); // 加载好的 libhookinunidbg.so对应为一个模块 module = dm.getModule(); // debug// emulator.attach().addBreakPoint(module.findSymbolByName("base64_encode").getAddress()); // 执行JNIOnLoad(如果有的话) dm.callJNI_OnLoad(emulator); } public void unicornHook(){ emulator.getBackend().hook_add_new(new CodeHook() { final RegisterContext registerContext = emulator.getContext(); @Override // com.github.unidbg.arm.backend.Detachable public void hook(Backend backend, long address, int size, Object user) { if(address == module.base + 0x8A0){ int r0 = registerContext.getIntByReg(ArmConst.UC_ARM_REG_R0); System.out.println("0x8A0 r0:"+Integer.toHexString(r0)); } if(address == module.base + 0x8A2){ int r2 = registerContext.getIntByReg(ArmConst.UC_ARM_REG_R2); System.out.println("0x8A2 r2:"+Integer.toHexString(r2)); } if(address == module.base + 0x8A4){ int r4 = registerContext.getIntByReg(ArmConst.UC_ARM_REG_R4); System.out.println("0x8A4 r4:"+Integer.toHexString(r4)); } } @Override // com.github.unidbg.arm.backend.Detachable public void onAttach(UnHook unHook) { } @Override // com.github.unidbg.arm.backend.Detachable public void detach() { } }, module.base + 0x8A0, module.base + 0x8C2, null); } public void hook(){ int patchCode = 0x4FF00000; // movs r0,0 emulator.getMemory().pointer(module.base + 0x8CA).setInt(0,patchCode);// try (Keystone keystone = new Keystone(KeystoneArchitecture.Arm, KeystoneMode.ArmThumb)) {// KeystoneEncoded encoded = keystone.assemble("mov r0,0");// byte[] patchCode = encoded.getMachineCode();// emulator.getMemory().pointer(module.base + 0x8CA).write(0, patchCode, 0, patchCode.length);// }// emulator.attach().addBreakPoint(module, 0x8CA, new BreakPointCallback() {// RegisterContext registerContext = emulator.getContext();// @Override// public boolean onHit(Emulator> emulator, long address) {// System.out.println("nop这里的调用");// emulator.getBackend().reg_write(ArmConst.UC_ARM_REG_PC, registerContext.getPCPointer().peer + 4 + 1);// emulator.getBackend().reg_write(ArmConst.UC_ARM_REG_R0, 0);// return true;// }// }); } public void call(){ DvmClass dvmClass = vm.resolveClass("com/example/hookinunidbg/MainActivity"); String methodSign = "call()V"; DvmObject<?> dvmObject = dvmClass.newObject(null); dvmObject.callJniMethodObject(emulator, methodSign); } public static void main(String[] args) { crackDemo mydemo = new crackDemo(); mydemo.hook(); mydemo.call(); }}
来源地址:https://blog.csdn.net/weixin_38927522/article/details/128224931