30天自制操作系统------保护操作系统

一、攻击(1

使用C语言编写的应用程序擅自修改操作系统管理的内存,导致操作系统的功能出错。

void api_end(void);
   void HariMain(void)
   {
	*((char*)0x00102600)=0;
	api_end();
   }

二、解决办法(1

   为操作系统以及应用程序分配各自的段,互不影响。函数cmd_app(C语言编写)为应用程序分配专用的段。

启动应用程序时,计算机的环境切换过程:操作系统——>应用程序——>操作系统。此部分为start_app函数(由汇编语言编写)完成。

应用程序很有可能会访问保存在操作系统段的API,但是应用程序和操作系统不在同一个段,所以需要进行环境切换:应用程序——>操作系统——>应用程序

 

以上部分并不能解决攻击(1)产生的问题。

x86架构规范中,当应用程序试图破坏操作系统,或者试图违背操作系统的设置时,就会自动产生0x0d中断。也就是说以上攻击会产生0x0d中断,所以为了应对这种中断,我们需要编写0x0d中断函数,并且将其注册在IDT中。

0x0d中断函数应该给出提示信息,并且强制结束应用程序。

给出提示信息的工作可以通过调用INT 0x40来实现,而强制结束应用程序需要正确设置CSEIP。具体的0x0d号中断服务例程如下:

_asm_inthandler0d:
		STI
		PUSH ES
		PUSH DS
		PUSHAD     ;将寄存器的值保存到栈里
		
		MOV AX,SS  ;判断发生中断的环境
		CMP AX,1*8
		JNE .from_app

	    ;操作系统中产生中断	
		MOV EAX,ESP
		PUSH SS  	;保存中断时的SS
		PUSH EAX	;保存中断时的ESP
		MOV AX,SS
		MOV DS,AX
		MOV ES,AX
		CALL _inthandler0d
		
	    ADD ESP,8	
		POPAD
		POP DS
		POP ES
		ADD ESP,4
		IRETD

.from_app:   ;当应用程序中发生中断
		CLI 
		MOV EAX,1*8
		MOV DS,AX			;将DS设为操作系统用
		MOV ECX,[0xfe4]		;操作系统的ESP
		ADD ECX,-8
		MOV [ECX+4],SS		;保存中断时的SS
		MOV [ECX],ESP		;保存中断时的ESP
		MOV SS,AX
		MOV ES,AX
		MOV ESP,ECX
		STI
		CALL _inthandler0d
		CLI 
		CMP EAX,0
		JNE .kill
		POP ECX
		POP EAX
		MOV SS,AX			;将SS设回应用程序用
		MOV ESP,ECX			;将ESP设回应用程序用
		POPAD
		POP DS
		POP ES
		ADD ESP,4
		IRETD
		
.kill:	;将应用程序强制结束
		MOV EAX,1*8
		MOV ES,AX
		MOV SS,AX
		MOV DS,AX
		MOV FS,AX
		MOV GS,AX
		MOV ESP,[0xfe4]		;强制返回到start_app的ESP
		STI					;切换完成后恢复中断请求
		POPAD				;恢复事先保存的寄存器的值
		RET

将应用程序强制结束的代码.kill部分,需要结合start_app函数来看。

asm_inthandler0d已经被注册在IDT中了,即在操作系统段中,当执行这段代码时,CS寄存器已经指向了OS段,若要强制结束应用程序,使得各个寄存器都指向OS段,就需要将其他的段寄存器指向OS段,为了正常返回到OS的环境中,还需要知道下一条指令的地址,才能保证操作系统的正常运行,所以需要首先获得操作系统栈顶的地址,然后才能获得正确的EIP


    start_app函数保存在内存单元0xfe4处的ESP就是如上图所示的ESP,所以要想获得正确的EIP,应该先将8个寄存器的值弹出,然后用RET指令(执行POP EIP的动作)使得程序返回到操作系统的环境中。


三、攻击(2

   攻击(1)之所以可以对操作系统造成影响是因为应用程序擅自访问了操作系统管理的内存空间,我们通过给应用程序分配专用的段、编写相应的异常处理程序解决了这个问题。

但是因为我们是通过C函数cmd_app给应用程序分配专用的段的,而应用程序可以忽略操作系统的分配,自己通过汇编语言可以给各寄存器赋值,任意使用内存空间,这样的话很有可能会对操作系统造成破坏,例如如下应用程序,0x102600为操作系统管理的内存:

[INSTRSET "i486p"]
[BITS 32]
	MOV EAX,1*8
	MOV DS,AX
	MOV BYTE [0x102600],0
	MOV EDX,4
	INT 0x40
  

四、解决办法(2

    攻击(2)之所以会攻击到OS,是因为应用程序擅自向DS存入了OS用的段地址。

在段定义的地方,如果将访问权限加上0x60的话,就可以将段设置为应用程序用,当CS中的段地址为应用程序段地址时,CPU会认为“当前正在运行应用程序”,这时如果存入操作系统用的段地址就会产生0x0d号异常。

也就是说,只需要在cmd_app给应用程序分配专用的代码段和数据段时,将原本的访问权限加上0x60即可,这样一旦应用程序想要擅自向段寄存器中存入OS用的段地址,就会触发0x0d异常,使得应用程序强制结束。

 

如此一来,OS环境与应用程序环境就很明确的分割开来。但是根据x86的规则,是不允许操作系统CALL应用程序的,操作系统向应用程序用的段进行FAR-CALL也是被禁止的。

    那么操作系统如何启动应用程序呢?

此处我们使用了RETF指令,相当于执行POP EIPPOP CS指令,只需要预先将应用程序的CSEIP压栈,那么程序就可以启动应用程序。

为了保证在发生异常时可以正常返回到OS,需要记录OS的栈顶ESPOSESP被保存在tss_esp0处。


版权声明:本文为Xuan0715原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Xuan0715/article/details/75095376

智能推荐

spring与redis整合和序列化问题

spring与redis整合 首先用docker下载redis 下载:docker pull redis 运行:docker run -d -p 6379:6379 --name myredis docker.io/redis 连接redis Desktop Manager 然后开始在springboot上开始配置 application.yml: 自动配置好StringRedisTemplate...

CentOS 7配置南大docker镜像

文章目录 CentOS 7配置南大docker镜像 0.帮助页面 1.系统要求 2.卸载旧版本(没有旧版本可跳过) 3.安装方式 4.准备工作 5.可选操作 Stable Test Nightly 6.安装docker引擎 7. (可选)修改配置文件防止与xshell连接冲突 8.启动docker CentOS 7配置南大docker镜像 0.帮助页面 南大docker源:https://mirr...

Qcon演讲纪实:详解如何在实时视频通话中实现AR功能

2018年4月20日-22日,由 infoQ 主办的 Qcon 2018全球软件开发大会在北京如期举行。声网首席 iOS 研发工程师,iOS 端移动应用产品设计和技术架构负责人龚宇华,受邀分享了《基于 ARkit 和 ARcore,在实时视频通话中实现 AR 功能》,在演讲中剖析了 AR 与 VR 差异,ARKit 的工作原理,以及逐步讲解如何基于 ARKit 与声网Agora SDK 创建 AR...

POJ2348 UVa10368 HDU1525 Euclid's Game【博弈】

Euclid's GameTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4106    Accepted Submission(s): 1947 Probl...

使用Breeze.js编写更好的查询

这篇文章是由同行评审Agbonghama柯林斯 。 感谢所有SitePoint的审稿作出SitePoint内容也可以是最好的! 数据量正在迅速发展,他们正在变得越来越复杂,维护。 许多开发人员希望避免由数据问题他们的工作过程中造成的问题和头痛。 一个使我们的工作更轻松的图书馆是Breeze.js 。 在这篇文章中,我们将讨论我们如何能够写出更好的查询与Breeze.js。 但是首先,我们应该知道什...

猜你喜欢

Netty框架构建Nio编程

~~~ 随手点赞,养成习惯 ~~~ 为什么选择Netty框架 Netty是业界最流行的NIO框架之一,它的健壮性、功能、性能、可定制性和可扩展性在同类框架中都是首屈一指的。 优点: ① API使用简单,开发门槛低 ②功能强大,预置了多种编解码功能,支持多种主流协议 ③ 定制能力强,可以通过ChannelHandler对通信框架进行灵活地扩展; ④性能高,通过与其他业界主流的NIO框架对比,Nett...

【JZOJ5262】【GDOI2018模拟8.12】树(DP,性质题)

Description Solution 首先我们可以知道两个性质:1、路径u-v和路径v-w可以合并为路径u-w;2、路径u1-v1加路径u2-v2和路径u1-v2加路径u2-v1是等价的(就是起始点和终点可以互换) 那么知道这些性质之后就很好做了。我们只用知道每个点多少次做起点和多少次做终点。 我们设f[i]表示满足i子树的需求i上的值要是多少。 那么枚举i的所有儿子,判断a[i]-f[i],...

【String-easy】541. Reverse String II 反转的元素,有反转个数和间隔

1. 题目原址 https://leetcode.com/problems/reverse-string-ii/ 2. 题目描述 3. 题目大意 给定一个字符串,和字符串的间隔k, 这个k表示每k个数反转一次,然后再间隔k个元素再反转k个元素。 4. 解题思路 只要按照间隔去反转就可以了。然后间隔k个元素不反转是通过让i每次递增 2*k完成的。 5. AC代码 6. 相似题型 【1】344. Re...

【C语言笔记结构体】

我们都知道C语言中变量的类型决定了变量存储占用的空间。当我们要使用一个变量保存年龄时可以将其声明为int类型,当我们要使用一个变量保存某一科目的考试成绩时可以将其声明为float。 那么,当我们要做一个学生信息管理系统时,需要保存学生的姓名、学号、年龄等信息,该怎么做呢? 如当要保存三个学生的信息时, 方法一是: 方法二是: 显然,方法二跟更清晰,因为它把name、num、age都集成在一个模板,...

39. Combination Sum 回溯算法简析

LeetCode传送门     这道题要求给你一组正数 C,然后给你一个目标数 T,让你从那组C中找到加在一起等于 T 的那些组合。     例如:给你 [2,3,6,7] 和 7,则返回 [[2,2,3],[7] ] 。      想解决这个问题前,我们首先引入一个新问题,图(树)的遍历问题。  ...