GRUB2 分析 (三)
接上一篇
从地址0x8200开始的是lzma_decompress.img。这是由startup_raw.S编译生成的。这个文件稍微复杂点。首先一开始就是个跳转指令:
ljmp $0, $ABS(LOCAL (codestart)) /* 机器码:ea 1c 82 */
跳转到0x821c,这里是真正的开始代码。0x8203到0x821b之间存放的是一些特殊数据,如压缩数据前后的长度、冗余数据的长度等,由GRUB安装时填写,后面会用到。
接下来设置实模式堆栈后,切换到保护模式:DATA32 call real_to_prot
然后打开Gate A20,即第21根地址线的控制线: call grub_gate_a20 这是在80286时代IBM想出来的通过开闭Gate A20来兼容8086/8088实模式的方法。在保护模式下,为了正常寻址必须把Gate A20打开。
然后开始利用里德-所罗门(Reed Solomon)算法对GRUB受保护数据进行检查和修复:
call EXT_C (grub_reed_solomon_recover)
RS恢复代码是用C写的,文件是lib/reed_solomon.c。编译时会先编译成rs_decoder.S然后被startup_raw.S包含。(最新的GRUB版本应该生成的文件名是rs_decoder.h,只是改了个名字。)
RS保护的范围以reed_solomon_part标记开始(Gate A20代码后,多重启动代码前),到lzma_decompress.img结尾,再到后面接着的压缩过的kernel.img映像结尾。在此后面是冗余数据区。冗余数据是被算法利用对受保护数据进行修复的。
这样算来GRUB数据的前5个扇区(0-4)以及部分第6个扇区是不受保护的,其他都受到了保护。
为什么要做这件事情?如之前提到的,硬盘2-62号扇区是不安全的,有可能被其他软件写入数据破坏。利用冗余数据,GRUB有能力从这种破坏中正常引导,如果破坏的数据量在可接受范围内的话。我记得GRUB社区有一场讨论,关于如何处理与其他软件冲突的问题。就像一场罗马元老院辩论一样,有人忿忿不平,觉得这种在保留扇区写隐藏数据的行为是邪恶的,GRUB应该以牙还牙,数据恢复过来后,就应该写回硬盘,虽然这会造成其他软件不能工作。也有人认为,普通用户并不会理解这里面的是非曲折,而把一切问题怪罪到GRUB头上,GRUB应仅仅支持防御性的操作。
RS恢复操作执行完后跳转到标记post_reed_solomon对余下的压缩过的kernel.img进行解压缩:
jmp post_reed_solomon /* 偏移量:0x07a6,不同版本会有差异 */
解压后的数据存放在地址0x100000开始的内存区域。
解压算法采用LZMA算法。具体实现在lzma_decode.S中,是手工优化精简的版本。
最后执行跳转指令:
jmp *%esi /* GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR = 0x100000 */
跳转到地址0x100000执行下一条指令。也就是刚才解压缩出来的第一条指令。
至此startup_raw.S执行完毕。
GRUB2 分析 (三)的更多相关文章
- tomcat源码分析(三)一次http请求的旅行-从Socket说起
p { margin-bottom: 0.25cm; line-height: 120% } tomcat源码分析(三)一次http请求的旅行 在http请求旅行之前,我们先来准备下我们所需要的工具. ...
- 一些有用的javascript实例分析(三)
原文:一些有用的javascript实例分析(三) 10 输入两个数字,比较大小 window.onload = function () { var aInput = document.getElem ...
- Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理
相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...
- 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入
使用react全家桶制作博客后台管理系统 前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...
- Nouveau源代码分析(三):NVIDIA设备初始化之nouveau_drm_probe
Nouveau源代码分析(三) 向DRM注冊了Nouveau驱动之后,内核中的PCI模块就会扫描全部没有相应驱动的设备,然后和nouveau_drm_pci_table对比. 对于匹配的设备,PCI模 ...
- Linux I2C驱动分析(三)----i2c_dev驱动和应用层分析 【转】
本文转载自:http://blog.chinaunix.net/uid-21558711-id-3959287.html 分类: LINUX 原文地址:Linux I2C驱动分析(三)----i2c_ ...
- [ipsec][strongswan] strongswan源码分析-- (三) xfrm与strongswan内核接口分析
目录 strongwan sa分析(三) xfrm与strongswan内核接口分析 1. strongswan的实现 2. 交互机制 4. xfrm的消息通信的实现 strongwan sa分析(三 ...
- 13 数组 Java内存分析 三种初始化
Java内存分析 三种初始化 静态初始化 //静态初始化 创建+赋值 int[] a = {1,2,3}; Man[] mans = {new Man(1,1),new Man(2,2)}; 动态初始 ...
- ABP源码分析三:ABP Module
Abp是一种基于模块化设计的思想构建的.开发人员可以将自定义的功能以模块(module)的形式集成到ABP中.具体的功能都可以设计成一个单独的Module.Abp底层框架提供便捷的方法集成每个Modu ...
随机推荐
- 让iOS应用支持不同版本的系统与设备
本文转载至 http://blog.csdn.net/pucker/article/details/11980811 最近一直在做app的iOS 6和7的同时适配工作,所以在此介绍一下系统与设备的兼 ...
- python中的coding的格式书写形式
# -*- coding:utf-8 -*-可以改写成以下各种形式:1,# -*- coding=utf-8 -*-2,# _*_ coding=utf-8 _*_3,# coding:utf-84 ...
- 帧动画和骨骼json、极速、二进制对比
对比总结: 1. 帧动画的效率最高,但是图片超过一定帧数,资源图片非常大.比较适合帧数少,大量动画存在,要求效率高的场合. 骨骼json效率较低,已经不推荐使用. 骨骼极速,不支持网格等. 骨骼二进制 ...
- 微信小程序-云开发(手记)
微信小程序-云开发(手记) 1.创建data.json文件 注意以下几点要求: 入门示例: init方法的env:默认环境配置,传入字符串形式的环境 ID(理解为数据库)可以指定所有服务的默认环境(意 ...
- 【Python数据挖掘】决策树、随机森林、Bootsing、
决策树的定义 决策树(decision tree)是一个树结构(可以是二叉树或非二叉树).其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出,而每个叶节点存放一个类别. ...
- 剑指Offer——删除链表中重复的结点
题目描述: 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理 ...
- post 传递参数中包含 html 代码解决办法,js加密,.net解密
今天遇到一个问题,就是用post方式传递参数,程序在vs中完美调试,但是在iis中,就无法运行了,显示传递的参数获取不到,报错了,查看浏览器请求情况,错误500,服务器内部错误,当时第一想法是接收方式 ...
- apache2.2版本 configuration error: couldn't perform authentication. AuthType not set!: /
configuration error: couldn't perform authentication. AuthType not set!: / 500服务器错误 解决方案: <Dire ...
- 深入浅出MySQL-DDL语句
DDL语句 DDL是数据定义语言的缩写,简单来说,就是对数据库内部的对象进行创建.删除.修改等操作的语言.它和DML(数据操纵语言)的最大区别是DML知识对表内部的数据操作,而不涉及表的定义.结构的修 ...
- php实现异步的程序调用
浏览器和服务器之间的通信是基于HTTP协议进行链接通讯的,它是一种请求和相应的协议.浏览器通过URL向服务器发送请求,服务器接收到请求并执行请求,然后服务器将执行完成的数据返回到客户端. 这就存在一个 ...