题目简介
题目名称:汤姆的苹果
题目类型:Android APK逆向
考察知识点:Android逆向、异或加密、静态分析、Smali字节码理解
解题思路
这是一道典型的Android APK逆向题,主要考察点:
- APK文件结构解析
- Smali字节码的静态分析能力
- 简单异或加密的识别与破解
整体思路:
- 解压/反编译APK获取核心代码
- 定位关键验证逻辑(按钮点击事件处理)
- 识别加密算法
- 暴力破解或还原算法得到flag
详细解题步骤
步骤1:APK文件初步分析
首先将APK作为ZIP解压,观察目录结构:
汤姆的苹果_extracted/
├── AndroidManifest.xml
├── classes.dex # 核心Dalvik字节码
├── res/ # 资源文件
└── META-INF/ # 签名信息
步骤2:定位主Activity和关键代码
使用androguard静态分析,找到主Activity:
from androguard.misc import AnalyzeAPK
a, d, dx = AnalyzeAPK('汤姆的苹果.apk')
print(a.get_main_activity())
# 输出: com.example.myfirstc.MainActivity
MainActivity的onCreate方法逻辑:
- 获取Button控件 (id=2131230807)
- 获取EditText输入框 (id=2131230864)
- 设置点击事件监听器
MainActivity$a
步骤3:深入分析点击事件监听器
MainActivity$a就是按钮点击事件的处理类,它会调用Lb/b/a/b类进行验证。
步骤4:发现核心加密验证逻辑
在Lb/b/a/c类的handleMessage方法中,我们发现了关键的比较逻辑:
# 填充加密后的字符数组
fill-array-data v0, +000001fh
fill-array-data-payload
b'z\x00p\x00}\x00{\x00g\x00v\x00}\x00u\x00o\x00t\x00z\x00$\x00%\x00.\x00/\x00(\x00.\x00-\x00/\x00v\x00w\x00v\x00t\x00a\x00'
提取加密字符串:去掉0字节后得到密文:
zp}{gv}uotz$%./(.-/vwvta
步骤5:分析Lb/b/a/b加密类
在<clinit>、<init>和a方法中,发现了加密流程:
# 异或操作核心代码
aget-char v4, v3, v2
sget v5, Lb/b/a/b;->c I
xor-int/2addr v4, v5 ; v4 = v4 XOR v5
int-to-char v4, v4
aput-char v4, v3, v2
步骤6:识别加密算法
通过分析,我们发现这是固定值单字节异或加密:
明文每个字符 ↔ 异或 ↔ 固定密钥值 ↔ 比较密文
步骤7:暴力破解密钥
由于是单字节异或,直接暴力枚举0-255所有可能:
encrypted = [ord(c) for c in 'zp}{gv}uotz$%./(.-/vwvta']
for key in range(256):
result = []
valid = True
for b in encrypted:
d = b ^ key
if d < 32 or d > 126:
valid = False
break
result.append(chr(d))
if valid:
flag = ''.join(result)
if '{' in flag and '}' in flag:
print(f'密钥 {key}: {flag}')
运行结果:
密钥 28 (0x1c): flag{jaishf89234213jkjh}
步骤8:验证解密正确性
手动验证解密过程(前6个字符):
| 位置 | 密文 | ASCII | 密钥 | 异或结果 | 明文 |
| 0 | z | 122 | 28 | 122 ^ 28 = 102 | f |
| 1 | p | 112 | 28 | 112 ^ 28 = 108 | l |
| 2 | } | 125 | 28 | 125 ^ 28 = 97 | a |
| 3 | { | 123 | 28 | 123 ^ 28 = 103 | g |
| 4 | g | 103 | 28 | 103 ^ 28 = 123 | { |
| 5 | v | 118 | 28 | 118 ^ 28 = 106 | j |
前6字符解密结果:flag{j,格式正确!
最终Flag
flag{jaishf89234213jkjh}
解题总结
本题考点
- Android逆向基础:理解APK结构、dex文件、Smali字节码
- 静态分析能力:能够通过字节码分析出程序流程
- 密码学基础:识别并破解简单的异或加密
- 工具使用:androguard、androguard等逆向工具的使用
关键突破点
- 定位
handleMessage方法:这里存储了加密后的字符数组 - 识别异或加密:
xor-int/2addr指令是关键提示 - 暴力破解:单字节异或的密钥空间只有256种可能,暴力破解完全可行
可能的坑点
- 误以为是多字节异或(密钥是数组),浪费时间
- 误以为密钥是"tomato"或"apple"等题目相关关键词,走弯路
- 忽略了
fill-array-data-payload中的0字节
解题脚本
完整的解密Python脚本:
# 加密字符串从smali中提取,去除0字节
encrypted_str = 'zp}{gv}uotz$%./(.-/vwvta'
encrypted = [ord(c) for c in encrypted_str]
# 单字节异或暴力破解
for key in range(256):
flag = ''.join([chr(b ^ key) for b in encrypted])
if 'flag{' in flag and '}' in flag:
print(f'密钥={key}')
print(f'Flag={flag}')
break
运行结果:
密钥=28
Flag=flag{jaishf89234213jkjh}