wintersnowaAa
ext4 file system - Block Group (Super Block, GDT , Block & I-node Bitmap, I-node Table) 본문
ext4 file system - Block Group (Super Block, GDT , Block & I-node Bitmap, I-node Table)
wintersnowaAa 2025. 6. 7. 17:09한동안 공부를 안했다.
어떻게든 다시 열심히해야하지....
몇가지 ext2, ext3, ext4 에서 사용하는 구조들을 알아보자.
※ 이후에 포스팅 해야할거 Journal이랑 Data 블록!
1. Block Group (Super block)

파티션 아래에는 파일 시스템이 1개 할당되는데, 여기서는 ext 파일시스템을 할당했다고 가정하자.
그리고 시작은 Boot Sector 이고, 이후에는 여러 개의 Block Group들이 존재한다.
여기서 알아볼 구조는 Block Group 이다.
microsoft store을 통해 설치했던 ubuntu 폴더를 보면 vhdx 파일이 있다.
이걸 FTK Imager로 분석해보려고한다.
(조금 다를 수도 있지만 구조 이해하는데에는 충분할듯...?)
Block Group의 구조 내에는 여러개의 Block 들이 존재한다.

파일시스템의 시작 (파티션의 시작) 부분을 보면 앞부분은 00으로 채워져있다.
gpt한테 물어보니까 대부분 ext4 파일시스템은 1024byte 이후부터 super block이 존재한다고한다.
1024 = 0x400인데,

실제로 0x400부터 유의미한 데이터 값들이 보인다. 이게 아마 superblock으로 보이는데

FTK Imager가 명시해준 superblock 파일부분은 파일시스템의 0x400부터가 아니라 처음부터 0x400을 넘기고 큰 크기의 영역을 표기해준다. 이게 맞는건진 모르겠지만 일단 superblock의 범위가 어디건 유의미한 내용은 0x400부터 나온다는 것을 알았다.
Super Block = VBR과 비슷한 기능을 가진 영역으로 모든 Block Group의 첫번째에 사본들이 존재한다.
(NTFS와 FAT에는 VBR 사본이 1개로 총 2개의 VBR이 존재했지만, Super Block은 각 Block Group에 존재해서 엄청나게 많다.)
여기에는 VBR과 비슷하게 Block의 크기 단위, inode 개수, Block 개수, 볼륨 라벨명등의 정보가 있다.
struct ext2_super_block {
__le32 s_inodes_count; // 전체 inode 수
__le32 s_blocks_count_lo; // 전체 블록 수 (low 32비트)
__le32 s_r_blocks_count_lo; // 예약된 블록 수
__le32 s_free_blocks_count_lo; // 사용 가능한 블록 수
__le32 s_free_inodes_count; // 사용 가능한 inode 수
__le32 s_first_data_block; // 첫 번째 데이터 블록 번호
__le32 s_log_block_size; // 블록 크기 = 1024 << s_log_block_size
__le32 s_log_cluster_size; // 클러스터 크기
__le32 s_blocks_per_group; // 블록 그룹당 블록 수
__le32 s_clusters_per_group; // 클러스터당 그룹 수
__le32 s_inodes_per_group; // 블록 그룹당 inode 수
__le32 s_mtime; // 마지막 마운트 시간
__le32 s_wtime; // 마지막 쓰기 시간
__le16 s_mnt_count; // 마운트 횟수
__le16 s_max_mnt_count; // 최대 마운트 횟수
__le16 s_magic; // 파일 시스템 식별자 (0xEF53)
__le16 s_state; // 파일 시스템 상태 (clean 등)
__le16 s_errors; // 오류 발생 시 동작
__le16 s_minor_rev_level; // 마이너 버전
__le32 s_lastcheck; // 마지막 fsck 수행 시간
__le32 s_checkinterval; // 자동 검사 간격 (초)
__le32 s_creator_os; // 파일 시스템 생성 OS
__le32 s_rev_level; // 파일 시스템 레벨 (0 = 초기, 1 = 동적)
__le16 s_def_resuid; // 예약 블록의 사용자 ID
__le16 s_def_resgid; // 예약 블록의 그룹 ID
// 확장된 기능들
__le32 s_first_ino; // 첫 번째 비-예약 inode
__le16 s_inode_size; // inode 크기 (바이트)
__le16 s_block_group_nr; // 슈퍼블록이 속한 블록 그룹
__le32 s_feature_compat; // 호환 가능한 기능 비트 플래그
__le32 s_feature_incompat; // 호환 불가능한 기능 플래그
__le32 s_feature_ro_compat; // 읽기 전용 호환 기능
__u8 s_uuid[16]; // 파일 시스템 UUID
char s_volume_name[16]; // 볼륨 이름
char s_last_mounted[64]; // 마지막 마운트된 경로
__le32 s_algorithm_usage_bitmap; // 압축 알고리즘 비트맵 (사용되지 않음)
// Journaling 관련
__u8 s_journal_uuid[16]; // 저널 UUID
__le32 s_journal_inum; // 저널 inode 번호
__le32 s_journal_dev; // 저널 디바이스
__le32 s_last_orphan; // 마지막 orphan inode
// 수많은 확장 필드가 계속 이어짐...
};
이건 ext2 기준 super_block 구조체이다.

