C 在x86_64和i686上编译时,NOP字符0x90的printf不同
我有两个系统:C 在x86_64和i686上编译时,NOP字符0x90的printf不同,c,linux,gcc,buffer-overflow,nop,C,Linux,Gcc,Buffer Overflow,Nop,我有两个系统: 3.13.0-35-通用。。。x86_64 x86_64 x86_64 GNU/Linux,带gcc:4.8.2 2.6.32-21-generic#32 Ubuntu。。。i686 GNU/Linux与gcc:4.4.3 我在两个系统上编译了以下代码: int numOfNops = 600; unsigned char nops[numOfNops]; int i; for (i=0; i < numOfNops; i++) { nops[i] = '\x90'
int numOfNops = 600;
unsigned char nops[numOfNops];
int i;
for (i=0; i < numOfNops; i++) {
nops[i] = '\x90';
}
...
printf("GET /%s%s\x90\x90%s HTTP/1.0 \n", nops, buf, ESPs);
Hexdump系统#2:
因此,附加字符是:0x24 0xc5 0x12
[Q] 为什么呢
谢谢。您的缓冲区没有NUL'\0'终止,因此您正在打印超出缓冲区本身的字符 我建议尝试添加nops[numOfNops-1]='\0';在调用printf之前。请考虑告诉 要打印的NOP的确切数量:
printf("GET /%.*s%s\x90\x90%s HTTP/1.0 \n", numOfNops, nops, buf, ESPs);
这避免了您没有空终止字符串的问题
(请注意,严格来说,
%.*s
表示法告诉printf()
最多格式化numOfNops
字符,或者直到第一个空字节,作为转换规范的输出。如果您有问题中的NOP值的固定数组,这与告诉printf()相同)
精确打印给定数量的NOP值。)为什么。。。你会那样做吗?只是一项作业。:)什么是“NOP字符”?HTTP 1.0中的URI必须是ASCII,而0x90不是有效的ASCII字符。@Wyzard他正在那里编写x86机器代码。(可能是利用服务器缓冲区溢出。)0x90是nop指令。奇数字符的原因是在64位机器上,内容以8的倍数格式化,而在32位机器上,内容以4的倍数格式化。奇数字符是生成8倍大小的结果间距。在第一个答案中使用对printf()的建议修改将更正显示的输出。nops[numOfNops]=0更类似。此外,超过缓冲区,未通过。a哦,缓冲区需要大一点。这会导致一个一个缓冲区溢出。谢谢你更正了拼写。逻辑错误是首选吗?(缓冲区溢出可能是由于不正确地修复了逻辑错误,这也是一个错误)谢谢,现在剩下的问题是:为什么我在64位系统上编译它时没有问题?主要是运气,它没有必要链接到64/32位(我懒得检查对齐)-您在32位环境中的最后一个0x90之后,堆栈中有0,这就是您的运气。对这个非常严格-乔纳森的解决方案有助于PrtfF——但是如果你没有明确地用一个NUL字节终止你的0x90,甚至不要考虑在这个缓冲区上使用任何STR*函数-你的漏洞可能会崩溃或者经历意外的行为,并且在某些情况下会产生一个可利用的bug。我建议使用valgrind来调试此类问题。
00000250 90 90 90 90 90 90 90 90 90 90 90 90 90 24 c5 12 |.............$..|
00000260 89 e3 da c4 d9 73 f4 5f 57 59 49 49 49 49 49 49 |.....s._WYIIIIII|
printf("GET /%.*s%s\x90\x90%s HTTP/1.0 \n", numOfNops, nops, buf, ESPs);