Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 为什么以下装配顺序信号会显示?_Assembly_X86 64 - Fatal编程技术网

Assembly 为什么以下装配顺序信号会显示?

Assembly 为什么以下装配顺序信号会显示?,assembly,x86-64,Assembly,X86 64,在0x7fffffffdbe4之前,这些指令都是有效的,此时程序已经调用exit syscall gdb) x/20i $rip => 0x7fffffffdbb0: movabs rax,0x2168732f6e69622f 0x7fffffffdbba: push rax 0x7fffffffdbbb: lea rdi,[rsp] 0x7fffffffdbbf: xor rax,rax 0x7fff

在0x7fffffffdbe4之前,这些指令都是有效的,此时程序已经调用exit syscall

gdb) x/20i $rip
    => 0x7fffffffdbb0:  movabs rax,0x2168732f6e69622f
       0x7fffffffdbba:  push   rax
       0x7fffffffdbbb:  lea    rdi,[rsp]
       0x7fffffffdbbf:  xor    rax,rax
       0x7fffffffdbc2:  mov    BYTE PTR [rdi+0x7],al
       0x7fffffffdbc5:  mov    QWORD PTR [rdi+0x8],rdi
       0x7fffffffdbc9:  mov    BYTE PTR [rdi+0x10],al
       0x7fffffffdbcc:  mov    rsi,QWORD PTR [rdi+0x8]
       0x7fffffffdbd0:  push   rax
       0x7fffffffdbd1:  push   rdi
       0x7fffffffdbd2:  mov    rsi,rsp
       0x7fffffffdbd5:  add    rax,0x3b
       0x7fffffffdbd9:  syscall 
       0x7fffffffdbdb:  add    rax,0x1
       0x7fffffffdbdf:  xor    rdi,rdi
       0x7fffffffdbe2:  syscall 
       0x7fffffffdbe4:  and    DWORD PTR [rcx],esp
       0x7fffffffdbe6:  and    DWORD PTR [rcx],esp
       0x7fffffffdbe8:  mov    al,0xdb
       0x7fffffffdbea:  (bad)  
调用0x7fffffffdbb1指令后会出现意外行为,这是我无法理解的

(gdb) nexti
0x00007fffffffdbba in ?? ()
(gdb) nexti
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x2168732f6e69622f

0x00007fffffffdbbb in ?? ()
(gdb) i r rsp
rsp            0x7fffffffdbe8   0x7fffffffdbe8
(gdb) i r rip
rip            0x7fffffffdbbb   0x7fffffffdbbb
(gdb) nexti
0x00007fffffffdbbf in ?? ()
(gdb) nexti
0x00007fffffffdbc2 in ?? ()
(gdb) nexti
0x00007fffffffdbc5 in ?? ()
(gdb) nexti
0x00007fffffffdbc9 in ?? ()
(gdb) nexti
0x00007fffffffdbcc in ?? ()
(gdb) nexti
0x00007fffffffdbd0 in ?? ()
(gdb) nexti
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x0

0x00007fffffffdbd1 in ?? ()
(gdb) nexti

Program received signal SIGILL, Illegal instruction.
0x00007fffffffdbd9 in ?? ()
(gdb) 

我从0x7fffffffdbba开始发布输出,因为gdb似乎无法在地址(推入堆栈的值)设置断点,然后在地址0设置断点。

正如一些人提到的,您正在用堆栈和
mov将代码粉碎到
[rdi]
。但是,
mov
恰好发生在
rsp-8
上,因此对于地址0x7fffffffdbd0应该是可以的

我认为问题的出现就是因为这个。每次按下
mov[rdi+x],?
后,您应该查看程序(
x/20i$rip
),以查看它变成了什么。它可能是有效的代码。。。它可能不会因此而消失

