unicornHook ネイティブ フック

unidbg が unicorn に基づいて開発されていることは誰もが知っています。

hook_add_new の最初のパラメータはフック コールバックです。ここでは CodeHook を選択します。これは 1 つずつフックです。パラメータ 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();
    }
}

おすすめ

転載: blog.csdn.net/weixin_38927522/article/details/128224931