• 线程第一次启动和异常的注册(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搞出一个程序崩溃的窗口。

  • 相关阅读:
    在Docker容器中修改PostgresSQL最大连接数
    2024比较赚钱的项目是什么?亲身经历,月入过万!
    c++11 入门基础
    AI大模型日报#0421:「个性化」图像Gen4Gen框架、吴恩达亲授智能体设计模式、国内14大LLM最新评测报告
    【分析BMI指数~python】
    springboot仓库管理系统
    获得淘宝商品快递费用接口调用展示
    GEE:关系、条件和布尔运算
    【Java】常用API——ArrayList类
    RocketMQ源码(10)—Broker asyncSendMessage处理消息以及自动创建Topic
  • 原文地址:https://blog.csdn.net/lyshark_lyshark/article/details/126794875