这算是最简单的入门教学题目了。看网上的博客和视频讲解的原理,感觉挺简单的,但是实际自己动手去做的时候还是有一些问题出现,在这里记录一下。
首先打开IDA,找到main函数,和存在漏洞的vulnerable函数。这里的注释意思是,用户数据在栈的ebp-0x10的位置开始存放。
然后我就用gdb动态调试一下,想看看具体发生了哪些事情。
一开始是不能打开的,提示没有权限,然后用chmod 777更改一下就可以了。
用gdb打开之后,b main在main函数处下断点,然后run。
我在用si ni想逐句读一下是怎么工作的,然后就被栈里的esp和ebp给绕晕了。
我的问题是发生在valnerable函数中的gets,当我ni之后,观察栈发现,esp和ebp相差很多,而且也并不是IDA中显示的距离esp+8的位置来存放输入数据的。
后来又想了想,如果再执行完后面两条语句就符合了。究其原因就是这里gets函数是cdcall约定(清理栈的工作交给调用函数来处理),所以当gets返回后需要清理栈,这才是一个完整的过程。
再一个不明白的就是这个get_pc_thunk_ax函数,查询得到,调用这个函数后,将会得到下一行的指令地址并放到EAX中。
ni后,确实如此。但是对这个函数到底有什么用,还是不明白。
然后我想到,gdb中有n和s(区别于ni和si),它是按照源代码执行一条语句来调试的。
当我用n和s调试时,发现,会直接跳过0x80484f6--0x8048502的这些语句,也就是说明这6行汇编指令对应的是源代码中的一行代码。
接着看IDA可知,也许跳过的这些汇编,就是char buffer[8]这行语句。