找一个受害者(这里使用的是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搞出一个程序崩溃的窗口。