首页
社区
课程
招聘
[原创]cpu异常浅析
发表于: 2017-6-16 21:57 9177

[原创]cpu异常浅析

2017-6-16 21:57
9177

cpu内部产生的异常(软中断)可分为2:

 

1.陷阱,由代码执行int xx指令,指令执行成功后陷入内核,根据idt表中对应的段描述符,执行对应的中断处理函数,因为是int xx执行成功后才陷入的内核,中断处理函数中得到的异常触发地址为int xx的下一条指令的地址

 

2.故障,一条指令可以分解为多条微指令,如在执行div ecx,该指令被分为多条微指令,执行过程中,微指令会先判断操作数的值是否符合要求,如果此时ecx的值为0不符合要求,会产生除0故障(类似int 0指令的效果),陷入内核后,对于cpu来说,该故障已经被处理,

对于操作系统来说异常处理才刚刚开始,这里我们不谈操作系统的异常处理,此时该指令还没执行完毕,应该说执行失败,中断处理函数中得到的异常触发地址为该指令的地址

 

例子:触发一个故障

#include <stdio.h>

 

int main(int argc, char *argv[])

{

    _asm int 0x20;

    return 0;

}

在执行int 0x20过程中,微指令判断对应的门描述符是否有效,要陷入的函数权限是否符合要求,任意不满足则触发故障,指令执行失败。

0x20号中断在idt中的描述符为0000000000080000,描述符p位为0,描述符无效,该指令执行失败触发一个故障,故障产生于应用程序,对于操作系统来说是一个3环异常,所以产生如下效果

 

 

例子:触发一个陷阱一个故障

#include <stdio.h>

 

int main(int argc, char *argv[])

{

    _asm int 0x20;

    return 0;

}

依旧使用int 0x20,此时我们使用windbg修改idt表将0x20号的门描述符修改为对于cpu来说,3环程序可用的门描述符

0号门描述符的地址为0x80b95400

20 号门描述符的地址应为 0x80b95400 + 0x20*8 = 0x80b95500

修改为0000 ee 00 0008 0000,此时虽然中断处理函数的地址为00000000,但对于cpu来说是一个3环程序可用的门描述符

 


int 0x20执行成功后程序陷入0,并且试图去0地址执行代码,对于cpu来说陷阱已经处理完毕,windows0-0xffff地址为空指针区域,都不是一个合法区域,所以会产生一个访问冲突的0环异常,其对应一个故障,我们在程序的内核态中并没有注册过任何seh结构化异常处理函数,所以该异常将成为一个不可除去的异常,因为处于0环导致系统崩溃蓝屏

 

例子:触发两个故障

#include <stdio.h>

 

int main(int argc, char *argv[])

{

    _asm{

       xor ecx, ecx;

       div ecx

    }

    return 0;

}

该程序会产生一个除0的故障对应中断号为0.

门描述符为84038e0000088650这是一个0环才可用的门描述符,但是我们在3环下触发除0异常,可以使用到此门,这可能是cpu体供的一些特殊机制,对此我们不深究.

 

当跳转到该门的中断函数地址后,cpu视为该故障已被处理,正常情况下,将执行系统的异常处理机制,此时我们修改该门描述符为00008e0000080000,只修改了中断处理函数,第一个故障处理后cpu将处于0环模式并且试图在0地址执行代码之后流程和之前情况相同蓝屏


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 4
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  CCkicker   +1.00 2017/07/12
最新回复 (13)
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
最后是一个三重故障,三重故障没有对应的故障处理例程,如果发生这种故障,cpu会直接重启
2017-6-17 01:04
0
雪    币: 370
活跃值: (51)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
yy虫子yy 最后是一个三重故障,三重故障没有对应的故障处理例程,如果发生这种故障,cpu会直接重启
如果命名的话,我感觉叫多重故障比较贴切一点
2017-6-17 08:04
0
雪    币: 2575
活跃值: (502)
能力值: ( LV2,RANK:85 )
在线值:
发帖
回帖
粉丝
4
这个微软有公开的资料吗?
2017-6-17 09:00
0
雪    币: 759
活跃值: (2359)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
我记得复现双重故障的一个方法就是在驱动中进行无限递归,导致rsp到达栈边界。
2017-6-17 10:13
0
雪    币: 370
活跃值: (51)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
wyfe 这个微软有公开的资料吗?
微软有没有我不知道,intel的IA-32手册上肯定有
2017-6-20 18:53
0
雪    币: 370
活跃值: (51)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
我是哥布林 我记得复现双重故障的一个方法就是在驱动中进行无限递归,导致rsp到达栈边界。
嗯嗯,系统栈的大小是很有限的,在写驱动的时候,很容易出现满栈的问题,导致发生页错误的异常,而上面有说到,对于cpu来说,操作系统通过陷阱门成功陷入内核态,便是一次成功的异常处理,这里我略过了一些细节,cpu在通过陷阱门陷入内核过程中,会在系统栈中压入一些异常信息,而系统栈已经达到边界,导致陷入内核态失败,引发双重故障,这个也是非常经典的问题,终于遇到明白人了
2017-6-20 19:07
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
布衣勇者 嗯嗯,系统栈的大小是很有限的,在写驱动的时候,很容易出现满栈的问题,导致发生页错误的异常,而上面有说到,对于cpu来说,操作系统通过陷阱门成功陷入内核态,便是一次成功的异常处理,这里我略过了一些细节, ...
引发双重故障也会压栈,但是系统栈满了,最后导致三重故障重启
2017-6-27 16:10
0
雪    币: 2575
活跃值: (502)
能力值: ( LV2,RANK:85 )
在线值:
发帖
回帖
粉丝
9
布衣勇者 微软有没有我不知道,intel的IA-32手册上肯定有
多谢!
2017-7-11 19:08
0
雪    币: 4120
活跃值: (5822)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
10
是否可以用来攻击QUEM虚拟类和云计算的系统
2017-7-12 14:31
0
雪    币: 36
活跃值: (102)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
mark
2017-7-13 17:27
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
大神请教下,我们的linux系统宕机后,没有任何日志打印,该节点ping不通,ssh登录不了;只能通过按钮硬复位重启恢复;以你的经验,CPU的错误指令可以导致这个问题嘛?
2020-4-11 16:11
0
雪    币: 1108
活跃值: (3896)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
13
转眼三年过去了,时间好快啊。
2020-4-11 16:32
0
雪    币: 922
活跃值: (1813)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
14
转眼,3年了啊
2023-1-28 20:42
0
游客
登录 | 注册 方可回帖
返回
//