如果您正在使用本书(如下)中的示例代码,在某些时候您应该会达到“AAAAAAAA”模式(0x41)。请注意,由于您在 64 位机器上运行它,每个元素在堆栈中存储 8 个字节,因此您应该$ ./fmtstr "AAAAAAAA %016x %016x %016x %016x %016x %016x %016x %016x %016x %016x %016x %016x %016x"
改为运行它,否则您将丢失堆栈中每个元素的一部分。
#include <stdlib.h>
int main(int argc, char *argv[]){
static int canary=0; // stores the canary value in .data section
char temp[2048]; // string to hold large temp string
strcpy(temp, argv[1]); // take argv1 input and jam into temp
printf(temp); // print value of temp
printf("\n"); // print carriage return
printf("Canary at 0x%08x = 0x%08x\n", &canary, canary); //print canary
}
您应该注意书中的引述:
显示的第四项(来自堆栈)是我们的格式字符串这一事实取决于所使用的格式函数的性质以及易受攻击的调用在易受攻击的程序中的位置。要找到这个值,只需使用蛮力并不断增加 %08x 标记的数量,直到找到格式字符串的开头。对于我们的简单示例 (fmtstr),称为偏移量的距离定义为 4。
请记住,被解析的参数printf
不是字符串本身,而是字符串的地址。因此,它在程序的内存布局上相对于printf
堆栈的位置将定义您必须搜索多远才能找到它。