Search code examples
memoryassemblyshellcode

Modifying a byte in memory using shellcode


I have been trying to create a simple chunk of shell code that allows me to modify a string by doing something simple like changing a letter, then print it out.

_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'

It's supposed to print out "hallo world". The problem occurs (segfault) when I try and modify a byte of memory with a mov command like so.

mov byte [esi+1], 41

I ran the program though GDB and the pop esi command works correctly, esi is loaded with the address of the string and everything is valid. I can't understand why I cant modify a byte value at the valid address though. I am testing this "shellcode" by just running the executable generated by NASM and ld, I am not putting it in a C program or anything yet so the bug exists in the assembly.

Extra information

I am using x64 Linux with the following build commands:

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

I have pasted the full code here.


Solution

  • If I had to guess, I'd say dbhello world` is being compiled in as code, rather than data, and as such has read and execute permissions, but not write ones. So you're actually falling foul of page protection.

    To change this, you need to place the string in a section .data section and use nasm's variable syntax to find it. In order to modify the data as is, you're going to need to make a mprotect call to modify the permissions on your pages, and write to them. Note: these won't persist back to the executable file - mmap()'s MAP_PRIVATE ensures that's the case.