unidbg 加载 so 并调用 so 中函数¶
1. 前提准备¶
本文前需要以下准备:
jadx
: 主要用于查看目标app
的native
的部分,也可不用ida
: 用于分析目标app
的so
文件idea
: 用于编写和调试unidbg
脚本jdk
: 环境需要- 肉丝 unidbg 知乎教程系列
- unidbg 官方文档
- unidbg github 地址
unidbg
也一直在维护和更新中,一切请以 unidbg
官网最新 api
为准。
1.1. 环境配置¶
将上步骤的 jdk
等环境配置即可,然后 git
克隆 unidbg
的项目,会自动下载依赖。如果能跑通 unidbg
中的 看雪
和 Github
等示例即可。都很简单,不再赘述!
1.2. unidbg 新建项目¶
根据目标 app
的包名信息创建项目
那么,为什么要以目标 app
的包名创建项目呢?
简单来说,就是 unidbg
在符号调用 so
的函数时需要包名信息来确定要调用的方法所在的 java
类。
2. 调用过程¶
unidbg
执行 so
函数可以使用符号调用
或地址调用
,以下会使用这两类方式进行演示:
2.1.加载 so,并调用 init 以及 init_array 中的函数¶
init
对应的 app
中 cpp
的内容大致如下:
也可以在 ida
中反编译 so
文件后查看 init_array
的信息:将 so
文件拖入 ida
中分析,ctrl + s
查看 init_array
中有两个函数:go into myConstructor1
和 go into myConstructor2
go into myConstructor1
如下:
go into myConstructor2
如下:
unidbg
在加载 so
时就完成了 init
的相关调用
对应 uniodbg
的输出信息为:
2.2. 调用 so 中的普通函数¶
2.2.1. 调用 add(int, int) 函数:¶
对应的导出函数名为 _Z3addii
,具体如下:
则调用 add(int, int)
函数的示例为:
2.2.2. 调用 add_six(int,int,int,int,int,int) 函数¶
ida
查看对应的导出函数名为 _Z7add_sixiiiiii
,具体如下:
则调用 add_six(int,int,int,int,int,int)
函数的示例为:
2.2.3. 调用 getstringlength(char const*) 函数¶
getstringlength(char const*)
对应的导出函数为 _Z15getstringlengthPKc
,至于怎么得到这个结论不再演示。
则调用示例为:
2.2.4. 调用 getstringlength2(char const*,char const*) 函数¶
这个函数就比 2.2.2
多个同是指针的参数,老版 unidbg
记得申请内存地址两次即可,新版也只要添加个同样的参数而已,不再赘述。
3. 调用 JNI_OnLoad函数¶
直接执行 unidbg
的 JNI_OnLoad
函数就可以了
执行结果为:
4. 调用 jni 函数¶
根据 3
的执行结果,可以知道 b35
地址对应的为 stringFromJNI2
函数信息。在 ida
中按快捷键 G
输入 b35
跳转到对应代码内容。
4.1. 调用静态注册的 stringFromJNI1 函数¶
我们先调用在 ida
的 Exports
中可以查看到的 stringFromJNI1
函数,ida
中查看代码为:
unidbg
调用示例如下:
4.2. 调用动态注册的 stringFromJNI2 函数¶
在 ida
中按快捷键 G
输入 b35
跳转到对应代码内容如下:
在上面和下面的 unidbg
日志可知,动态注册的函数名称为 stringFromJNI2
:
则调用示例为: