Visual Studio 2013 /GH /Gh _penter/_pexit 64bit 如何保存寄存器?

Posted

技术标签:

【中文标题】Visual Studio 2013 /GH /Gh _penter/_pexit 64bit 如何保存寄存器?【英文标题】:Visual Studio 2013 /GH /Gh _penter/_pexit 64bit how to save registers? 【发布时间】:2014-05-23 11:32:24 【问题描述】:

我在 VS2013 中使用以下编译器选项:

/Gh(启用_penter挂钩功能)

http://msdn.microsoft.com/en-us/library/c63a9b7h.aspx

/GH(启用 _pexit 挂钩功能) http://msdn.microsoft.com/en-us/library/xc11y76y.aspx

当我尝试为我的代码实现一些基本分析时。但是对于 64 位编译器,它不可能使用裸属性:

http://msdn.microsoft.com/en-us/library/h5w10wxs.aspx

我不认为这真的是个问题,但问题是我找不到保存寄存器的方法,因为此编译器不支持内联汇编。因此,如果更改任何寄存器,那么它们的值就会被丢弃。例如:

; int __cdecl DllMain(void *hModule, unsigned int ulReason, _CONTEXT *pContext)
push    rbx
sub     rsp, 20h
call    _penter

这里我们必须确保 _penter 不会破坏 rsp 的值:

; int __cdecl penter(LARGE_INTEGER PerformanceCount)
PerformanceCount= LARGE_INTEGER ptr  8

sub     rsp, 28h
xor     eax, eax
lea     rcx, [rsp+28h+PerformanceCount] ; lpPerformanceCount
mov     qword ptr [rsp+28h+PerformanceCount], rax
call    cs:__imp_QueryPerformanceCounter
add     rsp, 28h
retn
_penter endp

在这种情况下,_penter 正在修复 rsp 是可以的 - 但是 eax 和 rcx 的值被覆盖了。在 x86 编译器中,我可以简单地添加内联 asm 来推送和弹出这些寄存器。如何在 x64 编译器中做到这一点?

【问题讨论】:

并不是说您不能继续编写自己的分析器,而是 Visual Studio 附带了一个基于采样和检测的分析器 我正在分析迂回的 win32 api 函数,VS 分析器将从结果中删除这些 - 所以我最终什么都没有。 【参考方案1】:

这实际上是 MSVC x64 的一个问题,它不尊重 _penter/_pexit 函数的非裸(x64 中不存在)声明。

下面是我如何解决此问题的示例(不仅您必须保存易失性寄存器的内容,这些寄存器的内容被认为会被调用破坏,而且标志寄存器也必须保存,因为 _penter/_pexit 可能会被插入- 依赖于标志的汇编命令之间;这只能在单独的汇编文件中完成,因为 MSVC 在 x64 中不提供内联汇编):

PUSHREGS    macro
    push    rax
    lahf
    push    rax
    push    rcx
    push    rdx
    push    r8
    push    r9
    push    r10
    push    r11
endm

POPREGS macro
    pop r11
    pop r10
    pop r9
    pop r8
    pop rdx
    pop rcx
    pop rax
    sahf
    pop rax
endm

...

profile_enter   proc
    PUSHREGS
    ; > your code goes here. Be aware that it must preserve any non-volatile registers used and align the stack pointer for any calls made.
    POPREGS
    ret
profile_enter   endp

您还可以在此处查看工作代码: https://github.com/tyoma/micro-profiler/blob/master/micro-profiler/collector/hooks.asm

【讨论】:

【参考方案2】:

您必须将您的汇编代码移至 .asm 文件,因为 Visual Studio 不支持 x64 中的内联汇编代码。

【讨论】:

以上是关于Visual Studio 2013 /GH /Gh _penter/_pexit 64bit 如何保存寄存器?的主要内容,如果未能解决你的问题,请参考以下文章

用于 penter 和 pexit 的 Visual Studio 宏

Visual Studio 2013 Apache Cordova 更改未应用

Microsoft Visual Studio 2013 链接错误 1104

Visual Studio 2010 未生成 SharePoint 2010 WebPart .g.cs 文件

Visual Studio C++11g 编译错误 - 初始化程序太多

visual studio vb.net 转到行短键(Ctrl + G)不起作用?