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某些代码中断,因此这是默认设置。这可能是可配置的(在编译时,如果不是在运行时)。我现在必须出发去终极飞盘,但回来后我会再看一看。