以芯片直读方式得到的全盘镜像解析及ext4日志区域解析
之前在centos中分析了/dev/sda1下的结构,但当对象是一块以芯片直读方式作出来的全盘镜像呢?
这次以安卓手机的全盘镜像为对象,尝试按照ext4文件系统结构手动解析,加强对ext4文件系统、EFI系统分区、GPT磁盘的理解,补充ext4文件系统的日志结构的描述。
我得到的全盘镜像有两种格式,一种.img,一种是.bin,两种镜像的组织方式是比较类似的,但可能因为是不同的直读机做出的原因,.img格式的镜像在“真正的数据”前附加了机器的标志信息。
.bin格式镜像分析
.bin格式全盘镜像是以GPT分区的方式进行管理的,GPT磁盘的总体布局如下:

.bin格式的全盘镜像头512个字节也就是0号扇区的内容是一个DOS分区,分区表的内容如下:

该分区表只有一个表项被使用,记录的分区起始扇区号是0x01,分区扇区数是:0xDA BF FF,0号扇区最后两个字节就是MBR扇区的有效标志0x55 AA。当然在dos分区表前面还有446个字节的引导代码区域,这里的引导代码没有写,就没有截图了。
接下来我们看1号扇区的内容,按照GPT磁盘的总体布局,1号扇区是EFI信息区也就是GPT头,他对解析GPT分区是很关键的存在,因为其中记录了GPT分区表、GPT分区区域的位置以及大小,分区表中每个表项的大小(字节数),下面是1号扇区部分内容:

可以看到前7个字节是EFI分区的签名“EFI PART”,0x28-0x2F处是GTP分区区域的起始块号,接下来8个字节是终止块号,0x47-0x4F处的8个字节是GPT分区表的起始块号,接下来的4个字节是GPT分区表表的项数,然后四个字节是GPT分区表每一项的字节数。
从2号扇区到33号扇区存储的就是GPT分区表,包括我们表熟悉的/system,/boot,/userdata分区等等,以/userdata分区为例,查看他的GPT分区表项:

前16个字节是分区类型GUID,接下来16个字节是分区的唯一GUID,然后8个字节是分区起始扇区号,接下来是分区终止扇区号,再8个字节是分区属性,后面一直到这个表项结束都是分区名的Unicode码。
我们查看0x564000号扇区的内容(偏移0x564000*0x200=0xac800000)发现内容是全0,然后在偏移量增加0x400后发现了ext4的超级块结构,这和对单个分区的解析结果是一致的,说明我们解析全盘镜像的时候,与解析单个分区相比,只是增加了解析EFI分区和GPT分区的部分。
/userdata分区日志分析
接下来通过解析一下/userdata分区的日志部分,来记录ext4的日志结构。
查看/userdata分区的超级块,得到该分区中块的0号块组的起始块号是0,每个块组有0x8000个块、0x2000个i节点,每个块大小是0x1000个字节,i节点表的每个表项长度是0x100个字节。
接下来我们需要通过查看块组描述符表来得知每个块组的i节点表起始块号。块组描述符表的起始块号分三种情况:
1、当块的大小为0x400时,块组描述符表在2号块(偏移0x800处)
2、当块的大小为0x800时,块组描述符表在1号块(偏移0x800处)
3、当块的大小为0x1000时,块组描述符表在1号块(偏移0x1000处)
这里计算块组描述符表的时候需要加上分区的起始偏移0xac800000,也就是0xac801000

可以看到0号块组的i节点表起始块号是0x0303,我们知道ext4文件系统的8号i节点是日志节点,我们来查看8号i节点的内容以找到日志所在块号。
8号i节点所在的偏移为:0xac800000+0x0303*0x1000+(8-1)*0x100=oxacb03700:

可以看到该i节点的extent结构中,有两个有效的entry,extent_header的深度为0,第一个extent结构记录的块号是0x0503,第二个extent记录的块号是0x0504。
我们查看0x0503块号的内容,计算该块的偏移位置:0xac800000+0x0503*0x1000=0xacd03000
在查看日志内容前我们需要清楚一点,ext4文件系统整个是小端模式,但ext4的日志区域确实大端模式

上面是一个日志的超级块部分内容,前12个字节是ext4日志的标准头,通过他我们可以区分某个块是否是日志块,是日志块的哪个部分。前4个字节ext4的日志签名“c0 3B 39 98”,然后四个字节是日志块类型,0x04是超级块(版本2),0x01是描述符块,0x02是提交块,0x03是超级块(版本1),0x05是废除块,然后四个字节是序号。接下来就进入了超级块的内容,前4个自己是日志块的大小,一般和普通文件的块大小是相同的,接下来4个字节是日志块的数量,然后4个字节是日志的实际起始块号,然后4个字节是第一个事务序号,接下来4个字节是第一个事务序号的日志块号,这里所提到的日志块号都是相对于日志区域的,因此在使用的时候需要进行转换。
接下来我们查看1号日志块的内容,

1号块开始4个字节是日志标准头的签名,接下来的4个字节的属性值为0x01,说明这是一个描述符块,标准头结束后就是真正的描述符块的内容,0x2E 00 02是这组记录的文件系统块号,接下来4个字节是项标志。项标志有四种,分别为:0x01(日志块避开),0x02(与前面具有相同的UUID,此时没有后面的UUID区域),0x04(本块已经被事务删除),0x08(本描述项为描述块中的最后一个描述项)。红框框出本描述符块记录的部分块号。接下来的块将按照描述符块中记录的块号顺序“抄写”文件系统块。

上面是下一个块的部分内容,可以看到这是对i节点表所在块的“抄写”,当然读这块内容的时候需要依照小端模式读取。
在描述符块中记录的块号被“抄写”完成后,会有一个日志提交块紧随其后,表明一个日志记录的完成

