You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Visual Studio x64(MASM)中GS段寄存器为何被设为0x0000000000000000?

解决x64环境下GS寄存器为0及NtGlobalFlag反调试失效问题

嘿,我之前折腾反调试技术的时候也碰到过一模一样的问题,来给你掰扯清楚:

首先得纠正一个关键误解:**x64 Windows的用户态程序里,GS寄存器默认就是0!**这完全不是异常情况——GS段在内核态才用来访问KPCR(内核处理器控制区),而用户态下我们要获取PEB(进程环境块),靠的是FS段寄存器,你看到FS有有效值才是正常的,之前把FS和GS的用户态用途搞混啦。

回到你的代码问题:书中的写法大概率是针对NASM这类汇编器的语法,而VS2017用的MASM语法有差异,再加上x64下PEB的访问路径不对,才导致失效。咱们一步步修正:

适配VS2017 MASM的x64 NtGlobalFlag检测代码

; 获取PEB指针:x64用户态下,FS:[0x30] 直接指向PEB的地址
mov rax, qword ptr fs:[0x30]
; 读取NtGlobalFlag字段(PEB的偏移量在Win10/11 x64下通常是0xBC,你也可以通过调试器确认)
mov al, byte ptr [rax + 0xBC]
; 检测调试标记组合:0x70对应三个调试相关的Flag位
and al, 0x70
cmp al, 0x70
je being_debugged  ; 如果匹配,说明正在被调试

你的原代码失效的核心原因

  • GS寄存器的认知错误:用户态x64程序里GS=0是标准行为,别把它和内核态的GS用法混淆,用户态访问PEB只能靠FS段。
  • MASM语法不兼容:书中的gs:lodsq是NASM风格的段前缀写法,MASM里的段前缀应该写在括号前,比如fs:[...],你改成lodsq gs:[rsi]既不符合MASM语法,还选错了段寄存器。

最后补个小tip:不同Windows版本的PEB结构可能有微小偏移变化,你可以用x64dbg加载程序后,查看fs:[0x30]指向的内存,手动确认NtGlobalFlag的准确偏移,确保万无一失。

内容的提问来源于stack exchange,提问作者Cyber_Noob

火山引擎 最新活动