使用shellcode修改内存中的字节

时间:2012-11-04 20:26:47

标签: memory assembly shellcode

我一直在尝试创建一个简单的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程序或其他任何东西中,所以程序集中存在bug。

额外信息

我正在使用x64 Linux以及以下构建命令:

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

我已粘贴完整代码here.

1 个答案:

答案 0 :(得分:2)

如果我不得不猜测,我说db hello world`是作为代码而不是数据编译的,因此具有读取和执行权限,但不是写入权限。所以你实际上是在防止页面保护。

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