在 Smali 代码中插入 Log

1. 准备工作

工具准备:

  • Apktool:用于反编译和重新打包 APK
  • 签名工具:jarsigner(JDK 自带)或 apksigner(Android SDK 提供)
  • 调试工具:adb logcat 查看日志

操作流程:
反编译 APK -> 修改 Smali 代码 -> 重新打包 -> 签名 -> 安装测试

2. 反编译 APK

1
apktool d target.apk -o output_dir

反编译后,Smali 代码位于 output_dir/smali 目录中

3. 在 Smali 代码中插入日志

3.1. 定位目标代码

  • 通过逆向工具(如 Jadx)分析目标代码的大致位置,找到对应的 Smali 文件
  • 例如:目标代码在 com.example.MainActivity,则 Smali 文件为:
  • smali/com/example/MainActivity.smali

3.2. 插入日志的 Smali 指令

在 Smali 中调用Log.d()需要以下步骤:

  1. 定义 TAG(可选):在类中定义一个静态字符串作为 TAG
  2. 加载参数:将 TAG 和日志内容加载到寄存器
  3. 调用静态方法:执行Log.d(TAG, message)

示例:在方法中插入日志代码

1
2
3
4
5
6
7
8
9
# 原始代码(假设在方法 .method public onCreate()V 内)
.line 10
const/4 v0, 0x1
iput-boolean v0, p0, Lcom/example/MainActivity;->isReady:Z

# 插入日志代码(添加如下指令)
const-string v1, "MyTag" # 定义 TAG
const-string v2, "Debug message" # 日志内容
invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

3.3. 注意事项

  • 寄存器冲突:确保v1v2等寄存器未被占用(根据上下文调整寄存器编号)
  • 参数顺序:Log.d()的第一个参数是TAG (String),第二个参数是message (String)

4. 重新打包 APK

1
apktool b output_dir -o unsigned.apk

生成的unsigned.apk是未签名的 APK

5. 签名 APK

5.1. 生成签名密钥(若无可跳过,使用已有密钥)

1
keytool -genkey -v -keystore mykey.keystore -alias myalias -keyalg RSA -keysize 2048 -validity 10000

5.2. 使用 jarsigner 签名

1
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore mykey.keystore unsigned.apk myalias

输出文件为signed.apk

5.3. 使用 apksigner 签名(推荐)

1
apksigner sign --ks mykey.keystore --ks-key-alias myalias signed.apk unsigned.apk

6. 安装并测试

1
2
adb install signed.apk
adb logcat -s "MyTag" # 过滤日志

7. 常见问题与解决

7.1. 应用崩溃或无法启动

  • 原因:Smali 代码修改错误(如寄存器冲突、指令格式错误)
  • 解决:
    1. 检查插入的 Smali 指令语法
    2. 使用adb logcat查看崩溃日志(过滤 AndroidRuntime)

7.2. 日志未输出

  • 原因:
    • 代码未被执行(断点位置错误)
    • 日志 TAG 过滤错误
  • 解决:
    1. 检查插入日志的代码路径是否触发
    2. 使用adb logcat -s MyTag:*确保过滤正确

7.3. 签名后安装失败

  • 原因:签名不兼容或 APK 未对齐
  • 解决:
    1. 使用zipalign对齐 APK:zipalign -v 4 unsigned.apk aligned.apk
    2. 确保使用apksigner而非旧版jarsignerjarsigner仅支持 V1 签名,需改用apksigner生成 V2/V3 签名

8. 完整操作流程示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1. 反编译 APK(使用 Apktool)
apktool d original.apk -o decoded

# 2. 修改 Smali 代码后重新打包
apktool b decoded -o unsigned.apk

# 3. 对齐 APK
zipalign -v 4 unsigned.apk aligned.apk

# 4. 删除旧签名信息(避免冲突)
zip -d aligned.apk 'META-INF/*'

# 5. 使用 apksigner 签名
apksigner sign \
--ks mykey.keystore \
--ks-key-alias myalias \
--out signed.apk \
aligned.apk

# 6. 验证签名
apksigner verify -v signed.apk

# 7. 安装测试
adb install signed.apk

如果无法安装 zip,可以通过以下方式手动删除 META-INF 文件夹:

  1. 使用解压工具(如 7-Zip、WinRAR)打开 aligned.apk
  2. 删除 META-INF 文件夹
  3. 保存并关闭