观察可发现,该日志提交块的事务序号和日志描述符块的事务序号是相同的。
以上就是简单解析一个ext4日志区域的过程。
另外.img格式的镜像,我目前看到的除了在EFI分区信息前面添加了制作镜像的机器信息外,其他结构和.bin是一样的。
以芯片直读方式得到的全盘镜像解析及ext4日志区域解析的更多相关文章
- kafka直连方式消费多个topic
一个消费者组可以消费多个topic,以前写过一篇一个消费者消费一个topic的,这次的是一个消费者组通过直连方式消费多个topic,做了小测试,结果是正确的,通过查看zookeeper的客户端,zoo ...
- SRAM(静态)存储器芯片的读/写周期
一. 要保证正确地读/写,必须注意CPU时序与存储器读/写周期的配合.一般存储器芯片手册都会给出芯片读/写周期的时序图. Intel 2114芯片的读.写周期时序如图所示. 二. 读周期 读操作时,必 ...
- Dubbo直连方式
目录 一.dubbo概述 1. 基本架构 2. dubbo 支持的协议 二.直连方法 三.创建服务提供者 1. 思路 1. 创建maven web 2. pom.xml 3. 创建实体 4. 创建服务 ...
- SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量
SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量 1. ScalikeJDBC 2.配置文件 3.导入依赖的jar包 4.源码测试 通过MySQL保存kafka的偏移量 ...
- STM32-对芯片启动读保护,实现加密(详解)
STM32可以对存储在flash上的程序进行读保护. 启动读保护后,用户就不能再读写程序了. 所以,在烧写程序之前,需要程序调用关闭读保护.关闭读保护后,会自动清空flash上的程序 头文件位于:#i ...
- 内存直读技术DMA
DMA(Direct Memory Access) DMA(Direct Memory Access)即直接存储器存取,是一种快速传送数据的机制. 工作原理 DMA是指外部设备不通过CPU而直接与系统 ...
- 直读Innodb datafile
这两天有空翻了翻大神写的<innodb存储引擎>,手痒亲身实践.由于此书出版了有段时日,没有用其推荐的python工具,通过点滴推敲,略微发现其中冰山一角的奥秘.对于今后对于一些问题查证或 ...
- css水平竖直居中方式
CSS水平和垂直居中的几种实现方法: 1.单行垂直居中 文字在层中垂直居中vertical-align 属性是做不到的.我们这里有个比较巧妙的方法就是:设置height的高度与line-height的 ...
- Dubbo直连方式改造
目录 一.dubbo 服务化最佳实践 1. 分包 2. 粒度 3. 版本 二.改造 dubbo 项目 三.link-interface 1. pom.xml 2. 实体类 3. 公共接口 四.提供者 ...
随机推荐
- 开涛spring3(6.9) - AOP 之 6.9 代理机制
Spring AOP通过代理模式实现,目前支持两种代理:JDK动态代理.CGLIB代理来创建AOP代理,Spring建议优先使用JDK动态代理. JDK动态代理:使用java.lang.reflect ...
- 【 js 基础 】作用域和闭包
一.编译过程 常见编译性语言,在程序代码执行之前会经历三个步骤,称为编译. 步骤一:分词或者词法分析 将由字符组成的字符串分解成有意义的代码块,这些代码块被称为词法单元. 例子: var a = 2 ...
- ArcGIS 网络分析[2.5] VRP(车辆配送)
什么是VRP? VRP就是车辆配送. 大家有没有想象过一个城市的某个快递营业点,是怎么让各个快递员配送快递的? 每个快递员针对那片区域的客户,如何走路线才最省时间? 也许你会说,最短路径分析可以做到— ...
- 入职这一段时间的总结,Don't Repeat Yourself.
1.第一次接触到大型软件系统的开发,现在我们使用的是 python + flask +vue.js ,数据库:postgresql 2. 不要在自己不懂的情况下复制代码,每次分析一段代码的时候,就跟以 ...
- 基于谱聚类的三维网格分割算法(Spectral Clustering)
谱聚类(Spectral Clustering)是一种广泛使用的数据聚类算法,[Liu et al. 2004]基于谱聚类算法首次提出了一种三维网格分割方法.该方法首先构建一个相似矩阵用于记录网格上相 ...
- Nodejs-express 4.0框架 简单介绍
http://www.expressjs.com.cn/4x/api.html 这个是express API的中文手册 但是只是翻译了一点 英语比较差比较难受. 1. 关于安装 现在网上查的时候有一 ...
- Java中4种类型的内部类 .
在Java中有4种不同类型的内部类可以使用.下面给出它们的名称和例子. 1.静态嵌套类(Static Nested Classes) class Outer { static class Inner ...
- 关于redis内部的数据结构
最大感受,无论从设计还是源码,Redis都尽量做到简单,其中运用到的原理也通俗易懂.特别是源码,简洁易读,真正做到clean and clear, 这篇文章以unstable分支的源码为基准,先从大体 ...
- 干货 | 云智慧透视宝Java代码性能监控实现原理
这篇图文并茂,高端大气上档次,思维缜密的文章,一看就和我平时的风格不同.对了.这不是我写的,是我家高大英俊,写一手好代码,做一手好菜的男神老公的大作,曾发表于技术公号,经本人授权转载~~ 一.Java ...
- Ajax&jQuery教案总结
Ajax&jQuery教程总结 目录 第一章 Ajax入门 6 第1讲 传统表单提交存在的问题 6 课程内容 6 1. 问题的引入 6 2. 问题的解决 6 参考进度(0.5课时) 7 第2讲 ...