I type this code in c: __asm__("mov $10, %rsi"); printf("%x")
, It print a
.
I debug it in gdb
, found that the result store int register esi
.
QUESTION: why the result is esi
?
Description. The printf() function formats and prints a series of characters and values to the standard output stream stdout .
In C we have seen different format specifiers. Here we will see another format specifier called %p. This is used to print the pointer type data.
The %u format specifier is implemented for fetching values from the address of a variable having an unsigned decimal integer stored in the memory. It is used within the printf() function for printing the unsigned integer variable.
%s is for string %d is for decimal (or int) %c is for character.
printf("%x")
tries to get a second argument, but it isn't there, so it just reads the memory where it should have been, finds whatever garbage is there, and prints it.
In short: it is undefined-behavior.
EDIT: the reason you see the same value as in the esi
register, is because the System V AMD64 ABI (which is the spec most Unixes follow) passes the first few arguments through registers when possible. The second argument is passed through rsi
, therefore that's where printf
is reading from.
When calling printf("%x")
, it happens, that the arguments which it needs are pushed to the stack (in reverse order) and eventually, the function is called using assembly command call
. When providing your format string "%x"
, printf()
expects at least ONE argument following, so it will read the value next on the stack, which could be anything...
So this behavior is actually undefined and often the cause for exploits, because you can corrupt the stack.
Maybe a little excourse on this topic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With