0

我一直在尝试创建一个简单的 shell 代码块,它允许我通过做一些简单的事情来修改一个字符串,比如改变一个字母,然后打印出来。

_start:
        jmp short ender
starter:
        xor ecx, ecx            ;clear out registers
        xor eax, eax
        xor ebx, ebx
        xor edx, edx
        pop esi                 ;pop address of string into esi register

        mov byte [esi+1], 41    ;try and put an ASCII 'A' into the second letter of the string
                                ;at the address ESI+1

        mov ecx, esi            ;move our string into the ecx register for the write syscall
        mov al, 4               ;write syscall number
        mov bl, 1               ;write to STDOUT
        mov dl, 11              ;string length
        int 0x80                ;interrupt call
ender:
        call starter
        db 'hello world'

它应该打印出“你好世界”。当我尝试使用mov这样的命令修改一个字节的内存时,就会出现问题(段错误)。

mov byte [esi+1], 41

我通过 GDB 运行了该程序,并且该pop esi命令正常工作,esi加载了字符串的地址,并且一切都有效。我不明白为什么我不能修改有效地址的字节值。我只是通过运行由 NASM 和 ld 生成的可执行文件来测试这个“shellcode”,我还没有把它放在 C 程序或任何东西中,所以程序集中存在错误。

额外的信息

我正在使用带有以下构建命令的 x64 Linux:

nasm -f elf64 shellcode.asm -o shellcode.o
ld -o shellcode shellcode.o
./shellcode

我在这里粘贴了完整的代码。

4

1 回答 1

2

如果我不得不猜测,我会说dbhello world` 被编译为代码,而不是数据,因此具有读取和执行权限,但没有写入权限。因此,您实际上违反了页面保护。

要更改这一点,您需要将字符串放在一个section .data部分中并使用 nasm 的变量语法来查找它。为了按原样修改数据,您将需要调用mprotect来修改页面上的权限,并写入它们。注意:这些不会保留回可执行文件 -确保是这种情况mmap()MAP_PRIVATE

于 2012-11-04T20:34:01.200 回答