MSVC中有编译器选项,可以在进入和退出函数时自动生成检测调用。这些钩子称为_penter()和_pexit()。编译器的选项是:
/ Gh启用_penter Hook功能
/ GH启用_pexit挂钩功能
是否有一个pragma或某种函数声明会在每个函数的基础上关闭仪器?我知道使用__declspec(裸)函数不会被检测,但这并不总是一个非常实用的选项。我在PC和非X86平台上都使用MSVC,非X86平台很难在汇编程序中手动编写epilog / prolog(更不用说它会混淆调试器堆栈跟踪)。
如果只在每个文件(编译器选项)的基础上,我想我必须将特殊功能拆分成一个单独的文件来关闭该选项,但如果我能控制它就会容易得多在每个文件的基础上。
如果不能做到这一点,后备计划只是将功能移动到他们自己的CPP翻译单元,并在没有选项的情况下单独编译。
答案 0 :(得分:2)
我认为没有办法做到这一点。鉴于您无论如何都必须找到并处理每个受影响的函数,或许将它们移动到自己的模块中并不是一件大事。
答案 1 :(得分:0)
Asker 知道,但值得写出不合格的方法以供将来参考。 /Gh 和 /GH 不检测裸函数。您可以将要选择退出的函数声明为裸函数并手动提供 standard prolog/epilog,如下所示,
void instrumented_fn(void *p)
{
/* Function body */
}
__declspec(naked) void uninstrumented_fn(void *p)
{
__asm
{
/* prolog */
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
}
/* Function body */
__asm
{
/* epilog */
mov esp, ebp
pop ebp
ret
}
}
检测函数反汇编示例,显示对 penter 和 pexit 的调用,
537b0: e8 7c d9 ff ff call 0x51131
537b5: 55 push %ebp
537b6: 8b ec mov %esp,%ebp
537b8: 83 ec 40 sub $0x40,%esp
537bb: 53 push %ebx
537bc: 56 push %esi
537bd: 57 push %edi
537be: 90 nop
537bf: 90 nop
537c0: 90 nop
537c1: 5f pop %edi
537c2: 5e pop %esi
537c3: 5b pop %ebx
537c4: 8b e5 mov %ebp,%esp
537c6: 5d pop %ebp
537c7: e8 01 d9 ff ff call 0x510cd
537cc: c3 ret
等效的未插装函数反汇编(裸体加标准 prolog/epilog)
51730: 55 push %ebp
51731: 8b ec mov %esp,%ebp
51733: 83 ec 40 sub $0x40,%esp
51736: 90 nop
51737: 90 nop
51738: 90 nop
51739: 8b e5 mov %ebp,%esp
5173b: 5d pop %ebp
5173c: c3 ret