어느정도 ext4의 superblock 구조체와 일치하는 오프셋을 가진다.
그리고 현우의 말대로라면 ext4는 모두 리틀엔디안으로 보면 된다고한다.
더 상세한 내용은 ext4_fs.h 를 참고해서 보면 된다고한다.
(구글링 고고)
위의 내용을 기준으로 분석해보면
필드 이름 | 설명 | 실제 디스크 값 (일부는 리틀엔디안 -> 빅엔디안으로 변환한 값) |
Total I-node Count | 전체 inode 수 | 0x4000000 |
Total Block Count | 전체 블록 수 | 0x10000000 |
Free Block Count | Free Block 수 | 0xFB40983 |
Free I-node Count | Free I-node 수 | 0x3FF87DA |
Block size | 블록의 크기 | 0x2 (값이 2라면 블록 사이즈는 4096바이트) |
Block Per Group | 1개의 그룹이 갖는 블록 수 | 0x8000 |
I-node Per Group | 1개의 그룹이 갖는 I-node 수 | 0x2000 |
Mount Time | 마운트된 시간 | 0x684287ED |
Write Time | 수정된 시간 | 0x68428AA0 |
Magic Signature | ext 파일시스템에 대한 시그니처값 | 0xEF53 (통상적으로 0xEF53이 온다) |
Operating System | OS 종류 | 0x0 (0이면 Linux, 1이면 Hurd, 2이면 Masix, 3이면 FreeBSD, 4이면 Lites이다.) |
First non-reserved I-node | 사용되는 첫번째 i-node | 0xB |
I-node Entry Size | i-node Entry의 크기 (바이트 단위) | 0x100 |
Volume UUID | Universally Unique Identifier | 0x541E1C88FAA0E6BD99421C986FE01D66 |
Volume Label | Volume Label | 0x0 (아마 가상머신이라서 0x0 값을 가지는듯하다.) |
Last Mounted Directory | 파일시스템이 마지막으로 마운트한 디렉토리 | 0x006F72747369642F (/distro라는 문자열) |
hash Type | 디렉토리 해시값 알고리즘 | 0x1 (0이면 legacy, 1이면 Half MD4, 2이면 Tea등...) |
GDT Size | GDT의 크기 (바이트 단위) | 0x40 |
아래는 실제 리눅스에서 파티션의 파일시스템에 대한 정보이다.

