现在很多app都用so加密,以后会越来越多。爬虫工程师可能直接逆向app,看java代码,完成java层的算法破解,但是遇到这种情况怎么办?也许你会这么直接破解,但是真的会有很多爬虫工程师去这么破解吗?有时候我们可以用很多大佬写的轮子,不用破解so就可以完成so的调用。说到调用,有很多种方法,比如用frida的rpc,xposed+andserver,还有unicorn+web框架等等,今天要说的不是这些,而是??unidbg。这个框架有什么好??看看介绍。介绍(来自易飞)unidbg是一款基于unicorn的逆向工程工具,可以在Android和iOS中黑盒调用so文件。unidbg是一个标准的java项目。由于现在的大部分APP都是把签名算法放在so文件里面的,所以想要破解签名算法,就必须能够破解so文件。但是我们知道,C++的逆向工程要比Java的逆向工程难得多,所以很多情况下是不可能破解的。这时候也可以使用hook的方式直接读取程序中计算出的签名,但是这样的话,要真正运行这个应用,就需要模拟器或者真机了,效率不是很高。unidbg是一个非常聪明的解决方案。不需要直接运行app,也不需要逆向so文件。而是在app中找到对应的JNI接口,然后使用unicorn引擎直接执行so文件,所以效率比较高。这里重要的是web服务目前是使用unidbg+springboot做的。可食用案例来自JXU2QkQyYXBwJTIwdjQuMTYuMA==对于这款app来说,是一款非常适合入门的app。不加固,算法简单,很容易找到so的jni。先去凯神的github下载https://github.com/zhkl0228/unidbg下载完成后用idea打开,等待maven下载。我已经在这里创建了du文件。上面的代码看起来比较方便,代码中有很多注释publicclassduextendsAbstractJni{//ARMsimulatorprivatefinalARMEmulatoremulator;//vmprivatefinalVMvm;//加载模块privatefinalModulemodule;私有最终DvmClassTTEncryptUtils;//初始化publicdu()throwsIOException{//创建app进程,这里不用写,我这里随便写,用app自己的进程绕过进程检测emulator=newAndroidARMEmulator("com.du.du");内存memory=emulator.getMemory();//作者同时支持sdk19和23memory.setLibraryResolver(newAndroidResolver(23));memory.setCallInitFunction();//创建DalvikVM,使用apk本身可以为null//如果使用apk文件加载so,会自动处理签名的jni。详见AbstractJni,使用apk加载的好处,//vm=emulator.createDalvikVM(newFile("src/test/resources/du/du4160.apk"));我这里没有使用apk,主要是没有检测到其他因素。vm=emulator.createDalvikVM(null);//加载so,使用armv8-64会快很多,这里是so的文件路径,其实你也可以使用apk本身。DalvikModuledm=vm.loadLibrary(newFile("src/test/resources/du/libJNIEncrypt.so"),false);//调用jnidm.callJNI_OnLoad(emulator);模块=dm.getModule();//加载So的类TTEncryptUtils=vm.resolveClass("com/duapp/aesjni/AESEncrypt");}//关闭模拟器privatevoiddestroy()throwsIOException{emulator.close();System.out.println("销毁");}publicstaticvoidmain(String[]args)throwsIOException{dut=newdu();t.encodeByte();t.destroy();}privateStringencodeByte(){//调试//这里也支持gdb调试,//emulator.attach(DebuggerType.GDB_SERVER);//附加调试器//emulator.attach(DebuggerType.SIMPLE);//emulator.traceCode();//这里是断点,原地址0x00005028->新地址0x40005028新地址需要改成0x4//emulator.attach().addBreakPoint(null,0x40001188);//编码地址//emulator.attach().addBreakPoint(null,0x40000D10);数ret=TTEncryptUtils.callStaticJniMethod(模拟器,"getByteValues()Ljava/lang/String;");longhash=ret.intValue()&0xffffffffL;StringObjectst1=vm.getObject(散列);//*这里处理字符串StringbyteString=st1.getValue();StringBuilderbuilder=newStringBuilder(byteString.length());for(inti=0;i
