Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.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
Linux 为什么我的程序可以执行不可执行的数据?_Linux_Security_Assembly_X86 64_Fasm - Fatal编程技术网

Linux 为什么我的程序可以执行不可执行的数据?

Linux 为什么我的程序可以执行不可执行的数据?,linux,security,assembly,x86-64,fasm,Linux,Security,Assembly,X86 64,Fasm,为什么这不会失败? 我的意思是,如果我编译并执行以下代码,我会 mmap 4KB as readable/writeable, but not executable. write some code there. and call there. this should fail! but does not? thats weird! 我原以为我必须使用syscall sys\u mprotect将一些内存标记为可执行的,但这是可行的,即使它不应该 format elf64 executable

为什么这不会失败? 我的意思是,如果我编译并执行以下代码,我会

mmap 4KB as readable/writeable, but not executable.
write some code there.
and call there. this should fail!
but does not?
thats weird!
我原以为我必须使用
syscall sys\u mprotect
将一些内存标记为可执行的,但这是可行的,即使它不应该

format elf64 executable
use64
entry start

macro echo message
{
  mov rdx, message#.size
  lea rsi, [ message ]
  mov rdi, 1
  mov rax, 1
  syscall
}
struc db [ data ]
{
  common
    . db data
    .size = $ - .
}

segment executable
  start:
    echo msg0
    mov r10, 0x22 ;MMAP_Private | MMAP_Anonymous
    mov rdx, 0x03 ;readable | writeable
    mov rsi, 4096
    xor rdi, rdi
    mov rax, 9
    syscall
    mov qword [ buffer ], rax
    echo msg1
    mov rcx, stub.size
    mov rdi, qword [ buffer ]
    lea rsi, [ stub ]
    rep movsb

    echo msg2
    mov rdx, msg3.size
    lea rsi, [ msg3 ]
    mov rdi, 1
    mov rax, 1
    call qword [ buffer ]
    echo msg4
  exit:
    xor rdi, rdi
    mov rax, 60
    syscall
segment readable  writeable
  stub:
    syscall
    ret
  stub.size = $ - stub

  msg0 db 'mmap 4KB as readable/writeable, but not executable.', 10, 0
  msg1 db 'write some code there.', 10, 0
  msg2 db 'and call there. this should fail!', 10, 0
  msg3 db 'but does not?', 10, 0
  msg4 db 'thats weird!', 10, 0
  buffer rq 1
所以实际的问题是:我如何才能让它失败?我预计Linux会使用NX位来存储这样的内存和我的PC,我用

grep ^flags /proc/cpuinfo | head -n1 | egrep --color=auto ' (pae|nx) '

并在BIOS中检查它,允许这种内存保护。

如何将fasm的调试符号输出与gdb一起使用?我尝试了
fasm-snx-test.debug nx test.fasm
,但当我在gdb中尝试
symbol file nx test.debug
时,它说“无法读取符号:无法识别文件格式”。(我一点也不知道FASM,只有NASM和GNU。(还有一些MASM语法))。必须使用
readelf-a
获取
\u start
的地址设置断点:/只需使用
FASM文件名编译它。FASM
,使用
chmod+x文件名
使其可执行,并使用
/file name
执行它。符号文件是特定于fasm的,在这个上下文中并不是很有用。不能做
break\u start
,真让人讨厌。当gdb没有与地址关联的“函数名”时,它还有其他一些不便之处。我发现了这个重复项:。显然这是标准行为。可能有太多的程序在未暗示
PROT_EXEC
的情况下JIT某些代码中断,因此这是默认设置。这可能是可配置的(在编译时,如果不是在运行时)。我现在要去看Ultimate(飞盘),但回来后我会再看一看。如何将fasm的调试符号输出与gdb一起使用?我尝试了
fasm-snx-test.debug nx test.fasm
,但当我在gdb中尝试
symbol file nx test.debug
时,它说“无法读取符号:无法识别文件格式”。(我一点也不知道FASM,只有NASM和GNU。(还有一些MASM语法))。必须使用
readelf-a
获取
\u start
的地址设置断点:/只需使用
FASM文件名编译它。FASM
,使用
chmod+x文件名
使其可执行,并使用
/file name
执行它。符号文件是特定于fasm的,在这个上下文中并不是很有用。不能做
break\u start
,真让人讨厌。当gdb没有与地址关联的“函数名”时,它还有其他一些不便之处。我发现了这个重复项:。显然这是标准行为。可能有太多的程序在未暗示
PROT_EXEC
的情况下JIT某些代码中断,因此这是默认设置。这可能是可配置的(在编译时,如果不是在运行时)。我现在必须出发去终极飞盘,但回来后我会再看一看。