C++ 为什么在visual studio x64(MASM)上将gs段寄存器地址设置为0x0000000000000000?
我目前正在阅读,我正在尝试实现一些技术 要检查NtglobalFlag的值,他们使用以下代码-C++ 为什么在visual studio x64(MASM)上将gs段寄存器地址设置为0x0000000000000000?,c++,visual-studio,assembly,masm,masm64,C++,Visual Studio,Assembly,Masm,Masm64,我目前正在阅读,我正在尝试实现一些技术 要检查NtglobalFlag的值,他们使用以下代码- push 60h pop rsi gs:lodsq ;Process Environment Block mov al, [rsi*2+rax-14h] ;NtGlobalFlag and al, 70h cmp al, 70h je being_debugged 我在使用教程的visual studio 2017上运行x64代码时做了所有正确的调整 我使用此指令访问NtGlobalF
push 60h
pop rsi
gs:lodsq ;Process Environment Block
mov al, [rsi*2+rax-14h] ;NtGlobalFlag
and al, 70h
cmp al, 70h
je being_debugged
我在使用教程的visual studio 2017上运行x64代码时做了所有正确的调整
我使用此指令访问NtGlobalFlag
lodsq gs:[rsi]
因为它们的语法在VisualStudio上不起作用
但是,它仍然不起作用
调试时,我注意到gs寄存器的值设置为0x0000000000,fs寄存器的值设置为实值0x0000007595377000
我不明白为什么GS的值被归零,因为它的值应该设置为x64。所以我仍然不明白为什么发布在这里的代码会引起这么多问题,正如我刚才说的,我只是从“the” 但我找到了一个更简单的解决方案,效果非常好 正如"Peter Cordes"所说,我应该善于在没有lodsq的情况下直接获取价值-
mov rax, gs:[60h]
经过进一步调查,我发现了这个
代码-
mov rax, gs:[60h]
mov al, [rax+BCh]
and al, 70h
cmp al, 70h
jz being_debugged
我为我的程序做了一点修改-
.code
GetValueFromASM proc
mov rax, gs:[60h]
mov al, [rax+0BCh]
and al, 70h
cmp al, 70h
jz being_debugged
mov rax,0
ret
being_debugged:
mov rax, 1
ret
GetValueFromASM endp
end
只有一件事需要注意-
在visual studio 2017内部运行时,返回的结果为0。这意味着没有附加调试器,这是错误的(因为我使用了本地Windows调试器)
但是当使用WinDBG启动进程时,它确实返回了1,这意味着它可以工作。64位Windows显然在使用
fs
指向“每线程”内存,因为gs
为零。除了rand()的种子值之外,我不知道“每线程”内存中保存了哪些变量。您可以调试一个使用rand()的程序,并在反汇编程序窗口中单步执行,以查看如何访问它
将反调试器功能添加到程序中的成功与否将取决于有多少动机来阻止它。主要问题是Windows远程调试,和/或使用在内核模式下运行的黑客安装的设备驱动程序来阻止反调试器功能。请注意,
lodsq
修改RSI。您确定要这样做吗?mov-rax,gs:[60]
。请注意,gs
和fs
仅为16位段选择器寄存器。我认为您指的是内部fs和gs基址,只能通过rdgsbase
或使用rdmsr
和MSR\u gs\u base
访问,而不是直接使用普通指令。“gs的值”将是您从mov-eax,gs
获得的,其中0
将是完全正常的(因为操作系统通过MSR或wrgsbase
设置基础,而不是通过创建GDT或LDT条目并执行mov-gs,eax
).至于为什么Windows会这样设置FS和GS基,IDK;我没有要检查的Windows或MSVC。据我所知,lodsq在地址(R)处加载qwordSI into RAX和gs用作段前缀覆盖,使用mov RAX,gs生成一个随机值。是的,然后它将RSI增加8。是的,我在调试窗口中也看到了,这有问题吗?push 60h
和mov RAX,gs:[60]
正在使用不同的地址。很抱歉,您是对的,这是一个输入错误。正如您在我的代码中所能看到的,我使用了60小时。如果您想返回bool
,请使用setz al
而不是分支到mov
指令。(很抱歉在我的原始评论中出现60对60的拼写错误。push 60h/pop/lodsq的代码可能更小,但它肯定不简单,所以看起来太复杂了。)我很高兴你得到了你的解决方案,感谢你的分享,如果你将它们标记为答案,我将不胜感激,这将对其他社区有益。
.code
GetValueFromASM proc
mov rax, gs:[60h]
mov al, [rax+0BCh]
and al, 70h
cmp al, 70h
jz being_debugged
mov rax,0
ret
being_debugged:
mov rax, 1
ret
GetValueFromASM endp
end