Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This <strong>32-bit</strong> example illustrates how you can figure it out, see below for 64-bit:</p> <pre><code>#include &lt;stdio.h&gt; void function() { char buffer[64]; char *p; asm("lea 4(%%ebp),%0" : "=r" (p)); // loads address of return address printf("%d\n", p - buffer); // computes offset buffer[p - buffer] += 9; // 9 from disassembling main } int main() { volatile int x = 7; function(); x++; printf("x = %d\n", x); // prints 7, not 8 } </code></pre> <p>On my system the offset is 76. That's the 64 bytes of the buffer (remember, the stack grows down, so the start of the buffer is far from the return address) plus whatever other detritus is in between.</p> <p>Obviously if you are attacking an existing program you can't expect it to compute the answer for you, but I think this illustrates the principle.</p> <p>(Also, we are lucky that <code>+9</code> does not carry out into another byte. Otherwise the single byte increment would not set the return address how we expected. This example may break if you get unlucky with the return address within <code>main</code>)</p> <p><em>I overlooked the 64-bitness of the original question somehow.</em> The equivalent for x86-64 is <code>8(%rbp)</code> because pointers are 8 bytes long. In that case my test build happens to produce an offset of 104. In the code above substitute <code>8(%%rbp)</code> using the double <code>%%</code> to get a single <code>%</code> in the output assembly. This is described in <a href="http://www.x86-64.org/documentation/abi.pdf" rel="noreferrer">this ABI document</a>. Search for <code>8(%rbp)</code>.</p> <p>There is a complaint in the comments that <code>4(%ebp)</code> is just as magic as <code>76</code> or any other arbitrary number. In fact the meaning of the register <code>%ebp</code> (also called the "frame pointer") and its relationship to the location of the return address on the stack is standardized. One illustration I quickly Googled is <a href="http://www.unixwiz.net/techtips/win32-callconv-asm.html" rel="noreferrer">here</a>. That article uses the terminology "base pointer". If you wanted to exploit buffer overflows on other architectures it would require similarly detailed knowledge of the calling conventions of that CPU.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload