【问题标题】:Visual Studio 2013 /GH /Gh _penter/_pexit 64bit how to save registers?Visual Studio 2013 /GH /Gh _penter/_pexit 64bit 如何保存寄存器?
【发布时间】: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 分析器将从结果中删除这些 - 所以我最终什么都没有。

标签: assembly visual-studio-2013 inline-assembly


【解决方案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 中的内联汇编代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-15
      • 2022-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多