Assembly 64位上的fnstenv返回错误值?

Assembly 64位上的fnstenv返回错误值?,assembly,x86-64,shellcode,x87,Assembly,X86 64,Shellcode,X87,我正在使用fnstenvFPU指令获取64位外壳代码中的EIP。在GDB中运行它一切看起来都很好: 0x0000000000400080 ? fldz 0x0000000000400082 ? fnstenv [rsp-0xc] 通过使用si单步执行这些指令后,我在堆栈中得到正确的值(0x0000000000400082) 我错过的是:如果我在fnstenv之后放置一个断点,然后使用continue在它们之间没有断点的情况下执行,我会得到一个错误的值:0x000000330040

我正在使用
fnstenv
FPU指令获取64位外壳代码中的EIP。在GDB中运行它一切看起来都很好:

 0x0000000000400080  ? fldz   
 0x0000000000400082  ? fnstenv [rsp-0xc]
通过使用
si
单步执行这些指令后,我在堆栈中得到正确的值(0x0000000000400082)

我错过的是:如果我在
fnstenv
之后放置一个断点,然后使用
continue
在它们之间没有断点的情况下执行,我会得到一个错误的值:0x0000003300400082。 0x00000033是CS寄存器的值…不确定这是否是巧合

我使用nasm和ld的语法如下:

nasm -f elf64 shell.asm -o shell.o
ld shell.o -o sh --omagic

你能提供完整的源代码吗?
fnstenv
不支持64位,所以你只能得到RIP的32位低位,正如你所说的,这是EIP,但打印错误了。下面的单词确实包含
CS
选择器。也就是说,
gdb
在使用
si
时确实表现得很奇怪,我甚至没有得到有效的转储。正确的行为是第二个。PS:lea-rax,[rip]的内容有什么问题吗?请注意,您需要28字节的内存,因此即使与当前问题无关,
rsp-0xc
也非常可疑。这是完整的源代码。我不能使用lea,因为我在操作码中有一些限制,所以我使用它…但是如果它不适用于64位,我想我需要找到另一种方法。有
fxsave64
,但这对我根本不起作用。当然你可以做
syscall
?将
rcx
设置为
rip