我有一个小问题。我知道 %x 格式说明符可用于在格式字符串攻击中从堆栈中读取值。
我找到了以下代码:
%08x%08x%08x%08x
08是什么意思?它到底在做什么?谢谢 :)
分解:
8
表示要显示 8 位数字0
你想用0
's而不是空格作为前缀x
您想以小写十六进制打印。快速示例(感谢 Grijesh Chauhan):
#include <stdio.h>
int main() {
int data = 29;
printf("%x\n", data); // just print data
printf("%0x\n", data); // just print data ('0' on its own has no effect)
printf("%8x\n", data); // print in 8 width and pad with blank spaces
printf("%08x\n", data); // print in 8 width and pad with 0's
return 0;
}
输出:
1d
1d
1d
0000001d
%08x
意味着每个数字都应打印至少 8 个字符宽,并用零填充所有缺失的数字,例如对于 '1' 输出将是00000001
您提到的对 printf 的格式字符串攻击并非特定于“%x”格式 - 在任何情况下 printf 的格式参数多于传递的变量,它都会从堆栈中读取不属于它的值。例如,您将遇到与 %d 相同的问题。当您想将这些值视为十六进制时,%x 很有用。
如先前答案中所述, %08x 将生成一个 8 位十六进制数,并用前面的零填充。
在 printf 中使用代码示例中的格式,不带其他参数:
printf ("%08x %08x %08x %08x");
将从堆栈中获取 4 个参数并将它们显示为 8 位填充的十六进制数字。
这指定了您希望它显示多少位数。
指定最小字段宽度的整数值或 *。如果需要,结果会用空格字符(默认情况下)填充,右对齐时在左侧,如果左对齐,则在右侧。在使用 * 的情况下,宽度由 int 类型的附加参数指定。如果参数的值为负,则结果是指定的 - 标志和正的字段宽度。
来自http://en.wikipedia.org/wiki/Printf_format_string
指定宽度选项时,使用 0 而不是空格来填充字段。例如,printf("%2d", 3)
结果为“3”,而printf("%02d", 3)
结果为“03”。