一、指标 []
除了 AndroidNativeEmu 咱们还有一个抉择 Unidbg 来实现模仿执行 so,
GitHub 链接
https://github.com/zhkl0228/unidbg
特色
- 模仿 JNI 调用 API,以便能够调用 JNI_OnLoad。
- 反对 JavaVM,JNIEnv。
- 模仿 syscalls 调用。
- 反对 ARM32 和 ARM64。
- 基于 HookZz 实现的 inline hook。
- 基于 xHook 实现的 import hook。
- 反对 iOS fishhook、substrate、whale hook。
- 反对简略的控制台调试器,gdb,IDA android 调试器服务器,指令跟踪,内存读 / 写跟踪。
- 反对 iOS objc 和 Swift 运行时。
好吧,看上去很弱小的样子,咱们来跑个 Demo
二、步骤 []
先把 IDEA 配置好 (java 大佬疏忽这一步)
奋飞不会 java 开发,所以装好 IDEA 就开始急不可待的导入 unidbg 工程开始编译:
Tip:
IDEA 导入 unidbg 工程参见 https://code.newban.cn/151.html
- 报错 Error:(5, 24) java: 程序包 io.kaitai.struct 不存在
好吧,装一个 brew install kaitai-struct-compiler
- 持续报错 Error:(3, 34) java: 程序包 org.apache.commons.logging 不存在
行吧,下载一个 commons-logging-1.2.jar
- 还报错?不对劲,大神不可能这么难为凡人,肯定是哪出了问题??
google 之,原来是 Maven 没有配置好。搞他
Tip:
Maven 配置参见 https://zhuanlan.zhihu.com/p/28133184
搞定 Maven 之后如果还报错,那是因为依赖包没有下载下来,须要 reload 一下,静静的等依赖包下载完,反正奋飞是花了十多分钟。
好了,这次完满编译过来了
执行 so 中的 stringFromJNI 函数
- 在 unidbg-android 目录下新建 fenfei 文件夹,把 libnative-lib.so 文件放进去
sofile
- 在 unidbg-android/src/test/java/com 下新建 fenfei/testbase 文件夹,而后新建个 java 类 MainActivity
- 开始写代码了
public class MainActivity {public static void main(String[] args) {MainActivity mainActivity = new MainActivity();
mainActivity.stringFromJNI();}
private final AndroidEmulator emulator;
private final VM vm;
private DvmClass cNative;
private MainActivity() {emulator = new AndroidARMEmulator();
Memory memory = emulator.getMemory();
// 设置 sdk 版本 23
LibraryResolver resolver = new AndroidResolver(23);
memory.setLibraryResolver(resolver);
// 创立 DalvikVM,能够载入 apk,也能够为 null
vm = emulator.createDalvikVM(null);
// 是否打印日志
vm.setVerbose(false);
// System.out.println(getPath());
// 载入要执行的 so
DalvikModule dm = vm.loadLibrary(new File(getPath() + "/fenfei/libnative-lib.so"), false);
dm.callJNI_OnLoad(emulator);
}
private void stringFromJNI() {
// Jni 调用的类
cNative = vm.resolveClass("com/fenfei/myndk/MainActivity");
DvmObject<?> strRc = cNative.callStaticJniMethodObject(emulator,"stringFromJNI()Ljava/lang/String;");
System.out.println("call stringFromJNI rc =" + strRc.getValue());
}
public String getPath()
{String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
if(System.getProperty("os.name").contains("dows"))
{path = path.substring(1,path.length());
}
if(path.contains("jar"))
{// System.out.println("jar =" + path);
path = path.substring(0,path.lastIndexOf("."));
return path.substring(0,path.lastIndexOf("/"));
}
// System.out.println(path);
// path.replace("target/classes/", "");
return path.replace("/target/test-classes/", "");
}
}
跑一下,胜利输入, 出工
call stringFromJNI rc = Hello from C++
慢着!李老板又出场了,
奋飞呀,调用 so 你得给我一个可执行程序呀,总不能让我老板的机器上也装个 IDEA 来陪你玩吧?
打包成 jar 包
- File → Project Structure … 而后抉择 Artifacts, 点加号 Add
- jar → From modules with dependencies… 而后如下配置,别忘了勾上 Include tests
createjar
- OK 了,Build → Build Artifacts 编译胜利之后就在 unidbg-0.9.0/out/artifacts/unidbg_parent_jar 目录下生成了一堆依赖 jar 包和 unidbg-parent.jar 咱们把要载入的 fenfei/libnative-lib.so 放到和 unidbg-parent.jar 同级目录
泡一下,胜利输入,手工。(致力的字都不会打了)
fenfeideMacBook-Pro:unidbg_parent_jar fenfei$ java -jar unidbg-parent.jar
call stringFromJNI rc = Hello from C++
三、总结 []
学好 java,走遍天下都不怕
╮(‵▽′)╭ 工夫就应该节约在美妙的代码上