vs下汇编无法访问FS寄存器


.CODE
GetLdr PROC
        assume fs:nothing     如果加上这个就无法识别    error A2008: syntax error : fs
        mov rax,fs:[60h]       此处 引发的异常: 0xC0000005: 读取位置 0x0000000000000060 时发生访问冲突.
        ret
GetLdr ENDP

END

或者给一份64位用户态下,汇编读取FS寄存器的样例.

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    回答:

    在Visual Studio中使用汇编访问FS寄存器的问题,主要是由于Windows平台下默认情况下无法从用户态访问FS寄存器。因此,我们需要使用Windows API函数来获取FS寄存器的值。以下是一个64位用户态下的汇编代码示例,演示如何读取FS寄存器:

    section .data
        msg db "Hello, world!", 0
    section .text
        global main
    main:
        ; 获取FS寄存器的值
        mov rax, qword [gs:0x30]
    
        ; 访问FS寄存器中的数据例如NT_TIB结构
        mov rax, qword [rax + 0x60]
        ; 将NT_TIB结构中的StackBase地址存储在RCX中
        mov rcx, qword [rax + 0x8]
    
        ; 在栈上分配内存
        sub rsp, 0x1000
    
        ; 将msg字符串复制到栈上
        mov rdi, rsp
        mov rsi, msg
        mov rcx, len(msg)
        rep movsb
    
        ; 打印msg字符串
        mov edx, len(msg)
        mov ecx, rsp
        call print_string
    
        ; 释放栈上的内存
        add rsp, 0x1000
    
        ; 退出程序
        xor eax, eax
        ret
    
    print_string:
        ; 输出msg字符串
        ; 这里省略了具体实现
        ; 可以使用C库函数printf或WinAPI函数WriteConsole等来实现
        ret
    
    len equ $-msg
    

    在这份代码中,我们首先使用GS段寄存器获取NT_TIB结构的基地址,然后从该结构中获取StackBase的地址。接下来,我们使用栈分配内存,并将msg字符串复制到栈上。最后,我们打印msg字符串,并释放在栈上分配的内存。

    请注意,这份代码使用了许多汇编指令和语言结构,并且需要理解Windows API函数的使用。根据具体情况,可能需要进一步的修改和调整。如果有任何疑问,请在下方评论区留言。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

来自GPT的回答:

在 Visual Studio 中的汇编语言文件中,访问 FS 寄存器的语法是正确的。然而,您在代码中遇到的异常(0xC0000005)表明发生了访问冲突。这可能是由以下几个原因导致的:

非法访问:FS 寄存器用于存储线程本地存储(Thread Local Storage, TLS)的基址,它是一个指向线程特定数据的指针。如果在没有初始化 FS 寄存器的情况下尝试访问其内容,就会导致访问冲突。确保在访问 FS 寄存器之前,已正确初始化该寄存器。

访问权限问题:某些情况下,对于某些特殊的寄存器,如 FS 和 GS,访问权限可能受到限制。如果您的代码运行在受限的环境中,可能无法访问 FS 寄存器。请确保您的代码运行在具有足够访问权限的环境中。

操作系统限制:某些操作系统可能限制对 FS 寄存器的访问。这取决于操作系统的安全性策略和内核模式的要求。请确保您的代码在允许访问 FS 寄存器的操作系统环境中运行。

请注意,直接在 C 或 C++ 代码中内嵌汇编通常是不必要的,除非您有特定的原因。大多数情况下,可以使用 C 或 C++ 的标准语法和函数来实现相同的功能。如果您仍然希望在 C 或 C++ 代码中访问 FS 寄存器,可以考虑使用平台相关的机制或库函数来实现。

最后,如果您仍然遇到问题,建议查阅相关的操作系统文档、编译器文档或咨询相关的开发社区以获取更具体的帮助。

或者给一个64位汇编读取fs寄存器的参考代码

这个错误看着像是内存写入的错误,看下是否可以通过改变系统的栈保留空间来解决。在项目、属性、系统中找到堆栈保留大小,修改下看看。
至于你说的提供一份64位用户态下,汇编读取FS寄存器的样例,我给你找到一个资料:
汇编教程十三(64位汇编程序和32位汇编程序的汇编系统调用实验):https://www.cnblogs.com/aozhejin/p/17205723.html
里面有具体的样例,你可以参考下

内联汇编语句(Inline Assembly)。在C/C++代码中嵌入汇编语句,通过编译器的支持间接访问FS寄存器。

#include <stdio.h>

int main() {
    unsigned long long value;
    
    __asm
    {
        mov rax, qword ptr fs:[0x60]
        mov value, rax
    }
    
    printf("FS: [0x60] = 0x%llx\n", value);
    
    return 0;
}

使用__asm关键字将汇编代码嵌入到C代码中。mov rax, qword ptr fs:[0x60]从FS寄存器的偏移量0x60处读取64位数据,并将结果存储在rax寄存器中。然后通过printf函数打印出读取到的值。