Hacking - The Art of Exploitation, 2nd Edition

(Romina) #1
Programming 49

// Example of printing with different format string
printf("[A] Dec: %d, Hex: %x, Unsigned: %u\n", A, A, A);
printf("[B] Dec: %d, Hex: %x, Unsigned: %u\n", B, B, B);
printf("[field width on B] 3: '%3u', 10: '%10u', '%08u'\n", B, B, B);
printf("[string] %s Address %08x\n", string, string);


// Example of unary address operator (dereferencing) and a %x format string
printf("variable A is at address: %08x\n", &A);
}


In the preceding code, additional variable arguments are passed to each


printf() call for every format parameter in the format string. The final printf()


call uses the argument &A, which will provide the address of the variable A.


The program’s compilation and execution are as follows.


reader@hacking:~/booksrc $ gcc -o fmt_strings fmt_strings.c
reader@hacking:~/booksrc $ ./fmt_strings
[A] Dec: -73, Hex: ffffffb7, Unsigned: 4294967223
[B] Dec: 31337, Hex: 7a69, Unsigned: 31337
[field width on B] 3: '31337', 10: ' 31337', '00031337'
[string] sample Address bffff870
variable A is at address: bffff86c
reader@hacking:~/booksrc $


The first two calls to printf() demonstrate the printing of variables A and B,


using different format parameters. Since there are three format parameters


in each line, the variables A and B need to be supplied three times each. The


%d format parameter allows for negative values, while %u does not, since it is


expecting unsigned values.


When the variable A is printed using the %u format parameter, it appears


as a very high value. This is because A is a negative number stored in two’s


complement, and the format parameter is trying to print it as if it were an


unsigned value. Since two’s complement flips all the bits and adds one, the


very high bits that used to be zero are now one.


The third line in the example, labeled [field width on B], shows the use


of the field-width option in a format parameter. This is just an integer that


designates the minimum field width for that format parameter. However,


this is not a maximum field width—if the value to be outputted is greater


than the field width, the field width will be exceeded. This happens when 3 is


used, since the output data needs 5 bytes. When 10 is used as the field width,


5 bytes of blank space are outputted before the output data. Additionally, if a


field width value begins with a 0, this means the field should be padded with


zeros. When 08 is used, for example, the output is 00031337.


The fourth line, labeled [string], simply shows the use of the %s format


parameter. Remember that the variable string is actually a pointer containing


the address of the string, which works out wonderfully, since the %s format


parameter expects its data to be passed by reference.

Free download pdf