以芯片直读方式得到的全盘镜像解析及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. 公共接口 四.提供者 ...
随机推荐
- 使用redis做mybaties的二级缓存(2)-Mybatis 二级缓存小心使用
Mybatis默认对二级缓存是关闭的,一级缓存默认开启: 下面就说说为什么使用二级缓存需要注意: 二级缓存是建立在同一个namespace下的,如果对表的操作查询可能有多个namespace,那么得到 ...
- R实现地理位置与经纬度相互转换
本实例要实现目标通过输入城市名或者地名,然后找出其经度纬度值,以及通过可视化展现其线路流向以及周边地图展示 address_list数据: 山西省太原市小店区亲贤北街77号 贵州省贵阳市云岩区书香门第 ...
- Android Weekly Notes Issue #258
Android Weekly Issue #258 May 21st, 2017 Android Weekly Issue #258 本期内容: 围绕着Google I/O的热潮, 本周的posts除 ...
- Git 使用记录
在win7平台已经安装好了git的情况下: 1,Git 本地仓库建立与使用步骤: (2)新建立文件夹: $ mkdir learngit $ cd learngit $ pwd /Users/mich ...
- springboot 中使用websocket简单例子
gradle 中添加依赖,引入websocket支持 compile("org.springframework.boot:spring-boot-starter-websocket:${sp ...
- 中文分词中的战斗机-jieba库
英文分词的第三方库NLTK不错,中文分词工具也有很多(盘古分词.Yaha分词.Jieba分词等).但是从加载自定义字典.多线程.自动匹配新词等方面来看. 大jieba确实是中文分词中的战斗机. 请随意 ...
- 我做的第一个程序(菜鸟的java课堂笔记)
内存: 堆区,栈区,常量区,计数区,代码区: 数据类型: 基本数据类型:整形,浮点型,布尔型 boolean 只能返回真假值,字符型: 引用数据类型:类,数组: 基本数据类型-->直接存放到栈区 ...
- 浅谈Fastfds+nginx结合_单机
一.环境 centos6.8 x64 IP:192.168.134.128 所需软件包: libfastcommon-1.0.7.zip,FastDFS_v5.05.tar.gz,nginx-1.7 ...
- python基础操作_元组_字典操作
#元组'''元组是不可变的列表,不能改.取值和列表一样'''tp=(1,2,3)tp1=('127.0.0.1','3307')#元组只有count 和index两个方法.lis=['127.0.0. ...
- Hadoop hdfs完全分布式搭建教程
1.安装环境 ①.四台Linux CentOS6.7 系统 hostname ipaddress subnet mask ...