示例代码如下:

import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Module;
import com.github.unidbg.Unidbg;
import com.github.unidbg.android.AndroidEmulatorBuilder;
import com.github.unidbg.android.EmulatorTest;
import com.github.unidbg.hook.HookListener;
import com.github.unidbg.hook.ReplaceCallback;
import com.github.unidbg.hook.hookzz.HookZz;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.DvmClass;
import com.github.unidbg.linux.android.dvm.DvmObject;
import com.github.unidbg.linux.android.dvm.VarArg;
import com.github.unidbg.memory.Memory;
import com.github.unidbg.memory.SvcMemory;

import java.io.File;
import java.io.IOException;

public class TestSign extends EmulatorTest<DvmObject> implements HookListener<AndroidEmulator<DvmObject>> {

    private static final String APK_PATH = "src/test/resources/app-debug.apk";
    private static final String NATIVE_LIB_PATH = "src/test/resources/libtes.so";

    @Override
    protected DvmObject doTest(final AndroidEmulator<DvmObject> emulator) throws IOException {
        final Memory memory = emulator.getMemory();
        final Module module = emulator.loadLibrary(new File(NATIVE_LIB_PATH));

        DalvikModule dm = emulator.getDalvikModule();

        // 解析apk文件
        dm.loadApk(new File(APK_PATH));

        // 注册native方法sign
        DvmClass tes = dm.findClass("com.github.unidbg.unidbgandroid.TestSign");
        tes.setJni(new TestSignJni());

        // 找到要调用的方法
        DvmClass cls = dm.findClass("com.github.unidbg.unidbgandroid.MainActivity");
        DvmObject<?> context = cls.newObject(null);
        String[] args = new String[]{"test1", "test2", "test3", "test4", "test5", "test6"};
        VarArg varArg = new VarArg(args);
        return cls.callStaticJniMethodObject(emulator, "sign", context, varArg);
    }

    private static class TestSignJni implements ReplaceCallback {

        @Override
        public HookZz wrapHookZz(SvcMemory svcMemory, HookZz hookZz) {
            return hookZz;
        }

        @Override
        public void onCall(Emulator<?> emulator, long originFunction) {
            DvmClass dvmClass = emulator.getDalvikModule().findClass("com.github.unidbg.unidbgandroid.TestSign");
            DvmObject<?> obj = DvmObject.valueOf(dvmClass, 0);
            DvmObject<?>[] args = emulator.getArgs(obj, DvmObject.class, 7);
            for (DvmObject<?> arg : args) {
                System.out.println(arg.getValue());
            }
            emulator.getRegisterContext().setLongArg(0, 0);
        }
    }

    public static void main(String[] args) throws Exception {
        AndroidEmulatorBuilder<DvmObject> builder = AndroidEmulatorBuilder.for32Bit();
        final AndroidEmulator<DvmObject> emulator = builder.build();
        emulator.getSyscallHandler().addIOResolver(new AndroidResolver(23));
        new TestSign().test(emulator);
        emulator.close();
    }
}

