Simple NASM assembler code leaves me baffled

Ok, so you all know I’m new to assembler. I have started using NASM so that it is easier to look at the shell code. I’m trying my best to get this tiny piece of code to run. However it keeps segfaulting. Can anyone explain. It is the mov to [esi + 2] that causes it.

jmp short	stuff
code:

pop		esi
xor		eax, eax
mov byte	[esi + 2], al

mov		al, 0x01
xor		ebx, ebx
int		0x80

stuff:
call		code
db		'help###'

This is what the registers look like at the crash point

pete@satsuki:~/hck$ nasm nasm.S -o nasm.o -f elf
pete@satsuki:~/hck$ ld nasm.o -o nasm-bin
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048060
pete@satsuki:~/hck$ gdb ./nasm-bin 
GNU gdb (GDB) 7.0-ubuntu
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /home/pete/hck/nasm-bin...(no debugging symbols found)...done.
(gdb) run
Starting program: /home/pete/hck/nasm-bin 

Program received signal SIGSEGV, Segmentation fault.
0x08048065 in code ()
(gdb) info registers
eax            0x0	0
ecx            0x0	0
edx            0x0	0
ebx            0x0	0
esp            0xbffff4f0	0xbffff4f0
ebp            0x0	0x0
esi            0x8048073	134512755
edi            0x0	0
eip            0x8048065	0x8048065 
eflags         0x10246	[ PF ZF IF RF ]
cs             0x73	115
ss             0x7b	123
ds             0x7b	123
es             0x7b	123
fs             0x0	0
gs             0x0	0
(gdb) 

The outcome should have been that the "l" from "help" should have become a 0x00 byte. Any takers?

    • Damien
    • January 29th, 2010

    I’m not an expert on nasm but I seem to remember that when you want to declare a data section (for memory that is writeable you use) section .data and then you use section.text for code. Is if possible that the kernel knows you’re trying to write into a code block and that this triggers a segfault for security reasons (really just guessing) ? The code, registers and addresses look right (in terms of what you are trying to do).

  1. Yes, in fact you are correct. The data is being stored in the .text segment, which is leading to a segfault. I figured this out this morning with the help from some friends. The annoying part is that the tutorial I was looking at and following was written in 2002. I’m guessing memory protection wasn’t the same back then.

    A friend was telling me about something to do with pre-NX chips, x86 only, where segments that were readable were also executable, so a segment that was readable and writable was also executable by design. I guess I need to go back and learn some more. The question is, would the code work if it were used inside an exploit. I think the answer is quite probably as it would end up in a writable stack. However, there are also stack execution prevention routines in place now.

    It would be nice to find a way to test it before I try to exploit something with it. Not that I’m going to do anything malicious with it anyway.

  1. No trackbacks yet.

Leave a reply to Damien Cancel reply