Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You have 6 format specifiers (5 lots of <code>%08x</code> and one of <code>%s</code>), but you do not provide values for those format specifiers. You immediately fall into the realm of undefined behaviour - anything could happen and there is no wrong answer.</p> <p>However, in the normal course of events, the values passed to <code>printf()</code> would have been stored on the stack, so the code in <code>printf()</code> reads values off the stack as if the extra values had been passed. The function return address is on the stack, too. There is no guarantee that I can see that the value 0x08480110 will actually be produced. This sort of attack very much depends on the the specific program and faulty function call, and you might well get a very different value. The example code is most likely written assuming a 32-bit Intel (little-endian) CPU - rather than a 64-bit or big-endian CPU.</p> <hr> <p>Adapting the code fragment, compiling it into a complete program, ignoring the compilation warnings, using a 32-bit compilation on MacOS X 10.6.7 with GCC 4.2.1 (XCode 3), the following code:</p> <pre><code>#include &lt;stdio.h&gt; static void somefunc(void) { printf("AAAAAAAAAAAAAAAA.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.|%s|\n"); } int main(void) { char buffer[160] = "abcdefghijklmnopqrstuvwxyz012345" "abcdefghijklmnopqrstuvwxyz012345" "abcdefghijklmnopqrstuvwxyz012345" "abcdefghijklmnopqrstuvwxyz012345" "abcdefghijklmnopqrstuvwxyz01234"; somefunc(); return 0; } </code></pre> <p>produces the following result:</p> <pre><code> AAAAAAAAAAAAAAAA.0x000000A0.0xBFFFF11C.0x00001EC4.0x00000000.0x00001E22.0xBFFFF1C8.0x00001E5A.|abcdefghijklmnopqrstuvwxyz012345abcdefghijklmnopqrstuvwxyz012345abcdefghijklmnopqrstuvwxyz012345abcdefghijklmnopqrstuvwxyz012345abcdefghijklmnopqrstuvwxyz01234| </code></pre> <p>As you can see, I eventually 'found' the string in the main program from the <code>printf()</code> statement. When I compiled it in 64-bit mode, I got a core dump instead. Both results are perfectly correct; the program invokes undefined behaviour, so anything the program does is valid. If you're curious, search for 'nasal demons' for more information on undefined behaviour.</p> <p>And get used to experimenting with these sorts of issues.</p> <hr> <p>Another variation</p> <pre><code>#include &lt;stdio.h&gt; static void somefunc(void) { char format[] = "AAAAAAAAAAAAAAAA.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X\n" ".0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X\n" ".0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X.0x%08X\n"; printf(format, 1); } int main(void) { char buffer[160] = "abcdefghijklmnopqrstuvwxyz012345" "abcdefghijklmnopqrstuvwxyz012345" "abcdefghijklmnopqrstuvwxyz012345" "abcdefghijklmnopqrstuvwxyz012345" "abcdefghijklmnopqrstuvwxyz01234"; somefunc(); return 0; } </code></pre> <p>This produces:</p> <pre><code>AAAAAAAAAAAAAAAA.0x00000001.0x00000099.0x8FE467B4.0x41000024.0x41414141 .0x41414141.0x41414141.0x2E414141.0x30257830.0x302E5838.0x38302578.0x78302E58 .0x58383025.0x2578302E.0x2E583830.0x30257830.0x2E0A5838.0x30257830.0x302E5838 </code></pre> <p>You might recognize the format string in the hex output - 0x41 is capital A, for example.</p> <p>The 64-bit output from that code is both similar and different:</p> <pre><code>AAAAAAAAAAAAAAAA.0x00000001.0x00000000.0x00000000.0xFFE0082C.0x00000000 .0x41414141.0x41414141.0x2578302E.0x30257830.0x38302578.0x58383025.0x0A583830 .0x2E583830.0x302E5838.0x78302E58.0x2578302E.0x30257830.0x38302578.0x38302578 </code></pre>
 

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