Qemu中helper机制的理解

发布时间 2023-08-09 10:30:41作者: 太极者

因为项目中准备使用AFL++ + Qemu下,所以研究了其中AFL++下的Qemuafl的源码,其中插桩的方式与AFL原理一样,但是代码相差很大,因此记录一下。

qemuafl中桩点基本逻辑
1) qemuafl是AFL++直接fork了一份Qemu的源码,在Qemu的源码中直接进行代码修改。
2) 其中使用每个基本块的PC来作为每个基本块的桩点信息。
3) qemuafl直接在TCG的翻译阶段,将桩点代码生成为IR指令,嵌入到每个基本块的TCG-IR开始。
4) 这样子在执行TCG-IR的时候,装点代码就被直接运行了,很巧妙。

qemuafl中将桩点代码插入TCG-IR的方式即使用了Qemu的helper机制,以下说明helper机制。
参考:[http://blog.terrynini.tw/en/2021-QEMU-AFL-and-TCG/]()

1)首先进行宏声明
    DEF_HELPER_FLAGS_1(afl_maybe_log, TCG_CALL_NO_RWG, void, tl)

2)DEF_HELPER_FLAGS_1的声明在两个地方(没太明白qemuafl为啥这么做!!!)
     exec/helper-proto.h

     #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
     dh_ctype(ret) HELPER(name) (dh_ctype(t1));

3) 但是在exec/helper-proto.h文件的末尾,又使用了#undef DEF_HELPER_FLAGS_1

4) 实际定义的地方
    exec/helper-gen.h
    #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
   static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
        dh_arg_decl(t1, 1)) \
   { \
         TCGTemp *args[1] = { dh_arg(t1, 1) }; \
         tcg_gen_callN(HELPER(name), dh_retvar(ret), 1, args); \
    }
5) 宏定义中,调用了tcg_gen_callN函数,这个函数是作用是生成IR指令。这个函数的第一个参数HELPER(name),
   其作用是生成一个helper作为前面的函数名,对于name为afl_maybe_log,则这里的HELPER(afl_maybe_log)
    就是helper_afl_maybe_log,并将这个函数生成IR指令。
6) 而宏DEF_HELPER_FLAGS_1,对于name为afl_maybe_log,则声明一个名为gen_helper_afl_maybe_log的函数。
7) 总结来说,gen_helper_afl_maybe_log函数是为了生成名为helper_afl_maybe_log的函数调用的IR指令。