昨天在逆向某App的时候,发现有个加密工具类中的native方法是用C语言编写的,隐藏在so文件中。某大佬推荐逆向工具unidbg,能在pc端直接调用so文件中的函数,最终成功解决了问题。
一、unidbg引入
逆向某App,反编译dex得到Java代码,但是有两个加密工具类中的方法放到so文件中。






方法的实现用的C语言编写的,放在了so文件中。在Java中,动态加载so文件,使用native方法的形式隐藏了方法的方法体。难道伟大的逆向工程就此放弃?这显然不符合我们技术人的性格,肯定要想方设法弄出来。
二、unidbg概述
unidbg 是一个基于 unicorn 的逆向工具,可以直接调用Android和iOS中的 so 文件。项目的GitHub地址为https://github.com/zhkl0228/unidbg
我使用unidbg,直接调用libbaseEncryptLib.so、libencryptLib.so中的方法,这样就不用想破脑袋去逆向so文件了。
备 注 : \color{red}备注: 备注:so文件是unix系统中的动态连接库,属于二进制文件,作用相当于windows系统中的.dll文件。在Android中也可调用动态库文件*.so),一般会将加密算法、密码等重要的方法、信息使用C语言编写,然后编译成so文件,增强了软件的安全性。
三、unidbg使用姿势
1、下载unidbg项目
下载地址:https://github.com/zhkl0228/unidbg


2、导入到IDEA中
unidbg项目用Java编写,并且上面下载的是一个标准的maven项目。我这里演示导入到IDEA中,如果你熟悉其它的IDE,也可以自己去弄。(顺带一提,如果你之前没接触过Java语言,要确保电脑安装好JDK、maven)
①、解压压缩包
②、打开IDEA,导入解压的项目


浏览到刚刚解压好的文件夹




后面一路无脑next即可。。。








第一次导入此项目会自动下载一些jar包,和网速、maven服务器有关,耐心等待吧。


3、测试unidbg
项目中的src/test/java/com/xxxx/frameworks/core/encrypt路径中有一个TTEncrypt测试用例,直接执行其中的main方法。


4、运行自己的so文件
在前面,我们不是遇到了libbaseEncryptLib.so、libencryptLib.so文件么,利用unidbg直接调用so文件中 的方法。下面演示调用libencryptLib.so文件中的getGameKey函数。
①、编写EncryptUtilsJni类
package cn.hestyle;
import com.github.unidbg.Module;
import com.github.unidbg.arm.ARMEmulator;
import com.github.unidbg.linux.android.AndroidARMEmulator;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.*;
import com.github.unidbg.memory.Memory;
import java.io.File;
import java.io.IOException;
/** * description: EncryptUtils调用so * * @author hestyle * @version 1.0 * @className unidbg->EncryptUtilsJni * @date 2020-05-20 22:01 **/
public class EncryptUtilsJni extends AbstractJni {
// ARM模拟器
private final ARMEmulator emulator;
// vm
private final VM vm;
// 载入的模块
private final Module module;
private final DvmClass TTEncryptUtils;
/** * * @param soFilePath 需要执行的so文件路径 * @param classPath 需要执行的函数所在的Java类路径 * @throws IOException */
public EncryptUtilsJniString soFilePath, String classPath) throws IOException {
// 创建app进程,包名可任意写
emulator = new AndroidARMEmulator"cn.hestyle");
Memory memory = emulator.getMemory);
// 作者支持19和23两个sdk
memory.setLibraryResolvernew AndroidResolver23));
// 创建DalvikVM,利用apk本身,可以为null
vm = AndroidARMEmulator) emulator).createDalvikVMnull);
// (关键处1)加载so,填写so的文件路径
DalvikModule dm = vm.loadLibrarynew FilesoFilePath), false);
// 调用jni
dm.callJNI_OnLoademulator);
module = dm.getModule);
// (关键处2)加载so文件中的哪个类,填写完整的类路径
TTEncryptUtils = vm.resolveClassclassPath);
}
/** * 调用so文件中的指定函数 * @param methodSign 传入你要执行的函数信息,需要完整的smali语法格式的函数签名 * @param args 是即将调用的函数需要的参数 * @return 函数调用结果 */
private String myJniString methodSign, Object ...args) {
// 使用jni调用传入的函数签名对应的方法()
Number ret = TTEncryptUtils.callStaticJniMethodemulator, methodSign, args);
// ret存放返回调用结果存放的地址,获得函数执行后返回值
StringObject str = vm.getObjectret.intValue) & 0xffffffffL);
return str.getValue);
}
/** * 关闭模拟器 * @throws IOException */
private void destroy) throws IOException {
emulator.close);
System.out.println"emulator destroy...");
}
public static void mainString[] args) throws IOException {
// 1、需要调用的so文件所在路径
String soFilePath = "src/test/resources/myso/libencryptLib.so";
// 2、需要调用函数所在的Java类完整路径,比如a/b/c/d等等,注意需要用/代替.
String classPath = "com/.../EncryptUtils";
// 3、需要调用函数的函数签名,我这里调用EncryptUtils中的getGameKey方法,由于此方法没有参数列表,所以不需要传入
String methodSign = "getGameKey)Ljava/lang/String;";
EncryptUtilsJni encryptUtilsJni = new EncryptUtilsJnisoFilePath, classPath);
// 输出getGameKey方法调用结果
System.err.printlnencryptUtilsJni.myJnimethodSign));
encryptUtilsJni.destroy);
}
}
②、参数说明
EncryptUtilsJni类中最重要的设置为main方法中的soFilePath、classPath、methodSign三个参数,它们的作用在main方法中已经注释过了,这里再次解释一下。
soFilePath,填写你需要调用的so文件路径
classPath,填写你需要调用的函数所在Java类的完整类路径。


methodSign,填写你要调用的函数签名,语法为smali。(在jadx中,直接可以看smali代码)


备 注 : \color{red}备注: 备注:如果你要调用的函数还需要传入参数,直接传入myJni方法中即可,myJni方法中省略args参数就是供你传入参数。
③、执行结果
四、分析so文件的IDA工具
IDA工具是反汇编so文件的强大工具,由于libencryptLib.so文件比较简单,并且getGameKey函数返回的是一个常量,并没有复杂的处理过程,所以可以直接查看。
首先用IDA打开libencryptLib.so文件






查看反汇编得到的代码。






五、总结
unidbg确实很强大,直接在pc端模拟调用so文件,省去了反汇编逆向so文件的麻烦。上面的教程只演示了unidbg项目的导入、封装自己的调用so文件的API,其实这只是入门了,unidbg还支持断点调试so文件,也能导入到IDA中进行动态调试,自己去研究下吧,博主我也比较菜。
若 是 喜 欢 , 可 以 素 质 三 连 一 下 \color{red}若是喜欢,可以素质三连一下 若是喜欢,可以素质三连一下???





