为什么 gs 段寄存器的地址在 visual studio x64(MASM) 上设置为 0x0000000000000000?

Why the gs segment register is address is set to 0x0000000000000000 on visual studio x64(MASM)?

我目前正在阅读 "The Ultimate Anti Debugging Reference" 并且我正在尝试实施一些技巧。

要检查 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 代码进行了所有正确的调整我使用了 this 教程。

我使用这条指令访问了 NtGlobalFlag

lodsq gs:[rsi]

因为他们的语法不适用于 Visual studio。

但还是不行。

调试时我注意到 gs 寄存器的值设置为 0x0000000000000000 而 fs 寄存器设置为 a实际值 0x0000007595377000.

我不明白为什么 GS 的值被归零,因为它应该在 x64 上设置它的值。

所以我还是不明白为什么贴在这里的代码会引起这么多问题,正如我所说,我只是从“The “Ultimate”Anti-Debugging Reference

 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

但我找到了一个更简单的完美解决方案。

正如@“Peter Cordes”所说的那样,我应该只访问没有 lodsq 的值就好了 -

mov rax, gs:[60h]

经过进一步调查,我发现了这个 reference,

代码-

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 中时,结果 returned 为 0。这意味着没有附加调试器,这是错误的(因为我使用了本地 Windows 调试器)。

但是当使用 WinDBG 启动进程时它确实 return 1 这意味着它有效。

64 位 Windows 显然使用 fs 指向“每线程”内存,因为 gs 为零。除了 rand() 的种子值外,我不知道“每线程”内存中保存了哪些变量。您可以调试使用 rand() 的程序,并在反汇编程序中单步执行它 window,以查看它是如何被访问的。

向程序中添加 anti-debugger 功能是否成功取决于有多少动机去打败它。主要问题是 Windows 远程调试,and/or 在内核模式下使用黑客安装的设备驱动程序 运行 来破坏 anti-debugger 功能。