NASM: 将指针从寄存器复制到 .data 中的缓冲区
NASM: copying a pointer from a register to a buffer in .data
我是 asm 的新手。我正在尝试在 linux 64 位上使用 NASM 将指针从寄存器复制到 .data
变量。
考虑这个程序:
section .data
ptr: dq 0
section .text
global _start
_start:
mov [ptr], rsp
mov rax, 60
mov rdi, 0
syscall
这里我尝试将当前栈指针复制到ptr
。 ptr
声明为四字。 nasm
和链接器都没有抱怨,但是当用 gdb 调试程序时,我可以看到两个地址不同:
gdb ./test.s
+(gdb) break _start
Breakpoint 1 at 0x4000b0
+(gdb) run
Starting program: test
Breakpoint 1, 0x00000000004000b0 in _start ()
+(gdb) nexti
0x00000000004000b8 in _start ()
+(gdb) info registers
...
rsp 0x7fffffffe460 0x7fffffffe460
...
+(gdb) x ptr
0xffffffffffffe460: Cannot access memory at address 0xffffffffffffe460
据我了解,mov
应该将所有 64 位从 rsp
复制到 [ptr]
,但似乎最重要的 0
没有被复制 and/or 有某种符号扩展,好像只复制了最低有效位。
+(gdb) x/h ptr
h
表示half-word,也就是两个字节。你要的大概是g
(GDB术语中的Giant words,也就是八个字节)。
问题是,您没有 ptr
类型的调试信息,因此 gdb
将其视为整数。您可以使用以下方法检查其真实内容:
(gdb) x/a &ptr
0x600124 <ptr>: 0x7fffffffe950
(gdb) p/a $rsp
= 0x7fffffffe950
当然我对 rsp
的值与你不同,但你可以看到 ptr
和 rsp
匹配。
看来你对我的 gdb 使用有误:
section .data
ptr: dq 0
section .text
global main
main:
mov [ptr], rsp
ret
编译:
rm -f test.o && nasm -f elf64 test.asm && gcc -m64 -o test test.o
然后我的调试会话如下所示:
gdb ./test
(...)
(gdb) break main
Breakpoint 1 at 0x4004c0
(gdb) run
Starting program: /home/rr-/test
Breakpoint 1, 0x00000000004004c0 in main ()
(gdb) nexti
0x00000000004004c8 in main ()
(gdb) info registers
rax 0x4004c0 4195520
rbx 0x0 0
rcx 0x0 0
rdx 0x7fffffffe388 140737488348040
rsi 0x7fffffffe378 140737488348024
rdi 0x1 1
rbp 0x4004d0 0x4004d0 <__libc_csu_init>
rsp 0x7fffffffe298 0x7fffffffe298
(...)
(gdb) info addr ptr
Symbol "ptr" is at 0x600880 in a file compiled without debugging.
(gdb) x/g 0x600880
0x600880: 140737488347800
140737488347800 计算为 0x7FFFFFFFE298 就好了。
我是 asm 的新手。我正在尝试在 linux 64 位上使用 NASM 将指针从寄存器复制到 .data
变量。
考虑这个程序:
section .data
ptr: dq 0
section .text
global _start
_start:
mov [ptr], rsp
mov rax, 60
mov rdi, 0
syscall
这里我尝试将当前栈指针复制到ptr
。 ptr
声明为四字。 nasm
和链接器都没有抱怨,但是当用 gdb 调试程序时,我可以看到两个地址不同:
gdb ./test.s
+(gdb) break _start
Breakpoint 1 at 0x4000b0
+(gdb) run
Starting program: test
Breakpoint 1, 0x00000000004000b0 in _start ()
+(gdb) nexti
0x00000000004000b8 in _start ()
+(gdb) info registers
...
rsp 0x7fffffffe460 0x7fffffffe460
...
+(gdb) x ptr
0xffffffffffffe460: Cannot access memory at address 0xffffffffffffe460
据我了解,mov
应该将所有 64 位从 rsp
复制到 [ptr]
,但似乎最重要的 0
没有被复制 and/or 有某种符号扩展,好像只复制了最低有效位。
+(gdb) x/h ptr
h
表示half-word,也就是两个字节。你要的大概是g
(GDB术语中的Giant words,也就是八个字节)。
问题是,您没有 ptr
类型的调试信息,因此 gdb
将其视为整数。您可以使用以下方法检查其真实内容:
(gdb) x/a &ptr
0x600124 <ptr>: 0x7fffffffe950
(gdb) p/a $rsp
= 0x7fffffffe950
当然我对 rsp
的值与你不同,但你可以看到 ptr
和 rsp
匹配。
看来你对我的 gdb 使用有误:
section .data
ptr: dq 0
section .text
global main
main:
mov [ptr], rsp
ret
编译:
rm -f test.o && nasm -f elf64 test.asm && gcc -m64 -o test test.o
然后我的调试会话如下所示:
gdb ./test
(...)
(gdb) break main
Breakpoint 1 at 0x4004c0
(gdb) run
Starting program: /home/rr-/test
Breakpoint 1, 0x00000000004004c0 in main ()
(gdb) nexti
0x00000000004004c8 in main ()
(gdb) info registers
rax 0x4004c0 4195520
rbx 0x0 0
rcx 0x0 0
rdx 0x7fffffffe388 140737488348040
rsi 0x7fffffffe378 140737488348024
rdi 0x1 1
rbp 0x4004d0 0x4004d0 <__libc_csu_init>
rsp 0x7fffffffe298 0x7fffffffe298
(...)
(gdb) info addr ptr
Symbol "ptr" is at 0x600880 in a file compiled without debugging.
(gdb) x/g 0x600880
0x600880: 140737488347800
140737488347800 计算为 0x7FFFFFFFE298 就好了。