首先记录一下做这道题需要了解的知识点:
在fast_memecpy函数中有一个函数调用为:asm volatile
“asm” 表示后面的代码为内嵌汇编,“volatile” 表示编译器不要优化代码后面的指令, 保留原样。该函数有四个参数,中间用:隔开,函数格式为__asm__ volatile(汇编语句模板: 输出部分: 输入部分: 破坏描述部分),其中汇编语句模块是必须存在的一个参数,更多内容可以点击此链接查看
接下来是MOVDQA汇编指令,该指令在执行时必须对齐16字节边界,否则会生成一般保护性异常,而本题的解决方案也主要是针对这个指令。
在使用malloc函数进行堆分配时由于堆还需要包含一些头部信息和相关数据(保存在header中),因此molloc(size)分配的实际大小应该是大于size的,在32位系统中molloc的header长度通常为4字节,而64位系统中为8字节,同样,在molloc分配数据的字节对齐时32位系统是以8字节为单位而64位系统是以16字节为单位,这也是为什么当这个程序如果拉取到64位的本地系统时是能够正常运行的原因。
通读整个程序,发现程序如果能够正常执行10的话就能输出正确的代码,当在线运行时输入数据后可以发现当执行到第五次的时候程序就直接中断执行。
这是因为在执行前四次时由于size<64因此fast_memcpy直接调用slow_memcpy来执行,而第五次时由于数据大于64且不能达到16个字节对齐,因此会发生异常。
由于我安装的是64位系统,无法复现漏洞过程,因此在这也只能说一下原理:
由于MOVDQA汇编指令在执行过程中需要16字节对齐,由下面的代码可以看出用户需要先输入一个数据,然后使用malloc分配size长度的空间,而malloc在32位系统下进行字节分配的时候是以8个字节为单位进行空间分配的,如果长度不足8个字节依然会按照8个字节分配,同时还有一个长度为4字节的header。因此分配的实际值在满足16字节对齐满足一下两种情况的一种即可
a)(size+4)%16==0
b)(size+4)%16>8 (此时也会分配一个完整的16字节的长度)
编写代码如下:
for i in range(4,14):
low = pow(2,i-1)
high = pow(2,i)
#print low,high
for j in range(low+1,high):
if((j+4)%16==0 or (j+4)%16>=9):
print (j)
break
执行程序得到结果:
答案:1_w4nn4_br34K_th3_m3m0ry_4lignm3nt
这是因为gcc缺少一些库函数导致的,直接运行下面的代码进行下载对应的库函数即可
sudo apt install gcc-multilib