overwrite

overwrite 编写overwrite.c程序#inlcudestdio.h int main() { int b 123; int c 789; int a 456; char s[100]; printf(%p\n, a); scanf(%s, s); printf(s); if (a 16) { puts(my name is c); } else if (a 2) { puts(my name is small); } else if (b 0x12345678) { puts(my name is big); } return 0; }gcc -m32 overwrite.c -o overwrite 生成程序使用gdb调试输入s查看栈帧和运行结果可以看到aaaa是在printf第四个参数位置即%4$p即局部变量s的位置在printf的第4个参数位置小知识printf(hello %d hello,a);hello %d hello的字符串是printf的第一个参数a是第二个参数当printf前面的占位符和后面的参数个数不匹配多余的占位符会将栈上接下来的位置继续当作参数操作%p占位符:打印参数的地址图中printf当我输入%p当作占位符时后面并没有参数与占位符匹配所以第一个%p会将printf的esp4当作参数进行泄露第二个%p是esp8...图中第四个打印0x6161%n:将打印字符的个数重写入参数中比如printf(aaaa%n);就是将4写入第一个参数中因为打印在控制台上的是aaaa所以写入4写入第一个参数就是写入0xffffcec0地址中%4$p其中的4$就是第几个参数第一题将a的值改为16根据gdb调试可知:局部变量位于%4$p将a的值改为16则输出16个字符a_addr占4个差12个补上编写exp:第二题将a的值改成2%n输入的值是在该占位符之前的输出的个数只需aa%?$n即可考虑栈对齐再加上aa并计算参数现在的位置即可编写exp:第三题:将a的值改成0x12345678小知识:32位程序:一个地址占四个字节即32位%hhn输入的内容只能占1个字节即8位%hn:输入的内容只能占2个字节问题1怎么将这么大的数据存进去0x12345678是32位所以可以每8位为一组分成四组写入a_addr中比如0x78存入a_addr中0x56存入a_addr1中因为地址占四个字节最后a的结果就是将四个字节一起读取%100c输出100个字符(空格)问题2前面输入的大小大于后面的怎么办%hhn只占一个字节即8位所以范围为0-255所以当数值大于255后就会从0重置(进位但%hhn不管)先输入a_addr所占的地址p32(a_addr0),p32(a_addr1),p32(a_addr2),p32(a_addr3),四个字节因为程序是小端存储所以要先将0x78存入a_addr中之前已经输出4*4个字节所以只需要0x78-16104个字节将0x56存入a_addr1中前面已经有0x78(120)个字节(%?$n因为不打印所以并不会计算在内)现在只需要2560x56-0x78222个字节将0x34存入a_addr2中2562560x34-256-0x56222将0x12存入a_addr3中2562562560x12-256-256-0x34222小端存储当只有一个字节的数据类型存储数据时正常存储当该数据类型大于一个字节时会以一个字节为单位反过来存储(一个字节里面还是正常存储)编写exp: