硕士生
 
- 金币
- 1862
- 好评
- 3
- 信誉
- 100
|
发表于
2026-7-7 20:00:44
|
显示全部楼层
来自 湖南
通过静态分析还原的,不是动态 dump。
核心流程:
1. 先看 DEX
`classes.dex` 里只有一个类:
`Lcc/binmt/simpleapp/MainActivity;`
方法列表显示:
- `<clinit>()V`:加载 `libhvmp.so`
- `<init>()V`:普通构造
- `onCreate(Bundle)`:native
- `onClick(View)`:native
也就是说 VMP 后两个 Java 方法被改成了 native,由 `libhvmp.so` 执行。
2. 分析壳库 JNI 导出
`libhvmp.so` 里有两个静态导出:
- `Java_cc_binmt_simpleapp_MainActivity_onCreate`
- `Java_cc_binmt_simpleapp_MainActivity_onClick`
对应被 VMP 的两个方法。
3. 提取壳内明文元数据
这个样本的 VM 元数据和常量没有完全加密,SO 里能直接看到关键内容,包括:
- `Lcc/binmt/simpleapp/MainActivity;->onClick(Landroid/view/View;)V`
- `Lcc/binmt/simpleapp/MainActivity;->onCreate(Landroid/os/Bundle;)V`
- `Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V`
- `setContentView(I)V`
- `findViewById(I)Landroid/view/View;`
- `setOnClickListener(...)`
- `EditText.getText()`
- `Object.toString()`
- `String.equals(Object)`
- `Toast.makeText(...)`
- `Toast.show()`
- `EditText.setText(CharSequence)`
- `EditText.setVisibility(I)`
- `LinearLayout.setGravity(I)`
- `ObjectAnimator.ofFloat(Object,String,[F)`
- `ObjectAnimator.setRepeatCount(I)`
- `ObjectAnimator.start()`
- 字符串:`123456`
- 字符串:`rotation`
- 字符串:`请输入:123456`
4. 对照资源表还原 ID
`resources.arsc` 里资源 ID 是:
- `R.id.button = 0x7f010000`
- `R.id.container = 0x7f010001`
- `R.id.editText = 0x7f010002`
- `R.layout.activity_main = 0x7f020000`
- `R.string.success = 0x7f040001`
布局里是一个 `LinearLayout`,里面一个 `EditText` 和一个 `Button`。
5. 从 VM 字节码常量和调用序列恢复逻辑
壳内能看到两个方法对应的 VM 指令块。
`onCreate` 的调用序列很短,恢复为:
- 调用 `super.onCreate(bundle)`
- `setContentView(R.layout.activity_main)`
- `findViewById(R.id.button)`
- 给 Button 设置 `OnClickListener` 为当前 Activity
`onClick` 的调用序列恢复为:
- 找到 `editText`
- 取输入文本
- 转成字符串
- 和 `"123456"` 比较
- 如果正确:
- toast `R.string.success`
- 隐藏 EditText
- 取按钮父布局
- 设置父布局居中
- 对按钮创建 rotation 动画
- 重复次数设为 `-1`
- 启动动画
- 如果错误:
- EditText 设置为 `"请输入:123456"`
- toast 同样文本
6. 回填 smali
用 `dex_batch` 把两个 native 方法替换回普通 Java 方法体:
- `onCreate(Bundle)` 回填 smali
- `onClick(View)` 回填 smali
- `<clinit>()` 改成空实现,避免再加载壳库
7. 去壳
删除:
`lib/arm64-v8a/libhvmp.so`
然后重签 APK。
8. 校验和安装测试
- DEX check 通过
- APK 安装成功
- Activity 启动成功
所以这次能还原,主要原因是这个样本很小,而且 VMP 壳里保留了足够完整的调用元数据、字符串、资源 ID 和执行序列。没有靠猜函数名硬补,而是按 SO 里的 VM 元数据和资源表交叉还原。 |
|