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


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

  • 相关阅读:
    前端杂七杂八
    用户数据分析
    hash表
    django杂七杂八
    redis事务
    CF1457D XOR-gun
    后缀数组学习笔记
    CF1439C Greedy Shopping
    P3320 [SDOI2015]寻宝游戏
    P5327 [ZJOI2019]语言
  • 原文地址:https://www.cnblogs.com/csnd/p/16675606.html
Copyright © 2020-2023  润新知