逆向检测dex特征函数
2019-08-22 小文字背景
通过逆向工具我们可以反编译apk,进而查找一些关键词。但是这个效率往往比较慢,GUI工具占用内存特别大,而且查找也不是很方便。 本文分享下,怎么使用的dexdump快速检测代码。
查找特征代码
假设你现在需要检测一下apk中是否引入了某个sdk,或者是否有特定函数,
此时我们只需要分析出特征代码在编译后的方法签名即可快速查找,如果不严谨,甚至可以直接字符串匹配查查 简单的可以直接用linux下的strings命令,对zip递归查找。这里介绍下dexdump,分以下步骤
- 解析出classesN.dex文件
- 变量dex,针对每个dex执行dexdump,查找类定义,也就是dex中的class def
- 根据命中方法,输出方法所在的类名
- 输出报告
dexdump的使用,大家可以查阅帮助文档,默认该命令可能没有配置在PATH中,可以在以下路径找到
$ANDROID_HOME/sdk/build-tools/[platform版本号]/dexdump
通过 -d
或-h
参数都可以输出class列表定义,但是格式略有细微差异。
将上述流程编写为shell脚本方便后续使用。
dexdump查找
为了能够使用dexdump,我们需要在安装了SDK的情况下自助发现dexdump的目录,这里我们查找最新平台版本的dexdump目录
if [[ -z "${ANDROID_HOME}" ]]; then
die "ANDROID_HOME not found"
fi
echo "find target build-tools"
buildtools=($ANDROID_HOME/build-tools/*)
size=${#buildtools[@]}
buildtool=${buildtools[size-1]}
echo $buildtool
dexdump输出分析
现在先分析下dex解析后的数据结构,可以参考下 dex-format
-h
参数。首先输出的是head头信息不同字段的取值,接着就是class列表,这个是重点。
Opened '/Users/aven/Desktop/apk/classes.dex', DEX version '035'
Class #0 header:
class_idx : 79
access_flags : 17 (0x0011)
superclass_idx : 9234
interfaces_off : 0 (0x000000)
source_file_idx : 24233
annotations_off : 0 (0x000000)
class_data_off : 7547075 (0x7328c3)
static_fields_size : 0
instance_fields_size: 0
direct_methods_size : 1
virtual_methods_size: 0
我们看下class的定义,第一行是类名,接下来是类的各种定义信息,比如可见性,基类,接口继承,静态方法,成员方法。
因为我们是查找成员方法,因此关注的是Direct methods下的数组节点。 每个方法的输出,第一行是类名,第二行是方法名,另外就是是方法的属性信息。
Class #0 -
Class descriptor : 'Landroid/arch/core/R;'
Access flags : 0x0011 (PUBLIC FINAL)
Superclass : 'Ljava/lang/Object;'
Interfaces -
Static fields -
Instance fields -
Direct methods -
#0 : (in Landroid/arch/core/R;)
name : '<init>'
type : '()V'
access : 0x10002 (PRIVATE CONSTRUCTOR)
code -
registers : 1
ins : 1
outs : 1
insns size : 4 16-bit code units
catches : (none)
positions :
0x0000 line=10
locals :
0x0000 - 0x0004 reg=0 this Landroid/arch/core/R;
Virtual methods -
source_file_idx : 24233 (R.java)
观察完这段输出我们可以得到一个结论:
找到函数名后,往前一行输出,就是方法所在的类名
dexdump数据解析
接下来水到渠成,我们看下核心的解析方法
dexdump(){
match_lines=`$buildtool/dexdump -h $1 |grep -n $2|cut -d':' -f1`
#count=`echo $match_lines|wc -l|tr -d '[:space:]'`
if [ "$match_lines" != "" ]; then
echo "### $1" >> ../report.md
$buildtool/dexdump -h $1 > "dump-$1.txt"
line_numbers=(${match_lines//\n/ })
echo "found ${#line_numbers[@]} times"
for i in "${line_numbers[@]}"; do
#echo "===> suggetst class line @ $((i - 1))"
echo "\`\`\`" >> ../report.md
sed -n "$((i - 1)),${i}p" "dump-$1.txt" |cut -d':' -f2 >> ../report.md
echo "\`\`\`" >> ../report.md
done
fi
}
小结
理解dex数据结构,并且使用sdk的工具,可以方便的进行代码特征值的匹配。