一、程序代码
使用ollydbg调试进行调试的程序代码为
#include <stdio.h>
#include <string.h>
void cpyFrom(char*);
int main(){
char* srcStr="12345678aaaabbbbccccddd";
cpyFrom(srcStr);
printf("welcome back!\n");
return 0;
}
void cpyFrom(char* src){
char dstStr[8];
strcpy(dstStr,src);
printf("%s\n",dstStr);
}
在Dev-C++中的编译选项选择32-bit Debug
二、寻找main函数入口
1、区域分布
打开产生的Demo.exe可执行文件后,ollydbg的界面显示如下,其功能分布如图所示。
2、寻找入口
点击菜单栏中的查看(view)→可执行模块(Executable module),显示如下:
其中Demo对应的入口即为可执行文件的main函数入口(004014E0),右击该行,选择在CPU中查看代码(view code in CPU),找到该入口,在该入口下面(可能需要下拉较多的行数),可以看到我们在main函数中赋值的“123”以及要打印的“welcome back!”,可以确认该部分就是main函数,分析代码也可以看到
call Demo.00401535
为调用void cpyFrom(char* src)
函数,所以我们可以考虑在00401535处设置断点。
3、设置断点
函数void cpyFrom(char* src)
的汇编指令如下,在入口处设置断点,打开程序后点击运行程序(F9)则直接在该点处暂停,分析过程省略。
4、进行单步调试
有意思的是,在单步调试该函数时,可以通过堆栈观察到,虽然我们定义了char dstStr[8];
,但是实际上在堆栈中分配了16byte的空间,所以如果要让程序不正常运行,则输入字符串长度要>=16字符(不要忘记每个字符串后面还有一个‘\0’)。
三、实验总结
破坏Ebp和返回地址后可能产生不同的结果,我们都可以通过单步调试分析出这其中的原因,比如为什么会重复打印字符串、为什么会卡住等,对于理解缓冲区溢出的原理很有帮助。在此仅对一些准备过程中的问题给出自己的愚见,不再对具体的过程进行详细分析,不当之处还请谅解并给予反馈。