zl程序教程

您现在的位置是:首页 >  其他

当前栏目

线程第一次启动和异常的注册(UEF的一个特性)

注册异常线程 一个 启动 特性 第一次
2023-09-11 14:13:58 时间

找一个受害者(这里使用的是win 7 x32的)

这些都是之前做的现在出来上班怕到时又忘记了所以记录一下,这里是从r3开始记录的

首先需要找到一个进程用来观察它的线程的入口地址是多少,使用命令!process 0 0,如下图

最简单的方式就是挂靠到它,使用命令.process /i ,之后按g放行就挂上去了

 

之后使用!process可以找到ethread的地址,使用dt _ethread  875b9568命令查看当前ethread下的StartAddress

反汇编0x76e17098 地址,这里没有符号不方便分析当然可以指定加载ntdll的符号,但是为了方便我使用ida。

打开ida然后把箭头执行的段给重新设置,设置和当前进程的ntdll一样(这里windbg命令不熟悉可以加载到od中看ntdll的基地址)

跳到指定的位置按g

可以看到在win7 x32下线程执行的第一个函数为RtlUserThreadStart,eax是入口地址,ebx是Share_User_Data

进行往下可以看到第一次注册异常处理函数。

这个是try_except写的,展开比较麻烦。

 

最后跳到BaseThreadInitThunk执行第一个main函数

到目前位置我们知道了线程第一次调用的函数,以及在哪里注册的,这里需要说的是UEF(这个是基于栈的,也就是说这个是刚刚异常注册的处理函数)的一个反调试。

如果要手动注册一个UEF的话需要使用SetUnhandledExceptionFilter这个函数,反编译之后如下,自己注册的异常处理函数会被加密之后放放在BasepCurrentTopLevelFilter全局变量里面,这里可以看看被那些地方引用。

这里被UnhandledExceptionFilter所引用了,之前注册的异常处理函数会将异常分发到这个函数,但是在这之前会先检测是否有调试器,如果没有才会执行异常处理函数,检测用的是 NtQueryInformationProcess,这里绝大多数的od是没有hook它的,那么如果想反调试的话可以先抛出异常,之后将异常处理函数放在UEF里面,检测到有调试器就不会执行(这里建议在x32平台运行,有些od自带驱动,通常是过了的,但是你在x64平台运行这一关就有可能过不了)。其他的seh vch veh都没有这个特点。然后异常处理函数的执行流程说明一下veh seh uef vch,最后没人处理就会调用csrss搞出一个程序崩溃的窗口。