分析一个状态字段时,既要找到它在哪里赋值,也要弄清哪些方法会读取它。只搜索字段名称,容易混入局部变量、同名字段和注释文本。JEB Decompiler的交叉引用可以从字段对象跳到相关代码位置,再结合引用类型和底层指令确认读写行为。以下以Android APK、DEX分析为例,界面名称采用英文,其他分析模块的引用信息可能有所不同。
一、JEB Decompiler字段交叉引用怎么查看
查看引用前,先确认光标选中的是目标字段。所属类、字段名和类型共同帮助识别字段,混淆代码中尤其容易出现同名对象。
1、定位字段并打开引用列表
从声明处打开交叉引用,比较容易确认查询对象。已经在方法中看到字段使用位置时,也可以直接选中该字段操作。
①、点击【File】→【Open】打开待分析的【APK】或【DEX】,完成初步分析后,在【Code Hierarchy】中展开目标类。
②、打开字段声明所在的代码视图,将光标放在目标字段名上,核对所属类和字段类型。若从使用处进入,按【Enter】跳到定义处确认。
③、按【X】打开交叉引用列表,查看引用位置及【Details】列,记录引用该字段的方法和地址。
2、跳转到引用处检查上下文
①、在交叉引用列表中双击一条记录,跳转到对应代码位置,检查字段附近的赋值、条件判断或方法调用。
②、在反编译视图中按【Tab】切回对应的【Assembly】视图,核对字段签名和引用指令。
③、按【Alt+左方向键】或【Escape】返回之前的位置,再查看下一条引用。
引用列表提供的是代码中的引用位置,同一方法可能有多条记录。整理结果时,把方法名和指令地址一起保存,才能区分一次读取、多次赋值或循环中的同一条访问指令。
二、JEB Decompiler如何区分字段读取与写入
引用类型可以帮助快速分类,底层指令则能确认具体操作。反编译代码适合阅读业务含义,遇到复合表达式时还应展开检查。
1、结合引用标记判断访问方向
①、在目标字段的【交叉引用列表】中查看【Details】,将标为【GET】的记录作为读取位置,将标为【SET】的记录作为写入位置进一步核对。
②、双击读取记录,在反编译代码中检查字段是否用于返回值、参数或条件,例如【return this.count;】和【if(this.count>0)】。
③、双击写入记录,检查目标字段是否被赋值,例如【this.count=value;】,并继续确认右侧数值来自参数、常量还是计算结果。
不同插件、版本及引用来源可能提供不同的详情。标记缺失或含义不清时,继续查看对应指令,不要仅凭列表颜色判断。
2、用Dalvik指令确认读写
DEX中,实例字段和静态字段使用不同指令族,读取与写入也有明确区分。
①、在【Assembly】视图找到字段引用,遇到【iget】及其类型变体时,检查它从哪个对象读取字段、把值放入哪个寄存器。
②、遇到【iput】及其类型变体时,核对来源寄存器和目标对象,确认值写入的是当前分析的字段。
③、遇到【sget】或【sput】时,分别按静态字段读取、静态字段写入处理,并核对指令后的所属类与字段签名。
④、检查【-object】、【-wide】、【-boolean】等后缀,确认访问类型与字段定义对应。
3、拆开自增和对象内容修改
①、遇到【this.count++;】或【this.count+=step;】,切到【Assembly】,沿相关寄存器检查读取、计算和写回过程,分别记录读写地址。
②、遇到【this.items.add(value);】,查看是否先通过【iget-object】读取集合引用,再执行【invoke】调用;继续检查是否另有指令给字段重新赋值。
③、遇到【this.values[index]=value;】,检查字段读取后的数组访问指令,区分数组元素写入与字段引用本身的写入。
集合增加元素、数组修改内容,都可能改变字段所指向对象的状态。字段本身仍保存原来的引用时,其交叉引用可能表现为读取。追踪状态变化时,还要跟进对象操作,不能只统计字段写入次数。
三、JEB Decompiler字段引用不完整时怎么排查
交叉引用依赖当前加载的代码和分析结果。没有发现直接写入记录时,可以继续检查初始化、间接访问及实际执行路径。
1、检查初始化和间接访问
①、打开目标类的【
②、检查相关方法中的【Field.get】、【Field.set】等反射访问,结合类名、字段名字符串及对象来源确认目标。
③、发现【native】方法参与处理时,记录调用参数和返回值,继续检查对应本机库中的字段访问逻辑。
④、若项目包含多个【DEX】单元,核对相关类所在单元是否已经加载并完成分析,避免只检查其中一部分。
声明中的初始值、反射赋值和本机代码访问,不一定都表现为普通的直接写字段记录。列表为空时,需要结合这些路径判断,才能继续缩小范围。
2、核对字段身份并整理读写链路
同名字段可能属于不同类,继承关系中的访问还可能涉及相关字段引用。分析时把字段身份固定下来,比单纯扩大文本搜索范围更稳妥。
①、逐条核对引用中的【所属类】、【字段类型】和【字段名】,检查子类是否声明了同名字段。涉及继承访问时,再检查【Overrides】提供的相关项。
②、在确认的代码位置按【/】添加注释,记录读取用途、写入来源和关键条件,将字段访问地址保留下来。
③、从写入方法继续查看调用关系,检查其触发条件;需要验证运行顺序时,在可调试环境中设置对应位置的断点,观察实际对象和线程。
静态引用能说明哪些代码位置可能访问字段,具体是否执行、执行几次以及操作哪个实例,还要结合调用条件判断。存在多线程时,列表顺序也不能直接当作运行顺序。
总结
JEB的字段交叉引用适合建立访问位置清单,引用详情和Dalvik指令则帮助确认读取、赋值及间接修改之间的关系。把字段身份、指令地址和调用条件一起记录,后面追踪状态变化会清楚得多。希望大家遇到“字段值变了却找不到写入”的情况时,也能沿对象内容修改、初始化和间接访问继续检查,让分析结论有对应的代码依据。
