I found a simple shellcode on the internet. Then, to test this shellcode, I make the simple ret overwrite code.


#include <stdio.h>
#include <string.h>

char buf[100];

int main(void)
        char x=0;
        strcpy(buf, "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05");


        puts("end of program");

I compiled this using gcc like this.

gcc -o test test.c -fno-stack-protector -mpreferred-stack-boundary=2 -no-pie -fno-pie -z execstack

and the following is the result of what I debugged with gdb.

└─$ gdb -q test                                                                                
Reading symbols from test...
(No debugging symbols found in test)
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
   0x0000000000401126 <+0>:     push   rbp
   0x0000000000401127 <+1>:     mov    rbp,rsp
   0x000000000040112a <+4>:     sub    rsp,0x10
   0x000000000040112e <+8>:     mov    BYTE PTR [rbp-0x1],0x0
   0x0000000000401132 <+12>:    movabs rax,0x6e69622fbb48f631
   0x000000000040113c <+22>:    movabs rdx,0x5f54535668732f2f
   0x0000000000401146 <+32>:    mov    QWORD PTR [rip+0x2ef3],rax        # 0x404040 <buf>
   0x000000000040114d <+39>:    mov    QWORD PTR [rip+0x2ef4],rdx        # 0x404048 <buf+8>
   0x0000000000401154 <+46>:    movabs rax,0x50fd231583b6a
   0x000000000040115e <+56>:    mov    QWORD PTR [rip+0x2eeb],rax        # 0x404050 <buf+16>
   0x0000000000401165 <+63>:    lea    rax,[rbp-0x1]
   0x0000000000401169 <+67>:    add    rax,0x9
   0x000000000040116d <+71>:    mov    BYTE PTR [rax],0x40
   0x0000000000401170 <+74>:    lea    rax,[rbp-0x1]
   0x0000000000401174 <+78>:    add    rax,0xa
   0x0000000000401178 <+82>:    mov    BYTE PTR [rax],0x40
   0x000000000040117b <+85>:    lea    rax,[rbp-0x1]
   0x000000000040117f <+89>:    add    rax,0xb
   0x0000000000401183 <+93>:    mov    BYTE PTR [rax],0x40
   0x0000000000401186 <+96>:    lea    rax,[rbp-0x1]
   0x000000000040118a <+100>:   add    rax,0xc
   0x000000000040118e <+104>:   mov    BYTE PTR [rax],0x0
   0x0000000000401191 <+107>:   lea    rax,[rbp-0x1]
   0x0000000000401195 <+111>:   add    rax,0xd
   0x0000000000401199 <+115>:   mov    BYTE PTR [rax],0x0
   0x000000000040119c <+118>:   lea    rax,[rbp-0x1]
   0x00000000004011a0 <+122>:   add    rax,0xe
   0x00000000004011a4 <+126>:   mov    BYTE PTR [rax],0x0
   0x00000000004011a7 <+129>:   lea    rax,[rbp-0x1]
   0x00000000004011ab <+133>:   add    rax,0xf
   0x00000000004011af <+137>:   mov    BYTE PTR [rax],0x0
   0x00000000004011b2 <+140>:   lea    rax,[rbp-0x1]
   0x00000000004011b6 <+144>:   add    rax,0x10
   0x00000000004011ba <+148>:   mov    BYTE PTR [rax],0x0
   0x00000000004011bd <+151>:   lea    rax,[rip+0xe40]        # 0x402004
   0x00000000004011c4 <+158>:   mov    rdi,rax
   0x00000000004011c7 <+161>:   call   0x401030 <puts@plt>
   0x00000000004011cc <+166>:   mov    eax,0x0
   0x00000000004011d1 <+171>:   leave
   0x00000000004011d2 <+172>:   ret
End of assembler dump.
(gdb) b *main+172
Breakpoint 1 at 0x4011d2
(gdb) r
Starting program: /home/kali/test 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
end of program

Breakpoint 1, 0x00000000004011d2 in main ()
(gdb) si
0x0000000000404040 in buf ()
(gdb) x/30i $rip
=> 0x404040 <buf>:      xor    esi,esi
   0x404042 <buf+2>:    movabs rbx,0x68732f2f6e69622f
   0x40404c <buf+12>:   push   rsi
   0x40404d <buf+13>:   push   rbx
   0x40404e <buf+14>:   push   rsp
   0x40404f <buf+15>:   pop    rdi
   0x404050 <buf+16>:   push   0x3b
   0x404052 <buf+18>:   pop    rax
   0x404053 <buf+19>:   xor    edx,edx
   0x404055 <buf+21>:   syscall
   0x404057 <buf+23>:   add    BYTE PTR [rax],al
   0x404059 <buf+25>:   add    BYTE PTR [rax],al
   0x40405b <buf+27>:   add    BYTE PTR [rax],al
   0x40405d <buf+29>:   add    BYTE PTR [rax],al
   0x40405f <buf+31>:   add    BYTE PTR [rax],al
   0x404061 <buf+33>:   add    BYTE PTR [rax],al
   0x404063 <buf+35>:   add    BYTE PTR [rax],al
   0x404065 <buf+37>:   add    BYTE PTR [rax],al
   0x404067 <buf+39>:   add    BYTE PTR [rax],al
   0x404069 <buf+41>:   add    BYTE PTR [rax],al
   0x40406b <buf+43>:   add    BYTE PTR [rax],al
   0x40406d <buf+45>:   add    BYTE PTR [rax],al
   0x40406f <buf+47>:   add    BYTE PTR [rax],al
   0x404071 <buf+49>:   add    BYTE PTR [rax],al
   0x404073 <buf+51>:   add    BYTE PTR [rax],al
   0x404075 <buf+53>:   add    BYTE PTR [rax],al
   0x404077 <buf+55>:   add    BYTE PTR [rax],al
   0x404079 <buf+57>:   add    BYTE PTR [rax],al
   0x40407b <buf+59>:   add    BYTE PTR [rax],al
   0x40407d <buf+61>:   add    BYTE PTR [rax],al
(gdb) si

Program received signal SIGSEGV, Segmentation fault.
0x0000000000404040 in buf ()

I think that 'xor esi,esi' don't generate segmentation fault, but It generated. Why the segmentation fault occured?

1 Answer 1


Your buf variable is a global variable, which most likely is located inside .data section.

This section is not executable by default (it probably has RW permissions). You can check its permissions with readelf utility.

Since you are putting your shell code inside a buffer located in a non executable section of memory, upon executing first instructions, program segfaults.

Considering arguments you are passing to compile your code, I assume that you wanted your shell code to be located in the stack. Thus, to avoid segfault, your buf array should be a local variable (place your array inside main function).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.