汇编语言学习(调试一个缓存溢出的程序)
最近在学习调试,download了winbg使用起来一头雾水,不得不开始学习汇编。下面是我的学习过程。
从微软那里download了windbg,好像是一个不错的工具(我还没深入,掌握了几个命令),有download了Symbol。
先花了一上午,把汇编出略看了一下,知道了什么是通用寄存器,什么时段寄存器,什么是lea,什么是stos等等。
接下来,从开始菜单,运行windbg,选择Open Executable…打开你要调试的程序。下图红圈表示汇编模式,不然的话源码文件也会被打开,这样的话函数调用的细节也可以看得很清楚。
中间是命令窗口,右上是调用栈,右下局部变量。
用windbg调试,第一步当然要设置端点,需要使用bp命令。在命令窗口下面输入bp WinMain回车,bp foo回车。
可以用bl命令列一下,看看有没有设置好。设置完成后输入g回车,程序开始运行直到断点。
程序在WinMain的入口中断了。使用f10单步调试,
在调用foo之前有一个push eax,这是参数入栈,我向foo传递了一个字符串。
接着按f11跟踪进入函数。
push ebp 函数的返回地址入栈(我理解的是否正确)?
sub esp,0x4c 给当前函数分配空间(为什么分配0x4c)?
mov ecx,0x13 为什么只初始化0x13字节的空间?
mov eax,[ebp+0x8] ebp+0x8是传给foo的字符串地址。
Lea ecx,[ebp-0xc] [ebp-0xc]就是buf的首地址。
接下来,我们使用dd /c 1 esp看一下对栈内容
0012fedc存放的函数返回后的地址。(为什么比call stacks窗口中的值大四字节)
使用d ebp-0xc,保存的地址是0012fecc。这个地址strcpy函数要拷贝字符串的目的地址。
执行完strcpy后,我们在看一下对栈内容,dd /c 1 esp。
晕到。
保存在对栈中的函数的返回地址,居然被改变了,这样黑客就可以通过改变这个地址来执行他想要执行的过程了,当然探索缓存溢出这个工作也不是很容易的。
下面是原码:
#include "stdafx.h"
void foo(const char* input)
{
char buf[10];
//Pass the user input straight to secure code public enemy #1.
strcpy(buf, input);
}
void bar(void)
{
::MessageBox(NULL,"Hacked","hello",MB_OK);
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
foo(lpCmdLine);
return 0;
}
push ebp 函数的返回地址入栈(我理解的是否正确)?
sub esp,0x4c 给当前函数分配空间(为什么分配0x4c)?
mov ecx,0x13 为什么只初始化0x13字节的空间?
0012fedc存放的函数返回后的地址。(为什么比call stacks窗口中的值大四字节)?
以上我的几个问题希望高手告知。谢谢。