大神论坛

找回密码
快速注册
查看: 483 | 回复: 0

[原创] 基于APK文件格式的反编译对抗机制

主题

帖子

9

积分

初入江湖

UID
113
积分
9
精华
威望
18 点
违规
大神币
68 枚
注册时间
2021-06-20 15:17
发表于 2022-03-26 22:07
本帖最后由 南故 于 2022-03-26 22:07 编辑

商业APP为了防止反编译、被篡改,往往会采用第三方的APP加固方案,通过对源代码的混淆、加固、加壳等技术手段,隐藏源APP的逻辑结构,大大提高了反编译的难度,达到保障APP的安全与稳定运行的目的。而网赌、电诈、色情等涉网犯罪APP,基于成本考虑,其幕后的开发者往往不会采用第三方加固方案,但有可能会采用一些无成本的对抗机制,基于APK文件格式的反编译对抗就是其中的一种。该对抗机制主要利用了反编译工具的一些缺陷,导致APK反编译失败(图1)。

笔者研究发现,目前涉网犯罪APP主要利用了两种对抗机制,其一是修改APK文件,其二是修改AndroidManifest文件(AndroidManifest.xml)。两种对抗机制的原理本质上是一样的,都是修改对应二进制文件的一些特征数据,以达到“欺骗”反编译工具的目的,但是Android系统的包安装服务不会检测这些特征数据,因而又不影响APK的正常安装和运行。

一、基于ZIP文件格式的反编译对抗



1、ZIP文件格式



编译后生成的APK文件本质上就是一个ZIP压缩包,可以直接通过解压缩工具打开和解压。一个典型的ZIP文件的二进制数据由三部分组成:数据区、目录区、目录结束标记区。笔者新建一个txt文本文件(demo.txt),写入内容“this is  demo file”,保存后,压缩成一个ZIP文件(demo.zip),然后用十六进制编辑器010 Editor打开。如下图所示,该ZIP文件的二进制内容已被010 Editor识别并按颜色划分为三个不同的区域(黑色区域和灰色区域同属数据区,只是为了突出文件内容):

数据区



数据区记录了所有被压缩文件的内容信息,每个被压缩的文件由文件头、文件内容和文件描述三部分组成。其中,文件头和文件内容必然存在,文件描述则不一定存在。

表 1 文件头

文件头后则是文件内容,而文件描述只有当文件头的通用标记字段的第3位设为1时才会出现,一般在磁盘上存储的ZIP文件都没有文件描述。

目录区



目录区记录了压缩包里所有的子目录的描述信息。

表 2 目录区数据结构

目录结束标记区



目录结束标记区用于标记压缩包目录数据的结束。

表 3 目录结束标记区

2、典型对抗样例



为了不影响APK的正常安装和运行,幕后开发者不可能修改APK文件(ZIP包)的任意内容,而只能修改某些不会被Android包安装服务检测的特征数据,包括通用标记字段的加密标记位、磁盘编号、目录总数等,修改的位置集中在APK文件的头部和尾部。

通用标记字段



修改通用标记字段后,解压APK会提示输入密码,而实际上APK肯定不可能存在密码,否则无法正常安装。破解方法就是将字段改成“00 00”即可(要注意,通用标记字段同时存在于数据区和目录区)。

磁盘编号



修改磁盘编号后,解压文件会提示“头部错误”,这个错误利用的是ZIP文件的“过时缺陷”。ZIP格式诞生于MS-DOS时代,当时由于数据主要存储于软件和光盘,受容量限制,ZIP文件可能需要分盘存储,因此ZIP文件中要记录磁盘编号,因此当前磁盘编号和目录区开始位置磁盘编号可能不一致。而现在ZIP文件都存储在磁盘中,容量足够,无须分盘存储,因此当前磁盘编号和目录区开始位置磁盘编号一致(一般为0)。破解方法就是将当前磁盘编号和目录区开始位置磁盘编号字段都修改成“00 00”。

目录数



类似于磁盘编号,ZIP文件也记录了当前磁盘记录的目录数以及目录总数,修改该字段后也会导致解压APK文件失败。破解方法就是将当前磁盘记录的目录数以及目录总数保持一致,如下图所示把“77 77”修改成“3F 0A”即可: