#include "stdafx.h"
#include <windows.h>
#include<fstream>
#include<iostream>
using namespace std;
int main()
{
MessageBox(NULL,L"DSA",0,0);
char buf[10];
int eip=(int)main;
memcpy(buf+88,(int*)&eip,4);
_asm
{
//触发异常
xor eax,eax
mov dword ptr[eax],0;
}
#include <windows.h>
#include<fstream>
#include<iostream>
using namespace std;
int main()
{
MessageBox(NULL,L"DSA",0,0);
char buf[10];
int eip=(int)main;
memcpy(buf+88,(int*)&eip,4);
_asm
{
//触发异常
xor eax,eax
mov dword ptr[eax],0;
}
}
该程序实现的是主函数的死循环调用,至少在笔者的系统上是这样,可能换到您自己的机子上,88的偏移量也许会有所不同,
在现在主流系统上已经有了GS/的缓冲区保护,也就是说,如果我们使用传统的栈溢出时,函数执行完毕后会发现堆栈已经被溢出,从而不再去执行返回地址所指向的代码,转而
执行SEH(异常处理过程),对于绕过GS/保护,我们使用的方法主要是使用SEH覆盖
:如上代码,在覆盖SEH之后主动去,主动去触发一个异常,不在让其发现堆栈被溢出了。让程序主动去执行我们已经覆盖的SEH的地址,在本例程中也就是循环执行主函数
对于SEH覆盖现在有了safeseh编译选项,也就是说对于SEH中的地址有了有效性检验,如果该地址不被信任,则不再执行...
对于该地址,我们可以使用的有:
1.堆地址
2.加载模块之外的地址,即系统dll
3.未启用safeseh模块的地址
对于模块是否启用了safeseh,也就是看看IMAGE中的目录表中的第十一项,是否配置了异常处理函数地址,如果没有,则未启用SAFESEH