title: Modify the return address of a C function with buffer overflow vulnerability
body: <p>I am trying to modify the following C program so that the main function will skip the printf("x is 1") line and only print "x is 0".</p>
  
  <pre><code> void func(char *str) {
           char buffer[24];
           int *ret;
  
           ret = buffer + 28; // Supposed to set ret to the return address of func
           (*ret) += 32; // Add the offset needed so that func will skip over printf("x is 1")
           strcpy(buffer, str);
   }
  
   int main(int argc, char **argv) {
           int x;
           x = 0;
           func(argv[1]);
           x = 1;
           printf("x is 1");
           printf("x is 0");
           getchar();
   }
  </code></pre>
  
  <p>As the comments imply, the ret pointer needs to first be set to the return address of the function. I then need to add on an offset that will push it over the line I want to skip. I am running this code on a Linux system with 2 x Intel(R) Xeon(TM) CPU 3.20GHz. I am using gcc version 4.7.2 (Debian 4.7.2-5) to compile. I'm also trying to use example3.c from this (<a href="http://insecure.org/stf/smashstack.html" rel="nofollow">http://insecure.org/stf/smashstack.html</a>) link for reference. Here is a disassembly of the main function using gdb:</p>
  
  <pre><code>Dump of assembler code for function main:
      0x0000000000400641 &lt;+0&gt;:     push   %rbp
      0x0000000000400642 &lt;+1&gt;:     mov    %rsp,%rbp
      0x0000000000400645 &lt;+4&gt;:     sub    $0x20,%rsp
      0x0000000000400649 &lt;+8&gt;:     mov    %edi,-0x14(%rbp)
      0x000000000040064c &lt;+11&gt;:    mov    %rsi,-0x20(%rbp)
      0x0000000000400650 &lt;+15&gt;:    movl   $0x0,-0x4(%rbp)
      0x0000000000400657 &lt;+22&gt;:    mov    -0x20(%rbp),%rax
      0x000000000040065b &lt;+26&gt;:    add    $0x8,%rax
      0x000000000040065f &lt;+30&gt;:    mov    (%rax),%rax
      0x0000000000400662 &lt;+33&gt;:    mov    %rax,%rdi
      0x0000000000400665 &lt;+36&gt;:    callq  0x4005ac &lt;func&gt;
      0x000000000040066a &lt;+41&gt;:    movl   $0x1,-0x4(%rbp)
      0x0000000000400671 &lt;+48&gt;:    mov    $0x40075b,%edi
      0x0000000000400676 &lt;+53&gt;:    mov    $0x0,%eax
      0x000000000040067b &lt;+58&gt;:    callq  0x400470 &lt;printf@plt&gt;
      0x0000000000400680 &lt;+63&gt;:    mov    $0x400762,%edi
      0x0000000000400685 &lt;+68&gt;:    mov    $0x0,%eax
      0x000000000040068a &lt;+73&gt;:    callq  0x400470 &lt;printf@plt&gt;
      0x000000000040068f &lt;+78&gt;:    callq  0x400490 &lt;getchar@plt&gt;
      0x0000000000400694 &lt;+83&gt;:    leaveq
      0x0000000000400695 &lt;+84&gt;:    retq
   End of assembler dump.
  </code></pre>
  
  <p>Using what I've read from the example, my buffer is 24 bytes long and I should add an extra 4 bytes for the SFP size. This would mean I add 28 bytes to get to the return address of &lt;+41>. It then looks like I want to jump to the last printf call at &lt;+73>. This should be an offset of 32. However, when I execute the code, "x is 1" is still printed. I can't seem to find out why. Is there something wrong with my math or assumptions?</p>