외에도 많은데 정확한 구조체 내부의 변수명과 설명을 보려면
https://archive.kernel.org/oldwiki/ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout.html#Blocks
Ext4 Disk Layout - Ext4
From Ext4 OBSOLETE CONTENT This wiki has been archived and the content is no longer updated. For latest ext4 documentation, see Kernel Docs. This document attempts to describe the on-disk format for ext4 filesystems. The same general ideas should apply to
archive.kernel.org
여기를 보면 편하다. (대신 영어 울렁증 있는 나는 힘들었따.)
2. GDT (Group Descript Table), Block & I-node Bitmap
Group Descript Table = 그룹 설명 테이블이라고 직역됨.
여러개의 Block Group들에 대한 정보가 저장되어있다.
NTFS의 MFT Entry와 비슷하게 GDT Entry들로 이루어져있다.
GDT = n * GDT Entry
GDT의 크기는 앞의 Super Block에서 나왔듯이 내 노트북에서는 0x40으로 64바이트의 크기를 갖는다.
여기서 GDT 영역이 어디인지를 알아야한다.

Block Group은 여러개의 블록으로 이루어져있다.
super block도 1개의 블록이고,
GDT (Block Group Descriptor) 또한 1개의 블록이 여러개로 이루어져있다.
1개의 블록은 섹터와 비슷하게 사용된다.
그러므로 4096바이트가 1개의 블록 단위이므로 super block 이 0번째 블록
GDT는 1번째 블록으로 볼 수 있다.
그러므로 0x1000 (4096) 오프셋부터 GDT 영역이 나타난다.

바로 이 부분이다.
앞의 super block에서 GDT Size가 0x40 값을 가지는 것을 통해서 GDT Entry가 0x40바이트의 크기를 가지므로
위의 사진과 같이
0x1000 ~ 0x103F까지가 0번째 Group Block을 설명하고
0x1040 ~ 0x107F까지가 1번째 Group Block을 설명하는 형태를 갖는다.
그리고 실제로 GDT 영역은 1개의 block을 사용하지 않고 여러개의 block을 사용한다.
0x40만큼의 GDT Entry 형태를 가진 구조가 0x1000 이후로도 0x2000 이후로도 계속 많이 보이게된다.
GDT 또한 앞에 언급한
https://archive.kernel.org/oldwiki/ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout.html#Blocks
Ext4 Disk Layout - Ext4
From Ext4 OBSOLETE CONTENT This wiki has been archived and the content is no longer updated. For latest ext4 documentation, see Kernel Docs. This document attempts to describe the on-disk format for ext4 filesystems. The same general ideas should apply to
archive.kernel.org
여기서 구조를 파악할 수 있다.

DF_M@aster님이 글에 녹여내신 구조만 분석해보자.
(이건 0x40 중 절반인 0x20만큼의 앞부분 구조만 설명해놓은거다. 사실은 뒤에 0x20만큼 더 영역이 있고 그만큼 정보가 더 있다.)
필드 이름 | 설명 | 실제 디스크 값 (일부는 리틀엔디안 -> 빅엔디안으로 변환한 값) |
Block Bitmap | Data Block 할당 비트맵 (해당 값 번째의 블록으로 찾아가면 된다.) |
0x481 (0x481번째 블록을 찾아가자) |
I-node Bitmap | I-node Number 할당 비트맵 (마찬가지로 해당 값 번째 블록) |
0x1481 (0x1481번째 블록을 찾아가자) |
I-node Table | I-node Entry의 집합 | 0x2481 (0x2481번째 블록을 찾아가자) |
Free Block Count | Free Block 개수 | 0x1 |
Free I-node Count | Free I-node 개수 | 0x0 |
Directory Count | 디렉토리 개수 | 0x3DE |
Block Group Flag | 블록 그룹 플래그 값 | 0x4 |
Block Bitmap Checksum | 블록 비트맵 체크섬 | 0xFEEB |
I-node Bitmap Checksum | I-node 비트맵 체크섬 | 0x1D75 |
Unused I-node Count | 미사용 I-node 개수 | 0x0 |
Group Descriptor Checksum | Group Descriptor 체크섬 | 0x9F6D |
Bitmap들의 구조는 단순하다 각 비트들의 n번째를 계산하고 그 n번째 블록이 사용 중이라고 생각하면 된다.
당장 내 이미지 파일의 Block Bitmap을 기준으로 예시를 들어보겠다.

