是否可以在每个函数的基础上禁用 MSVC _penter 和 _pexit 挂钩?

发布于 2024-09-27 11:22:46 字数 459 浏览 4 评论 0原文

MSVC 中有编译器选项,可以在进入和退出函数时自动生成检测调用。这些钩子称为 _penter() 和 _pexit()。编译器的选项有:

/Gh 启用_penter钩子函数

/GH启用_pexit挂钩功能

是否有编译指示或某种函数声明可以在每个函数的基础上关闭检测?我知道使用 __declspec(naked) 函数不会被检测,但这并不总是一个非常实用的选择。我在 PC 和非 X86 平台上都使用 MSVC,在非 X86 平台上在汇编器中手动编写 Epilog/Prolog 很痛苦(更不用说它会扰乱调试器堆栈跟踪)。

如果这仅在每个文件(编译器选项)的基础上,我想我将不得不将特殊功能拆分到一个单独的文件中以关闭该选项,但如果我可以在每个文件上控制它会更容易文件依据。

如果无法做到这一点,后备计划是将函数移动到它们自己的 CPP 翻译单元,并在没有选项的情况下单独编译。

There are compiler options in MSVC to enable the automatic generation of instrumentation calls on entering and exiting functions. These hooks are called _penter() and _pexit(). The options to the compiler are:

/Gh Enable _penter Hook Function

/GH Enable _pexit Hook Function

Is there a pragma or some sort of function declaration that will turn off the instrumentation on a per function basis? I know that using __declspec(naked) functions will not be instrumented but this isn't always a very practical option. I'm using MSVC both on PC and on a non-X86 platform and the non-X86 platform is a pain to manually write epilog/prolog in assembler (not to mention it messes up the debugger stack tracing).

If this in only on a per file (compiler option) basis, I think I will have to split out the special functions into a separate file to turn the option off but it'd be much easier if I could just control it on a per file basis.

The fallback plan if this can't be done is to just move the functions to their own CPP translation unit and compile separately without the options.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

攒一口袋星星 2024-10-04 11:22:46

我看不出有什么办法可以做到这一点。考虑到无论如何您都必须找到并处理每个受影响的函数,也许将它们移动到自己的模块中并不是什么大问题。

I don't see any way to do this. Given that you would have to locate and handle every affected function anyway, perhaps moving them into their own module(s) is not such a big deal.

放肆 2024-10-04 11:22:46

Asker 知道,但值得写出不合格的方法以供将来参考。 /Gh 和 /GH 不检测裸函数。您可以将要选择退出的函数声明为裸函数,并手动提供 标准 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    

等效的未插装函数反汇编(裸体加上标准序言/结语)

   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   

Asker is aware, but worth writing out the disqualified approach for future reference. /Gh and /GH do not instrument naked functions. You can declare the function you want to opt-out for as naked and manually supply the standard prolog/epilog, as shown below,

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
    }
}

An example instrumented function disassembly, showing calls to penter and 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    

The equivalent uninstrumented function disassembly (naked body plus standard 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   
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文