文章总结: 文章分享逆向安卓APP中SO库加密方法的技术实践。由于混淆严重且无法直接Java调用ARM架构SO库,作者改用Unidbg模拟安卓环境成功调用加密函数,并与SpringBoot集成提供HTTP服务。关键步骤包括获取JNI调用链、处理架构兼容性、实现Unidbg引擎封装及性能优化建议(如实例池化应对初始化延迟与老化问题)。 综合评分: 89 文章分类: 逆向分析,安卓逆向,安全工具,技术标准,解决方案
【安卓逆向】模拟安卓环境调用SO库
原创
墨雪飘影 墨雪飘影
墨雪飘影
2026年7月10日 08:42 湖北
在小说阅读器读本章
去阅读
最近帮群友逆向一个 APP,加密参数都已经分析出来了,唯独缺一个加密算法。
后面在一堆 SO 文件里找到了目标,IDA 加载一看——混淆非常严重,纯算法还原太耗时间。于是决定直接调用 SO 文件中的加密方法,走模拟执行路线。
0获取调用链
通过 JEB 或 MT 文件管理器加载 APK 后反编译,定位到目标 SO 文件路径。
根据路径可以初步判断这是一个 JNI 库。接下来用 nm -D 查看 JNI 导出的函数名称:
▸ Shell 命令
nm -D libsu.so | grep encrypt
可以看到是静态注册的方式,理论上可以直接用 Java 调用这个 JNI 方法。
1直接调用(Java 方式)
先尝试最直观的方案:直接用 Java 加载 SO 文件并调用 native 方法。
▸ NativeDemo.java
public class NativeDemo {
static { System.load(“C:\sofile\libsu.so”); }
public native String encrypt(String input, String salt);
public static void main(String[] args) { NativeDemo demo = new NativeDemo(); String input = “test”; String salt = “123456”; System.out.println(demo.encrypt(input, salt)); } }
编译运行后报错:
AMD-64 平台无法加载 ARM64 SO 文件的错误信息
⚠️ 报错原因无法在 AMD-64 平台调用 ARM64 架构的 SO 文件。这是安卓原生库与桌面 Java 环境的架构差异导致的,直接加载方案行不通。
不可能为了调用一个方法单独起个 APP 去跑,所以必须换方案——模拟安卓环境。
2模拟安卓环境(Unidbg)
Unidbg 基于 Unicorn 引擎,可以模拟安卓原生库的执行环境,支持 ARM/ARM64 架构。
相关项目Unidbg 项目:https://github.com/zhkl0228/unidbg Unicorn 项目:https://www.unicorn-engine.org/
需要 JDK 1.8 + Maven 环境,拉取项目后在本地编译。
▸ Maven 编译命令
& “C:\Program Files\JetBrains\IntelliJ IDEA 2026.1.1\plugins\maven\lib\maven3\bin\mvn.cmd” install “-Dgpg.skip=true” “-DskipTests”
编译完成后 unidbg-android 依赖已安装到本地 Maven 仓库
编译完成后,在项目中引入依赖:
▸ pom.xml 依赖配置
然后编写 Unidbg 调用引擎:
▸ UnidbgEngineContext.java
package cn.mxpy;
import com.github.unidbg.AndroidEmulator; import com.github.unidbg.Module; import com.github.unidbg.linux.android.AndroidEmulatorBuilder; import com.github.unidbg.linux.android.dvm.*; import com.github.unidbg.memory.Memory; import com.github.unidbg.linux.android.AndroidResolver; import java.io.File; import java.io.IOException;
public class UnidbgEngineContext extends AbstractJni {
private final AndroidEmulator emulator; private final VM vm; private final DalvikModule dm; private final Module module;
public UnidbgEngineContext() throws IOException { emulator = AndroidEmulatorBuilder .for64Bit() .setProcessName(“com.xxxx.xxxx”) .build(); Memory memory = emulator.getMemory(); memory.setLibraryResolver(new AndroidResolver(23)); vm = emulator.createDalvikVM(); vm.setJni(this); vm.setVerbose(false); File soFile = new File(“C:\Users\i\sofile\libsu.so”); dm = vm.loadLibrary(soFile, false); module = dm.getModule(); dm.callJNI_OnLoad(emulator); }
public String encrypt(String arg0, String arg1) { DvmClass clazz = vm.resolveClass(“com/xxx/xx/xxx”); StringObject result = clazz.callStaticJniMethodObject( emulator, “encrypt(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;”, new StringObject(vm, arg0), new StringObject(vm, arg1) ); return result.getValue(); } }
在 App.java 中调用测试:
▸ App.java
package cn.mxpy;
import java.io.IOException;
public class App { public static void main(String[] args) throws IOException { System.out.println(“Hello World!”); UnidbgEngineContext unidbgEngineContext = new UnidbgEngineContext(); System.out.println(unidbgEngineContext.encrypt(“1”, “1”)); } }
控制台输出加密后的字符串,证明调用成功
调用成功!
3集成 SpringBoot 提供 HTTP 接口
将 Unidbg 与 SpringBoot 结合,把 SO 库中的加密方法封装成 HTTP 服务,供外部调用。
Controller 层接收参数,调用 UnidbgEngine 返回加密结果
通过 HTTP 请求即可获取加密结果:
▸ HTTP 调用示例
GET /api/encrypt?input=test&salt=123456 → 返回加密后的字符串
4总结与注意事项Unidbg 实例初始化耗时较长,本地测试约 7-8 秒,云主机约 12 秒左右。生产环境建议做实例池化或预热。
另外 Unidbg 存在 “老化” 问题(长时间运行后稳定性下降),需要定期重启或维护。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:墨雪飘影 墨雪飘影 墨雪飘影《【安卓逆向】模拟安卓环境调用SO库》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。







评论