unidbg补环境 - 某东APP sign分析

写在最前面

上篇是通过frdia hook 分析目标app的sign参数,这篇文章通过unidbg补环境,来获取到目标参数。同时记录下unidbg补环境的过程。

补环境

  • 搭建好模版
public class JingDongSign extends AbstractJni {

    private final AndroidEmulator emulator;
    private final VM vm;
    private final Module module;
    private Memory memory;

    public JingDongSign() {
        emulator = AndroidEmulatorBuilder.for32Bit().setProcessName("com.jingdong.app.mall").build();
        // 获取模拟器的内存操作接口
        memory = emulator.getMemory();
        // 设置系统类库解析
        memory.setLibraryResolver(new AndroidResolver(23));
        // 创建Android虚拟机,传入APK,Unidbg可以替我们做部分签名校验的工作
        vm = emulator.createDalvikVM(new File("path/目标.apk"));
        //
        //vm = emulator.createDalvikVM(null);
        // 加载目标SO
        DalvikModule dm = vm.loadLibrary(new File("/path/libjdbitmapkit.so"), true); // 加载so到虚拟内存
        //获取本SO模块的句柄,后续需要用它
        module = dm.getModule();
        vm.setJni(this); // 设置JNI
//        vm.setVerbose(true); // 打印日志

        dm.callJNI_OnLoad(emulator); // 调用JNI OnLoad
    }

public void getSignFromJni() {
        ArrayList args = new ArrayList<>(10);
        args.add(vm.getJNIEnv());
        args.add(0);
        // 前两个参数固定写法
        args.add(vm.addLocalObject(vm.resolveClass("android/content/Context").newObject(null)));
        args.add(vm.addLocalObject(new StringObject(vm, "searchBoxWord")));
        args.add(vm.addLocalObject(new StringObject(vm, " {\"geo\":\"VNfO2wQHmvP4y5nMzG57aoZ6JeMTGp8qU0MXssp7SNC338Ds0C1MbASr47trp0dd7idK5Yw57BgeHWK3CGvjZQ%3D%3D\",\"geoLast\":\"VNfO2wQHmvP4y5nMzG57aoZ6JeMTGp8qU0MXssp7SNC338Ds0C1MbASr47trp0dd7idK5Yw57BgeHWK3CGvjZQ%3D%3D\"}")));
        args.add(vm.addLocalObject(new StringObject(vm, "259fb80b2a74f7a3")));
        args.add(vm.addLocalObject(new StringObject(vm, "android")));
        args.add(vm.addLocalObject(new StringObject(vm, "10.2.0")));
        Number number = module.callFunction(emulator, 0x28b5, args.toArray()); // 调用so层方法
        System.out.println(vm.getObject(number.intValue()).getValue().toString());
    }

public static void main(String[] args) {
        JingDongSign jd = new JingDongSign();
        jd.getSignFromJni();
    }
}
 
 
  • 运行,根据报错信息来补环境
    • one


      image.png

      根据保存信息 补com/jingdong/common/utils/BitmapkitUtils->a:Landroid/app/Application;

    @Override
    public DvmObject getStaticObjectField(BaseVM vm, DvmClass dvmClass, String signature) {
        if("com/jingdong/common/utils/BitmapkitUtils->a:Landroid/app/Application;".equals(signature)){
            return vm.resolveClass("android/app/Activity").newObject(signature);
        }
        throw new UnsupportedOperationException(signature);

    }

    • two
image.png

取ApplicationInfo也就是apk的存放位置 可以在RE文件管理器/data/app中找到对应的位置

if ("android/content/pm/ApplicationInfo->sourceDir:Ljava/lang/String;".equals(signature)) {
            return new StringObject(vm, "/data/app/com.jingdong.app.mall-cd4VeJ0b5yxrR0Zb-io_MA=/base.apk");
        }
    • three


      image.png

      先查看传入的参数是


      image.png

      根据参数打开APK中中的META-INF搜索RSA结尾的文件
      image.png

      根据这个文件名补即可

     if ("com/jingdong/common/utils/BitmapkitZip->unZip(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)[B".equals(signature)) {
            System.out.println("arg0--  "+varArg.getObjectArg(0).getValue());
            System.out.println("arg1--  "+varArg.getObjectArg(1).getValue());
            System.out.println("arg2--  "+varArg.getObjectArg(2).getValue());
            return new ByteArray(vm, vm.unzip("META-INF/JINGDONG.RSA"));
     }
    • four


      image.png
        if("sun/security/pkcs/PKCS7->([B)V".equals(signature)){
            PKCS7 pkcs7= null;
            try {
                pkcs7 = new PKCS7((byte[]) varArg.getObjectArg(0).getValue());
            } catch (ParsingException e) {
                e.printStackTrace();
            }
            return vm.resolveClass("sun/security/pkcs/PKCS7").newObject(pkcs7);
        }
    • five


      image.png
        if("sun/security/pkcs/PKCS7->getCertificates()[Ljava/security/cert/X509Certificate;".equals(signature)){
            PKCS7 pkcs7 = (PKCS7) dvmObject.getValue();
            X509Certificate[] x509Certificates = pkcs7.getCertificates();
            return ProxyDvmObject.createObject(vm, x509Certificates);
        }
    • six
      补BitmapkitZip类下的objectToBytes方法


      image.png

      打开jdax搜这个方法


      image.png

      将此代码复制出来,写我们程序中
private static byte[] objectToBytes(Object obj) {
        try {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(obj);
            objectOutputStream.flush();
            byte[] byteArray = byteArrayOutputStream.toByteArray();
            objectOutputStream.close();
            byteArrayOutputStream.close();
            return byteArray;
        } catch (IOException e) {
            return null;
        }
    }

继续补环境

      if("com/jingdong/common/utils/BitmapkitZip->objectToBytes(Ljava/lang/Object;)[B".equals(signature)){
            return new ByteArray(vm, JingDongSign.objectToBytes(varArg.getObjectArg(0).getValue()));
        }
    • seven


      image.png
    if("java/lang/StringBuffer->()V".equals(signature)){
            StringBuffer stringBuffer = new StringBuffer();
            return vm.resolveClass("java/lang/StringBuffer").newObject(stringBuffer);
        }
    • eight


      image.png
        if("java/lang/StringBuffer->append(Ljava/lang/String;)Ljava/lang/StringBuffer;".equals(signature)){
            StringBuffer stringBuffer = (StringBuffer) dvmObject.getValue();
            return vm.resolveClass("java/lang/StringBuffer").newObject(stringBuffer.append(vaList.getObjectArg(0).getValue()));

        }
    • nine


      image.png
        if("java/lang/Integer->toString()Ljava/lang/String;".equals(signature)){
            Integer integer = (Integer) dvmObject.getValue();
            return new StringObject(vm, integer.toString());
        }
    • ten


      image.png
    if("java/lang/StringBuffer->toString()Ljava/lang/String;".equals(signature)){
            StringBuffer stringBuffer = (StringBuffer) dvmObject.getValue();
            return new StringObject(vm, stringBuffer.toString());

        }
    • end


      image.png

      运行成功,至此补环境完毕。之后就可以黑盒调试,不想调试也可以用spring boot搭建个服务,远程调用即可

你可能感兴趣的:(unidbg补环境 - 某东APP sign分析)