wenmo8 发布的文章

以栈作为基础的SEH本身具有很大的危险性,我们可以利用各种手段对栈上SEH节点进行覆盖重写,再次执行异常处理操作时就会将执行权给到了我们用来覆盖的函数上,这实际上在以前是很常见的windows栈溢出手段,当然,除了这种方法外还有许许多多的利用手段,可见这样的异常处理机制还是不够完善的。为了解决这些问题,微软逐步加入了Safe SEH、SEHOP、VCH等来弥补。

Safe SEH

SafeSEH又叫做软件DEP,是一种在软件层面实现的对SEH的保护机制,它需要操作系统和编译器的双重支持,在vs2013及以后的版本中会自动启用 /SafeSEH 链接选项来使用SafeSEH。也正是因为该项技术使得以往简单的覆盖异常处理句柄的漏洞利用几乎失效了

在加载PE文件时,SafeSEH将定位合法的SEH表的地址(如果该映像不支持SafeSEH的话则地址为0),然后是用共享内存中的一个随机数进行加密处理,程序中所有的异常处理函数的地址提取出来汇总放入SEH表,并将该表放入程序映像中,还会将将加密后的SEH函数表地址,IMAGE的开始地址,IMAGE的长度,合法SEH函数的个数,作为一条记录放入ntdll(ntdll模块是进行异常分发的模块)的加载模块数据内存中,每次调用异常处理函数时都会进行校验,只有二者一致才能够正常进行,该处理由RtlDispatchException() 开始,首先会经历两次检查,分别是:

  • 检查异常处理链是否在当前的栈中,不是则终止
  • 检查异常处理函数的指针是否指向栈,是则终止

通过两次检查后会调用RtlIsValidHandler() 来进行异常的有效性检查,08年的black hat给出了该函数的细节

BOOL RtlIsValidHandler( handler )
{
if (handler is in the loaded image) //是否在loaded的空间内 {if (image has set the IMAGE_DLLCHARACTERISTICS_NO_SEH flag) //是否设置了忽略异常 returnFALSE;if (image has a SafeSEH table) //是否含有SEH表 if (handler found in the table) //异常处理函数地址是否表中 returnTRUE;else returnFALSE;if (image is a .NET assembly with the ILonl y flag set)returnFALSE;
}
if (handler is on non-executable page) //handler是否在不可执行页上 {if (ExecuteDispatchEnable bit set in the process flags) //DEP是否开启 returnTRUE;elseraise ACCESS_VIOLATION;
}
if (handler is not in an image) //handler是否在未加载空间 {if (ImageDispatchEnable bit set in the process flags) //设置的标志位是否允许 returnTRUE;else returnFALSE;
}
return TRUE; /s/允许执行异常处理函数
}

我的应用程序,一个可执行文件,正在远程计算机上崩溃。我没有访问那台机器的权限,所以我请求了一个转储,通过任务管理器生成。使用WEBBG,在执行命令!analyze -v时,我可以看到许多其他的文本

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 0000000000000000
ExceptionCode: 80000003 (Break instruction exception)
ExceptionFlags: 00000000
NumberParameters: 0


我怎么知道它是不是对坠机事件负责?如果不是,我如何确定真正的原因?

 int3断点是根本原因吗?

我一直想知道更多关于这个问题的信息,但运气不太好。我一直在读,应用程序不应该出现这个错误,它不告诉我什么可以导致这个错误出现。我知道这个问题非常宽泛,因为我确信这个错误可能有多种原因,所以我会尽量缩小范围。我在VS2015中开发了一个使用C++ .NET的应用程序。应用程序主要使用非托管代码,很少使用托管代码(由于垃圾收集器的严重干扰)。所以我认为95%是非托管的,5%是托管的。我在某个地方读到过,不稳定/错误/不正确的非托管代码可能会扰乱CLR内存的某些部分,使其损坏并引发此错误。由于95%的应用程序是非托管的,我不知道从哪里开始查找。可能是少数几个在托管和非托管之间交互的类?如何将数据从托管封送到非托管?错误的空指针会导致此失败吗?还有什么问题会导致这种情况?数组索引越界?空对象呢?
如果您能提供有关System.ExecutionEngine故障可能原因的详细列表,我们将不胜感激!可能原因/情况列表如下:

  • C++与C语言的参数失配
  • 使用反射时
  • WCF服务试图在此处返回IList或IEnumerable
  • 使用分析工具
  • 在汇编程序中使用std指令
  • 多次调用::FreeLibrary()
  • .NET剪贴板调用
  • 使用统一框架
  • 使用错误的封送处理
  • 使用INotifyPropertyChanged

什么是FileNotFoundException?

尝试访问磁盘上不存在的文件失败时引发的异常。如果你的代码没有 PathDiscovery 的权限,则此异常的错误消息可能只包含文件或目录名称,而不是完全限定的路径。

继承