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 文件