看雪CTF签到题SEH异常处理--MysteriousLetter2

先看程序主逻辑


这里可以看到要求输入六位的序列号,最后三位是353,然后前三位的和是5.
但是我们并没有发现success的提示。
我们搜索并定位

可以看到success的提示在except里面

这里我们要提到SEH(结构化异常处理),这是Windows下的一种异常处理机制。

简单介绍一下SEH。

参考加密与解密

  • 功能
    SEH实际包含两个主要功能:结束处理(termination handling)和异常处理(exception handling)
    每当你建立一个try块,它必须跟随一个finally块或一个except块。
    一个try块之后不能既有finally块又有except块。但可以在try-except块中嵌套try-finally块,反过来 也可以。
    __try,__finally关键字用来标出结束处理程序两段代码的轮廓
    不管保护体(try块) 是如何退出的。不论你在保护体中使用return,还是goto,或者是longjump,结束处理程序 (finally块)都将被调用。
    在try使用__leave关键字会引起跳转到try块的结尾
  • TIB结构:在用户模式下,TIB(ThreadInformationBlock)位于TEB的头部。而TEB是操作系统为了保存每个线程的私有数据创建的,每个线程都有自己的TEB。
nt!_TEB
   +0x000 NtTib            : _NT_TIB
   +0x01c EnvironmentPointer : Ptr32 Void

我们看一下TIB的结构

typedef struct _NT_TIB          //sizeof  1ch
{
 00h   struct _EXCEPTION_REGISTRATION  *ExceptionList;          //SEH链入口
 04h   PVOID                            StackBase;              //堆栈基址
 08h   PVOID                            StackLimit;             //堆栈大小
 0ch   PVOID                            SubSystemTib;
       union {
           PVOID                FiberData;
 10h       DWORD                Version;
       };
 14h   PVOID                            ArbitraryUserPointer;
 18h   struct _NT_TIB                   *Self;                  //本NT_TIB结构自身的线性地址
}NT_TIB;

我们看到,ExceptionList在TIB的头部。而在X86下,TEB总是由fs:[0]指向的。
ExceptionList是一个链表的结构.
画了一个流程图便于理解

+---------+    +----------------+      +---------------+
| 发生异常 +--->+   TIB          +----->+   Next        +--+
|         |    |   fs:[0]       |      +---------------+  |            +------------------+
+---------+    +----------------+      |   Handler     +-------------->+  异常处理函数     |
                                       +---------------+  |            |  ...             |
                                                          |            |  retn            |
                                               +----------+            +------------------+
                                               |
                                       +-------v-------+
                                       |   Next        +--+
                                       +---------------+  |            +------------------+
                                       |   Handler     +-------------->+  异常处理函数     |
                                       +---------------+  |            |  ...             |
                                                          |            |  retn            |
                                               +----------+            +------------------+
                                               |
                                       +-------v-------+
                                       |  FFFFFFh      |
                                       +---------------+               +------------------+
                                       |   Handler     +-------------->+  异常处理函数     |
                                       +---------------+               |  ...             |
                                                                       |  retn            |
                                                                       +------------------+

next是下一个链的地址。如果next的值是FFFFFFh,表示是链表的最后一个节点,该节点的回调函数是系统设置的一个终结处理函数,所有无人值守的异常都会到达这里。
异常处理函数可以是自定义的函数,系统有一个默认的函数,但我们可以自定义一个异常处理函数,让它来处理。
但是得先安装自定义函数才能使用。
我们可以写一个异常处理的例子

//Powered by HAPPY
#include <Windows.h>
#include <iostream>
int exception_memory_access_violation(LPEXCEPTION_POINTERS p_exinfo)
{
    if (p_exinfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
    {
        return  EXCEPTION_EXECUTE_HANDLER; //handle this exception
    }
    else return EXCEPTION_CONTINUE_SEARCH; //Do not handle this exception
}

int main()
{
    char* mem = 0;
    std::cout << "Hello World!\n";
    __try {
        *mem = 0; //throw exception
    }
    __except (exception_memory_access_violation(GetExceptionInformation()))  //handler
    {
        puts("Memory error in except");
    }
}

我们可以将其编译后反汇编研究下except的代码以及是如何安装SEH的。限于篇幅,我们不做深入探究。了解更多可以看一下https://blog.csdn.net/w1012747007/article/details/77131781

异常分析

这里,我们看到filter(这是IDA自动生成的提示)


0x401373filter返回1,即EXCEPTION_EXECUTE_HANDLER,意思是捕获该异常,也就是说无论发生什么异常,都将被0x401379的异常处理捕获。
这里,我们知道了,如果想要程序输出success,程序中就需要出现一次异常。让0x401379的exception执行.
我们从try块开头开始分析。

这里的给ms_exc.registration.TryLevel赋值是用于处理嵌套的try。trylevel为0表示最外层,具体可以参见此处
大致的流程如下

esi的值是输入的序列号转为十六进制的结果。(例如输入的序列号是110799,那么esi就是0x110799)

重点来看0x401354的处理,我们分析一下执行到0x401354时帧栈

+--------+
| eax    |
+--------+
| EIP    +->0x401353 (call会把下一条汇编的地址压入。)
+--------+
|        |
+--------+


执行完0x401354,eax就是0x401353
然后div的时候,如果esi的值是0,就会触发异常,也就是我们想要的结果。
我们只需要esi的值原来是0x401353,也就是和eax一样。
而esi的值的由来前面分析过,所以序列码就是401353

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,036评论 1 32
  • 【JAVA 线程】 线程 进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者...
    Rtia阅读 2,702评论 2 20
  • Java SE 基础: 封装、继承、多态 封装: 概念:就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽...
    Jayden_Cao阅读 2,048评论 0 8
  • 整理来自互联网 1,JDK:Java Development Kit,java的开发和运行环境,java的开发工具...
    Ncompass阅读 1,516评论 0 6
  • 前些年读过一篇散文,名字就是《每次醒来,你都不在》。每每重复读它,眼珠子都会通红。这么诛心的话语,总让我和苏轼的“...
    德润长江阅读 204评论 0 1