Java方法标有native,打开后却没有方法体,这是分析JNI时经常遇到的情况。实现代码位于本地库,Java端只能看到声明和调用位置。围绕“JEB Decompiler如何分析JNI调用JEB Decompiler中Java方法与Native函数如何关联”,关键是找到加载的库,再确认方法绑定到哪个函数,而不是只在Java代码中反复搜索。
一、JEB Decompiler如何分析JNI调用
分析时需要同时查看DEX和ELF。以下使用JEB英文界面;涉及本地代码反编译及恢复插件的步骤,需要相应版本和模块支持。
1、打开应用和对应本地库
同一APK可能包含多种架构的同名库。名称相同不代表地址一致,分析过程中应固定一个架构,避免混用结果。
①点击【File】→【Open】,载入APK,等待DEX和资源解析完成。
②在【Project Explorer】展开应用内容,查看lib目录,确认arm64-v8a、armeabi-v7a等架构下的.so文件。
③双击对应ELF分析单元;库未被解析时,单独打开目标.so,确认已生成本地代码视图。
2、从Java声明追到调用位置
native声明说明实现位于本地代码,但不直接说明属于哪个库。加载语句可能位于静态初始化块,也可能经过其他加载类封装。
①在【Code Hierarchy】找到目标类,定位方法后按Tab查看反编译内容,记下类名、方法名及完整签名。
②光标停在方法上,按X查看交叉引用,双击调用条目,检查传入参数和返回值用途。
③查找System.loadLibrary或System.load,沿调用关系确认实际加载路径;例如loadLibrary("demo")对应常规命名的libdemo.so。
④在【Navigation】中启用【Do not replace Views】,保留Java与本地代码视图,便于来回核对。
二、JEB Decompiler中Java方法与Native函数如何关联
常见绑定方式有按JNI名称解析和通过RegisterNatives显式注册两种。后者的实现函数可以没有Java_前缀,也可能不在导出列表中。
1、通过导出名称查找实现
按名称绑定时,函数名包含编码后的类名与方法名。下划线、数组和重载参数都有专门规则,不能简单地把所有分隔符替换成下划线。
①在本地库的符号或导出列表查找Java_前缀,核对目标类和方法。
②例如com.example.Bridge中的run,可查找Java_com_example_Bridge_run;存在重载时,再核对带参数编码的长名称。
③双击目标函数,按Tab查看反编译结果,检查参数和返回值处理是否符合Java声明。
2、通过注册表确认绑定
RegisterNatives接收类对象、方法表和条目数量。JNINativeMethod中的名称、签名、函数指针,才是关联Java方法与本地实现的直接依据。
①在本地库中定位JNI_OnLoad,按Tab查看初始化逻辑,继续跟进注册相关调用。
②检查FindClass使用的类路径,或向前追踪传入注册函数的类对象来源。
③找到传给RegisterNatives的方法表,逐项读取名称、签名和函数指针,进入指针指向的函数。
④JNI_OnLoad中没有注册逻辑时,继续检查其他初始化函数和Java调用的注册入口,不据此认定没有关联。
3、使用恢复插件辅助查找
JEB Pro提供过针对JNI注册信息的恢复插件。它通过模拟JNI_OnLoad获取结果,缺少应用上下文时可能失败,输出仍需人工核对。
①点击【File】→【Engines】→【Plugins】,查找【Recover statically-registered natives(Android)】;存在该插件时,双击执行。
②按需要设置库名和架构过滤条件,运行后查看日志中的类名、方法名与函数地址。
③回到对应ELF单元核对地址和实现;日志没有结果时,保留手动追踪注册表的分析路径。
4、把确认的对应关系记入工程
重命名有助于阅读,但不会改变应用实际的JNI绑定。地址与签名应和名称一起保留,方便后续复核。
①在已确认的本地函数上点击【Action】→【Rename】,填写能对应Java方法的分析名称。
②按/添加注释,记录原始类名、签名、库名、架构及关联依据,再点击【File】→【Save】保存工程。
三、JEB Decompiler中JNI关联不明确怎么继续检查
遇到同名方法或地址对不上时,先检查签名、架构和运行状态。它们比函数名称更能解释为什么看似对应的两个位置实际上连不上。
1、用签名区分同名方法
同一个方法名可以对应不同参数。签名中的括号内是参数,括号后是返回类型。
①对照DEX声明和注册表签名,例如(I)Ljava/lang/String;表示接收int、返回String。
②检查static属性;普通JNI入口除显式参数外还有JNIEnv和对象或类参数,特殊JNI调用约定需另行核对。
2、区分文件位置与运行地址
ELF文件偏移、静态分析地址和进程中的地址不是同一种数值。不同架构的函数布局也可能不同。
①核对当前.so的版本与架构,确认它属于正在分析或调试的应用。
②对照加载基址和映像布局换算地址,不把文件偏移直接作为运行断点地址。
3、必要时观察实际调用目标
注册表可能运行时生成,绑定也可能被重新注册。静态信息不足时,调试可以补充实际执行证据。
①在已配置好Android调试环境的JEB中,打开【Assembly】,在调用native方法的invoke指令处设置断点。
②命中后执行【Step Into】,在支持的Java与本地联合调试会话中进入实际函数,核对所属库和地址。
③查看返回位置及结果,记录本次运行条件,不将一次观察直接推广到全部执行路径。
总结
希望这篇关于“JEB Decompiler如何分析JNI调用JEB Decompiler中Java方法与Native函数如何关联”的内容能帮到大家。面对跨语言程序,分析工作难免需要在不同视图之间往返,也需要耐心辨认一些看起来相似的细节。随着对工具和程序结构的了解加深,原本零散的信息会逐渐变得清楚。这份积累对理解软件、开展维护和技术研究都有帮助。学习过程中不必急于一次弄懂全部内容,能够把一个问题查清楚,就是实实在在的进步。若有JEB Decompiler相关需求,欢迎联系我们进一步了解。