解释如下:

  1. 加载unidbg所需的类库。

    import com.github.unidbg.AndroidEmulator;
    import com.github.unidbg.Module;
    import com.github.unidbg.Unidbg;
    import com.github.unidbg.android.AndroidEmulatorBuilder;
    import com.github.unidbg.android.EmulatorTest;
    import com.github.unidbg.hook.HookListener;
    import com.github.unidbg.hook.ReplaceCallback;
    import com.github.unidbg.hook.hookzz.HookZz;
    import com.github.unidbg.linux.android.AndroidResolver;
    import com.github.unidbg.linux.android.dvm.DalvikModule;
    import com.github.unidbg.linux.android.dvm.DvmClass;
    import com.github.unidbg.linux.android.dvm.DvmObject;
    import com.github.unidbg.linux.android.dvm.VarArg;
    import com.github.unidbg.memory.Memory;
    import com.github.unidbg.memory.SvcMemory;
    
  2. 定义APK文件路径和native库文件路径。

    private static final String APK_PATH = "src/test/resources/app-debug.apk";
    private static final String NATIVE_LIB_PATH = "src/test/resources/libtes.so";
    
  3. 重写doTest方法,实现调用方法的逻辑。

        @Override
        protected DvmObject doTest(final AndroidEmulator<DvmObject> emulator) throws IOException {
            final Memory memory = emulator.getMemory();
            final Module module = emulator.loadLibrary(new File(NATIVE_LIB_PATH));
    
            DalvikModule dm = emulator.getDalvikModule();
    
            // 解析apk文件
            dm.loadApk(new File(APK_PATH));
    
            // 注册native方法sign
            DvmClass tes = dm.findClass("com.github.unidbg.unidbgandroid.TestSign");
            tes.setJni(new TestSignJni());
    
            // 找到要调用的方法
            DvmClass cls = dm.findClass("com.github.unidbg.unidbgandroid.MainActivity");
            DvmObject<?> context = cls.newObject(null);
            String[] args = new String[]{"test1", "test2", "test3", "test4", "test5", "test6"};
            VarArg varArg = new VarArg(args);
            return cls.callStaticJniMethodObject(emulator, "sign", context, varArg);
        }
    
    1. 加载native库文件。

      final Module module = emulator.loadLibrary(new File(NATIVE_LIB_PATH));
      
    2. 解析APK文件。

      dm.loadApk(new File(APK_PATH));
      
    3. 注册native方法sign

      DvmClass tes = dm.findClass("com.github.unidbg.unidbgandroid.TestSign");
      tes.setJni(new TestSignJni());
      
    4. 找到要调用的方法,并传入参数。

      DvmClass cls = dm.findClass("com.github.unidbg.unidbgandroid.MainActivity");
      DvmObject<?> context = cls.newObject(null);
      String[] args = new String[]{"test1", "test2", "test3", "test4", "test5", "test6"};
      VarArg varArg = new VarArg(args);
      return cls.callStaticJniMethodObject(emulator, "sign", context, varArg);
      
  4. 实现native方法的回调逻辑。

    private static class TestSignJni implements ReplaceCallback {
    
        @Override
        public HookZz wrapHookZz(SvcMemory svcMemory, HookZz hookZz) {
            return hookZz;
        }
    
        @Override
        public void onCall(Emulator<?> emulator, long originFunction) {
            DvmClass dvmClass = emulator.getDalvikModule().findClass("com.github.unidbg.unidbgandroid.TestSign");
            DvmObject<?> obj = DvmObject.valueOf(dvmClass, 0);
            DvmObject<?>[] args = emulator.getArgs(obj, DvmObject.class, 7);
            for (DvmObject<?> arg : args) {
                System.out.println(arg.getValue());
            }
            emulator.getRegisterContext().setLongArg(0, 0);
        }
    }
    
    1. 找到要调用的native方法所在的类。

      DvmClass dvmClass = emulator.getDalvikModule().findClass("com.github.unidbg.unidbgandroid.TestSign");
      
    2. 获取native方法的参数。

      DvmObject<?> obj = DvmObject.valueOf(dvmClass, 0);
      DvmObject<?>[] args = emulator.getArgs(obj, DvmObject.class, 7);
      
    3. 输出参数。

      for (DvmObject<?> arg : args) {
          System.out.println(arg.getValue());
      }
      
    4. 返回值。

      emulator.getRegisterContext().setLongArg(0, 0);
      
  5. 调用doTest方法并运行程序。

    public static void main(String[] args) throws Exception {
        AndroidEmulatorBuilder<DvmObject> builder = AndroidEmulatorBuilder.for32Bit();
        final AndroidEmulator<DvmObject> emulator = builder.build();
        emulator.getSyscallHandler().addIOResolver(new AndroidResolver(23));
        new TestSign().test(emulator);
        emulator.close();
    }
    
    1. 创建32位Android模拟器。

      AndroidEmulatorBuilder<DvmObject> builder = AndroidEmulatorBuilder.for32Bit();
      final AndroidEmulator<DvmObject> emulator = builder.build();
      
    2. 添加23号系统调用的解析器。

      emulator.getSyscallHandler().addIOResolver(new AndroidResolver(23));
      
    3. 调用doTest方法。

      new TestSign().test(emulator);
      
    4. 关闭模拟器。

      emulator.close();
      

原文地址: https://www.cveoy.top/t/topic/bnws 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录