Block Bitmap 부분이 0x481이다.
이 말은 0x481번째 블록으로 찾아가면 Data Block 할당 여부를 알 수 있다.

FF로 가득찼다. 상당한 블록의 개수를 사용한다는 뜻이다.
FFFFFFFFFFF..... = 1111 1111 1111 1111 1111 .... 이니까
0번째부터 엄청나게 많은 번째까지 블록이 사용되고 있다는 뜻이다.
여기서 중요하긴한데 검증하거나 다른 멘토분께 물어봐야할건
0번째도 사용되고 있다고 표기되는데 이 0번째가 Super Block을 말하는건지 아니면

Data Block 영역의 시작 블록이 0번째 블록을 뜻하는건지를 물어봐야한다.
이 구조를 통해서 아래의 Block Bitmap과 Inode Bitmap까지 찾아가서 hex 값으로 확인 할 수 있다.
(DF_M@aster님은 Data Block을 기준으로 순서를 세는게 아니라 Block Group 을 기준으로 세는 것이라고 알고 있다고 하셨다.)
!! 이거 나중에 물어봐서 해결하자...리눅스에서 직접 블록 지우려고해도 파티션이 하나인 리눅스에서 보호 기능 때문에 블럭 해제가 안된다. 그리고 파티션도 나누는게 안된다 이미 구동하고 있는 파티션을 쪼개는게 안된다...아니 정확하게는 쪼갰는데 왜 lsblk로 봐도 그대로인게 이해가 안됨. gpt 열받네
3. I-node Table
이제 남은건 I-node Table과 Journal, Data Block이다.
I-node Table을 확인해보자.
I-node Table은 이전의 GDT처럼
I-node Talbe = n * I-node Entry 의 구조를 갖고 있다.

super block에서 I-node Entry의 크기는 0x100 이라고 나왔다.

마찬가지로 DF_M@aster 님이 블로그에 올리신 I-node Entry 구조를 보면 0x100만큼의 크기를 가진다.
실제 내 디스크에서는 I-node Table부분이 어느 오프셋에 있는지 궁금해졌다.

위에서 GDT Entry 정보를 통해서 오프셋을 알 수 있었다.