=> 0x7fffffffdbb0:  movabs rax,0x2168732f6e69622f
   0x7fffffffdbba:  push   rax
   0x7fffffffdbbb:  lea    rdi,[rsp]
   0x7fffffffdbbf:  xor    rax,rax
   0x7fffffffdbc2:  mov    BYTE PTR [rdi+0x7],al
   0x7fffffffdbc5:  mov    QWORD PTR [rdi+0x8],rdi
   0x7fffffffdbc9:  mov    BYTE PTR [rdi+0x10],al
   0x7fffffffdbcc:  mov    rsi,QWORD PTR [rdi+0x8]
   0x7fffffffdbd0:  push   rax                    <-- after "push rdi" (0x7fffffffdbd0)
   0x7fffffffdbd1:  push   rdi
   0x7fffffffdbd2:  mov    rsi,rsp
   0x7fffffffdbd5:  add    rax,0x3b
   0x7fffffffdbd9:  syscall                       <-- after 2nd "push rax" (0x7fffffffdbd8)
   0x7fffffffdbdb:  add    rax,0x1
   0x7fffffffdbdf:  xor    rdi,rdi
   0x7fffffffdbe2:  syscall                       <-- after 1st "push rax" (0x7fffffffdbe0)
   0x7fffffffdbe4:  and    DWORD PTR [rcx],esp
   0x7fffffffdbe6:  and    DWORD PTR [rcx],esp    <-- mov [rdi+7] (0x7fffffffdbe7)
   0x7fffffffdbe8:  mov    al,0xdb                <-- stack starts here
   0x7fffffffdbea:  (bad)  
=>0x7FFFFFDBB0:movabs rax,0x2168732f6e69622f
0x7FFFFFDBBA:推送rax
0x7fffffdbbb:leardi[rsp]
0x7FFFFFDBBF:xor rax,rax
0x7FFFFFDBC2:mov字节PTR[rdi+0x7],al
0x7FFFFFDBC5:mov QWORD PTR[rdi+0x8],rdi
0x7FFFFFDBC9:mov字节PTR[rdi+0x10],al
0x7FFFFFDBCC:mov rsi,QWORD PTR[rdi+0x8]

0x7FFFFFDBD0:push rax SIGILL未始终映射到硬件的#UD(非法指令);当操作系统决定发出SIGILL信号时,可能还有其他情况。此外,下面列出了在64位模式下,
push rdi
可能产生的硬件异常#GP(0)-如果内存地址为非规范形式#SS(0)-如果堆栈地址为非规范形式#如果出现页面错误,则为PF(错误代码)#AC(0)-如果在当前权限级别为3时启用对齐检查并进行未对齐的内存引用#UD-如果使用了锁前缀#UD-如果推送为CS、SS、DS或ES。但是,在您的情况下,无法立即猜测哪一个是这种情况。请在rsp和rip上检查内存,一旦它到达dbd1。堆栈正在侵入代码,已经覆盖了一条syscall指令,即将覆盖另一条syscall指令,因此代码显然会失败,但我不太明白为什么它会在dbd1而不是在dbd9失败。啊,也许单步操作会把东西放到堆栈上,覆盖额外的16个字节的代码。
rsp
rip
距离太近。有趣……是的,编写有效的指令可以解释“延迟”故障。不,它不能使用过时的i-cache或已获取的指令,不能在任何现有x86硬件上使用。x86具有与d-cache一致的i-cache。自修改代码理论上(在x86手册的纸上)需要一个
jmp
来获取/预取指令以“注意”新编写的指令,但实际上()现代CPU总是在当前RIP附近窥探存储并刷新管道(
machine_nuke.smc
)因为这是给出至少所需语义的最快方法。@PeterCordes,啊。我不知道x86会像这样保持I-cache的一致性。我想是向后兼容吧。是的,向后兼容是x86存在的理由。有关供应商避免破坏Windows等广泛使用的软件中的现有代码的长度的更多讨论,请参见链接答案,尤其是@krazyglew的答案及其评论线程。(Andy Glew致力于英特尔的P6微体系结构。)真正的CPU通常比纸质体系结构有更强的保证。纸张规格是他们最终可能在某个时候放松下来的。