redex-aop
Introduction: A bytecode optimizer for Android apps
Tags:
特性
- 灵活,可以使用 js 脚本操作 dex,bytecode
- 使用内置的字节码描述语言来编写插桩代码。封装了 dalvik bytecode 中的一些复杂特性,比如
-range
指令等。
编译
mkdir build
cd build
cmake .. -G Ninja
ninja
DEMO
在每个函数前面插入一段Log.d
插桩脚本例子
function process_all_classes(all_classes) {
for (let i in all_classes) {
let cls_def = all_classes[i];
std.printf("class name:%s\n", cls_def.c_str())
cls_def.get_all_methods().forEach(m => {
std.printf("%s.%s\n", cls_def.c_str(), m.c_str())
//找到第一条指令,在这条指令前面插入
let ircode = m.get_code();
if (!ircode) {
return;
}
let first_pos = null
code_utils.iterate_code(ircode, (it) => {
if (!opcode.is_a_load_param(it.insn.opcode())) {
first_pos = it;
return true;
}
return false;
})
// 构造要插桩的 code
let insert_code = `
(
(new-instance "Ljava/lang/StringBuilder;")
(move-result-pseudo-object v0)
(invoke-direct
(v0) "Ljava/lang/StringBuilder;.<init>:()V")
(const-string "${cls_def.c_str()}")
(move-result-pseudo-object v1)
(invoke-virtual
(v0 v1) "Ljava/lang/StringBuilder;.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;")
(const-string "${m.c_str()}")
(move-result-pseudo-object v2)
(move-object v3 v1)
(move-object v1 v2)
(invoke-virtual
(v0 v1) "Ljava/lang/StringBuilder;.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;")
(move-object v1 v3)
(invoke-virtual
(v0) "Ljava/lang/StringBuilder;.toString:()Ljava/lang/String;")
(move-result-object v0)
(const-string "dodola")
(move-result-pseudo-object v1)
(move-object v2 v0)
(invoke-static
(v1 v2) "Landroid/util/Log;.d:(Ljava/lang/String;Ljava/lang/String;)I")
(return-void)
)
`;
let dummy_code = code_utils.ircode_from_string(insert_code);
code_utils.inject_code_after(ircode, dummy_code, first_pos, [])
});
}
}
插桩配置
{
"redex": {
"passes": [
"MethodAopPass"
]
},
"MethodAopPass": {
"js_file": "../test/aop/test.js"
},
"ir_type_checker": {
"run_after_each_pass": false,
"verify_moves": false,
"check_no_overwrite_this": false
}
}
注意
:需要关闭 overwrite_this
,verify_moves
检查。
cd build
./redex-all -c ../test/aop/redexjs.json ../test/aop/classes.dex -o ../test/aop/opt/
插桩后:
后续计划
- 完成插桩代码的参数传递,比如
iget
之后获取到内存寄存器 - 完善 JS API,将大部分
redex api
通过js api
的形式开放出去,后续可以使用 js 完成 pass 的编写
License
The ReDex repository is available under the MIT License.