이부분이다. 그리고 0x100 단위로 I-node Entry 구조가 나름 깔끔하게 떨어지는 것으로 보인다.
I-node Table의 I-node Entry는 일종의 Windows OS 파일시스템에서 사용하는 메타데이터와 비슷한 역할을 하는듯하다.
정리해보면
필드 이름 | 설명 | 실제 디스크 값 (일부는 리틀엔디안 -> 빅엔디안으로 변환한 값) |
I-node Mode | I-node의 타입 (파일 타입과 접근권한) | 0x0 자세한건 https://kkikyul.tistory.com/41 참조 |
UID Lower | Owner ID의 하위 16bit | 0x0 |
Data Size Lower | 파일의 크기 (byte로 나타냄) | 0x0 |
Last Access Time | 파일의 마지막 접근 시간 | 0xCEA38366 |
Last I-node Change Time | I-node 마지막 변경 시간 | 0xCEA38366 |
Last Data Modification Time | 파일 내용 마지막 수정 시간 | 0xCEA38366 |
Deletion Time | 파일이 삭제된 시간 | 0x0 |
GID Lower | Group ID의 하위 16bit | 0x0 |
Hard Link Count | 하드 링크의 수 | 0x0 |
i_blocks_lo | 파일의 블록 개수 | 0x0 |
Flags | 파일에 대한 플래그 값 | 0x0 |
I-node OS version | 특정 OS에 대한 I-node version | 0x0 |
Extent | 뒤에 설명할 예정 | |
File Version | NFS를 위한 파일 버전 | 0x0 |
i_file_acl_lo | 파일 확장 속성 | 0x0 |
Data Size Upper | 파일 크기의 상위 32bit | 0x0 (ext2/3에서는 다른 값으로 쓰였다. ext4로 넘어오면서 이 영역은 사용이 바뀌었다) |
fragment address | 단편화 주소 | 0x0 (NTFS의 클러스터런 구조처럼 단편화된 데이터 영역을 나타내는 값으로 보인다.) !! 공홈에도 포스팅에도 자세한 정보가 없으니까 물어보자. |
Union osd2 | 특정 OS에 대한 정보 | 0x00 00 00 00 00 00 00 A9 2B 00 00 자세한건 https://archive.kernel.org/oldwiki/ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout.html#Inode_Table 참고 |
i-node field size | 확장 i-node의 필드 크기 | 0x0 !! 이것도 자세한 정보가 없다 물어보자. |
i-node checksum | i-node의 상위 16bit 체크섬 | 0x0 |
Extra Change Time | 더 자세한 변경 시간 (초단위) | 0x0 |
Extra Modification Time | 더 자세한 수정 시간 (초단위) | 0x0 |
Extra Access Time | 더 자세한 접근 시간 (초단위) | 0x0 |
File Creation Time | 파일의 생성 시간 | 0x0 |
Extra File Creation Time | 더 자세한 생성 시간 (초단위) | 0x0 |
version number | 버전 번호의 상위 32 bit | 0x0 |
Project ID | 프로젝트 ID | 0x0 |
아무래도 실질적으로 어떤 용도로 어떤 값을 사용하는지는 다양한 파일들에 적용해서 구조 분석을 많이하다보면 알게 될듯하다.(지금 실제 값들은 크게 의미가 보이지 않는다. 추리가 안됨....)
Free Inode와 Unused Inode는 다른거다.
Ext2/Ext3/Ext4 파일 시스템(Linux) 형식 및 차이점 알아보기
Ext2, Ext3 및 Ext4는 Linux용 파일 시스템입니까? 이 문서에서는 이러한 파일 시스템 형식의 차이점과 Linux 및 기타 운영 체제에 가장 적합한 파일 시스템에 대해 설명합니다. 지금 Windows에서 Linus 또
www.easeus.co.kr
https://ddongwon.tistory.com/66
ext4 파일 시스템_1 (기본 구조)
0. ext 파일 시스템 각각의 운영체제들을 저마다 파일들을 관리하는 파일 시스템을 채택하고 있다. 대표적으로 윈도우는 NTFS를, 맥 os는 APFS를 사용한다. 리눅스의 경우 ext 파일시스템을 사용한다.
ddongwon.tistory.com
[Digital Forensic] Android Ext4 File System Structure Analysis
Ext4Ext4(Extended File System): 리눅스 기반 시스템에서 널리 사용되는 파일 시스템으로, 주로 안드로이드의 파일 시스템으로 사용된다. 안드로이드는 리눅스 커널을 기반으로 하기 때문에,
digitalforensicmaster.tistory.com
https://archive.kernel.org/oldwiki/ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout.html#Blocks
Ext4 Disk Layout - Ext4
From Ext4 OBSOLETE CONTENT This wiki has been archived and the content is no longer updated. For latest ext4 documentation, see Kernel Docs. This document attempts to describe the on-disk format for ext4 filesystems. The same general ideas should apply to
archive.kernel.org
Ext4 File System
*공부를 위해 정리한 내용으로 틀린 부분이 있을 수 있습니다. *미리 쓰는 느낀점: NTFS, FAT만 보고 가볍게 덤볐다간 큰 코 다칠 수 있습니다. 너무 어렵다;;I. GPT (MBR) 디스크의 기본 구조인 GPT(MBR)
roklcw.tistory.com
https://kkikyul.tistory.com/40
[파일시스템] EXT2 파일시스템 (1/2)
내용 1. Ext2 1) 리눅스와 Ext2파일 시스템의 발전 - 리눅스가 처음 만들어 질 때 사용된 파일시스템인 Minix 파일시스템을 먼저 살펴 보면, 앤드류 타넨비움 교수가 교육용 유닉스 클론으로 만든 오
kkikyul.tistory.com
'포렌식 통합' 카테고리의 다른 글
이벤트 로그 (참고) [지속수정] (3) | 2024.11.16 |
---|---|
참고문헌 및 파일 (지속 수정) (1) | 2024.10.23 |