wintersnowaAa
ext4 file system - Block Group (Journal) 본문
bob 떨어져도 해야할건 해야지...
포렌식 공부는 그래도 재밌으니까
1. Journal
Journal 영역의 오프셋을 찾아야한다.
알아본 바로는 Journal 영역은 Inode Table의 Inode Entry 8번째를 사용한다고 한다.
https://wintersnowaaa.tistory.com/64
ext4 file system - Block Group (Super Block, GDT , Block & I-node Bitmap, I-node Table)
한동안 공부를 안했다.어떻게든 다시 열심히해야하지....몇가지 ext2, ext3, ext4 에서 사용하는 구조들을 알아보자.※ 이후에 포스팅 해야할거 Journal이랑 Data 블록!1. Block Group (Super block)더보기파티
wintersnowaaa.tistory.com
지난 포스팅에서 알아본 바로는 I-node Table의 오프셋은

0x2481000 이였다. 그리고 슈퍼블록에서 1개의 I-node는 0x100이라고 했으니까
0x2481700 혹은 0x2481800 에 위치할 것이다. (0번째~8번째로 세는지, 1번째~8번째로 세는지 차이)
근데 0x2481800~0x24818FF 영역은 0으로 채워져있어서 0x2481700~0x24817FF 가 Journal 에 대한 I-node Entry 영역인듯하다.

이 영역을 분석해보자.
일단 이게 Journal 영역에 대한 Inode Entry가 맞는지 확인해보자.


사진을 확인해보면 FTK Imager에서 말한 Journal 파일 생성시각과 8번째 Inode Entry의 파일 생성 시각이 일치하는 것을 볼 수 있었다. 일단 Journal 영역에 대한 Inode Entry인 것은 맞는 것 같다.
Inode Entry를 통해 해당 파일의 오프셋을 찾아가는 계산법은
Inode Entry의 Extent 영역의 내용을 활용해야한다. (아...Journal 영역부터 포스팅하려고 했는데, Extent를 먼저했어야했네 일단 보류하고 Extent부터 공부하고 이 포스팅으로 다시 돌아와야겠다.)
https://wintersnowaaa.tistory.com/65
ext4 file system - Block Group (I-node Entry Extent 영역)
ext4 첫번째 포스팅에서 I-node table에서 Extent 영역 설명에 이 포스팅 링크 걸어놓기!Extent Tree 구조 (논리적 구조) 와 Extent 영역(index node까지)더보기일단 Extent tree 구조는 ext4부터 사용되었다.이유는
wintersnowaaa.tistory.com
완료.
자 여태까지 Extent 영역에 대해 공부하고 와서 이제는 좀 다르다.
결국 journal 영역까지 I-node Table을 통해서 찾아갔고, 이제부터 정말 journal 영역을 분석해볼 차례이다.

일단 journal 영역이라고 추정되는 곳이 맞는지 FTK Imager에서 분류해준 journal 파일을 통해서 비교해보자.

음 일치한다! 잘 찾아간듯하다. 이전까지의 포스팅들이 어느정도 틀리지않고 알맞게 이해했다는 것이겠지...
이번에도 참고해서 구조 분석을 해보자
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의 저널링 시스템은 3개의 옵션을 가진다
1. data = ordered (기본값으로 메타데이터만 저널링, 데이터는 디스크에 씀)
2. data -= journal (데이터와 메타데이터 둘 다 저널링, 가장 안전하지만 느리다)
3. data = writeback (메타데이터만 저널링, 하지만 저널링이 우선되고 그 다음에 데이터를 디스크에 씀)
뭐 이건 크게 중요하진 않을듯하지만 알아두면 좋을 것이니까 적었다.
결국 Journal 영역의 구조는
다음과 같다.

Transaction 은 Journal Log라고도 부른다. 하나의 트랜잭션마다 1개의 Journal Log가 발생한다.
조금 보기 편한 구조를 보면,

요렇게 생겼다.
그러면 순서는 이렇게 될듯하다.
Journal Superblock -> Descriptor Block -> Metatdata Backup Block -> Commit Block or Revoke Block 순으로 나타날 것이다.
조금 길어질듯하니 나눠서 아래에 작성하도록하자.
2. Journal(journal super block)

journal super block은 1024 바이트의 크기를 갖는다.
이는 곧 0x400의 크기이다.
근데 사진의 내용이 끝이다.
0x180 이후로도 0으로 채워져있어서 사진 내용만 봐도 상관없다.
※ 정말 중요한 점! journal 영역인 jdb2은 빅엔디안을 사용한다! 진짜진짜진짜 중요함
가장 먼저 Journal 에서 블록들은 공통적으로 시작할 때 Block header 를 갖는다.

필드 이름 | 설명 | 실제 디스크 값 (빅엔디안) |
h_magic | jbd2의 매직 넘버(시그니처) | 0xC03B3998 |
h_blocktype | 블록의 타입 | 0x4 (이는 Journal Superblock v2 이다) 자세한 값들에 대한 설명은 https://archive.kernel.org/oldwiki/ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout.html#Block_Header |
h_sequence | 블록이 속한 트랜잭션 고유 번호 | 0x0 각 트랜잭션 세트(Journal Log의 구성인 각 블록들을 하나의 고유 번호로 묶은 것) 번호 0 -> 1 -> 2 이렇게 순서가 흘러가는게 아니라 트랜잭션 고유 번호이므로 랜덤하게 Journal Log 단위로 배정된다. |
매직넘버랑 트랜잭션 고유 번호는 이해가 되지만 블록의 타입인 0x4를 통해 Journal Superblock v2가 뭔지 모르겠다.
Journal Superblock v2는 저널 슈퍼블록의 일종의 종류이고,
이에 대한 정보는 Block Header 이후에 나타난다.

Journal super block 의 영역이다. (block header 이후)

같이 매치해서 한번 정리해보겠다.
필드 이름 | 설명 | 실제 디스크 값 (빅엔디안) |
s_blocksize | 저널 영역의 블록 크기 | 0x1000 |
s_maxlen | 저널 영역의 전체 블록 수 | 0x40000 |
s_first | 첫 트랜잭션 블록 번호 | 0x1 |
s_sequence | 다음에 커밋될 트랜잭션 ID | 0x21FE |
s_start | 현재 진행 중인 로그의 시작 블록 | 0x0 |
s_errno | 오류 코드 (문제 발생 시 기록) | 0x0 |
s_feature_compat | ext2,3과 호환 가능한 범위 표시 | 0x0 만약이 값이 0x1이라면 저널이 데이터 블록의 체크섬을 관리하는 설정이 켜져있는 것이다. |
s_feature_incompat | ext2,3과 호환 불가능한 범위 표시 | 0x13 https://archive.kernel.org/oldwiki/ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout.html#Super_Block 확인해보면, 0x10+0x2+0x1 이므로 REVOKE, 64BIT(대용량 디스크 지원), 고급 체크섬 v3 은 구 버전 커널에서 지원이 안된다. |
s_feature_ro_compat | 읽기 전용 호환 기능 범위 표시 | 0x0 (하지만 사실상 현재 ext4에서 읽기 전용 기능으로 표시할건 추가되지 않았다고 한다.) |
s_uuid[16] | 저널 UUID (파일시스템의 UUID와 일치) | 0x661DE06F981C4299BDE6A0FA881C1E54 |
s_nr_users | 저널을 공유하는 파일시스템 갯수 | 0x1 (ext4 단독으로 저널을 사용) |
s_dynsuper | 동적 슈퍼블록 위치 (실제로 동적 슈퍼블록은 여러 개의 Group Block에 존재하지만, 마지막으로 유효성이 검증된 동적 슈퍼블록을 가리키게끔 설정된다.) | 0x0 (동적 슈퍼블록을 사용하지 않는 것으로 보임) |
s_max_transaction | 트랜잭션당 최대 블록 수 (ext4에서는 미사용) | 0x0 |
s_max_trans_data | 트랜잭션당 최대 데이터 블록 수 (ext4에서는 미사용) | 0x0 |
s_checksum_type | 체크섬 알고리즘 | 0x4 (CRC32C 이다.) 다른 값들은 https://archive.kernel.org/oldwiki/ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout.html#Super_Block 에서 확인 가능 |
s_padding2 | 정렬용 패딩 (예약된 영역으로 추후에 사용 가능) | 0x0 |
s_padding[42] | 정렬용 더미 데이터 (쓰지 않는 영역) | 0x0 으로 대부분 채워져있지만, 중간에 0이 아닌 값 존재함. 실제 사용이 되진 않아보임 |
s_checksum | 전체 슈퍼블록의 체크섬 (자기 자신은 0으로 두고 계산) | 0x7D9A0A3E |
s_users[16*48] | 공유 저널 사용자의 UUID 목록 | 0x0 (공유 저널 사용자가 없는 것으로 보임.) |
맞게 구조를 나누고 분석했는지 확인하기 위해서는 저널 UUID인 0x661DE06F981C4299BDE6A0FA881C1E54 값이
파일시스템의 UUID 와 일치하는지를 보면 된다.

해당 microsoft store에서 설치한 ubuntu 에서 blkid 명령어를 통해서 리눅스에서 연결된 장치들의 파일시스템 종류와 UUID 를 보면 일치하는 것을 알 수 있다.
3. Journal(Journal Log - Revocation(Revoke) Block)

이제부턴 journal log 영역을 분석해보자.

journal log는 Descriptor, Metadata Backup Block, Commit or Revoke Block 으로 구성되어있다.
앞의 journal super block에서 s_first 값이 0x1 이므로 오프셋의 시작은 journal 영역 자체의 시작점을 오프셋으로 둔다.
journal super block에서 저널 영역의 블록 크기는 0x1000이므로
0번 = journal superblock
1번 = 첫번째 journal log 일 것이다.

journal 영역의 첫번째 오프셋이자 journal super block 의 오프셋은 0x7ff8000000 이므로
다음인 1번째 블록(journal log)는 0x7ff8001000 일 것이다.

0xC03B3998 로 journal의 헤더에서 가장 먼저 나오는 매직넘버(시그니처) 값이 존재하는 것으로 보아 맞게 찾아갔다.
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
읽어보면 체크섬 v3 옵션을 셋팅해놓았다면, 다른 구조를 가진 것을 확인 할 수 있다.
이전의 journal super block 영역에서 s_feature_incompat 값이 0x13으로 체크섬 v3을 사용하므로 이에 맞는 구조를 대입해서 영역을 나눠서 설명해보겠다.
처음은 header 영역이다.
h_magic | jbd2의 매직 넘버(시그니처) | 0xC03B3998 |
h_blocktype | 블록의 타입 | 0x5 (revocation block 영역이다...? 어...) |
h_sequence | 블록이 속한 트랜잭션 고유 번호 | 0x210A 각 트랜잭션 세트(Journal Log의 구성인 각 블록들을 하나의 고유 번호로 묶은 것) 번호 |
그리고 Descriptor Block 영역이...라고 생각했는데 아니였다!
h_blocktype 이 0x5라서 journal super block 다음에는 revocation block 이라는 블록이 들어와있었다...
https://archive.kernel.org/oldwiki/ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout.html#Revocation_Block
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 kernel 에서 확인해서 구조를 분석해봤다.
남들은 알지 못했던 내용을 공부하면 좋은거..겠지?
일단 중요한건 Revocation Block이 무엇을 하는 블록이냐는 것이다.
짧게 정리하면 Journal 영역에서 트랜잭션이 굉장히 많아지는데, 현재는 사용 중이여서 과거의 상태로 트랜잭션을 사용해 복구하면 안되는 블록을 명시하는 기능을 한다.
쉽게 말하자면 현재 데이터 블록으로 쓰고 있는 블록 영역이 과거에 메타데이터 블록으로 사용되어서 트랜잭션을 통해 복구하면 데이터 영역이 메타데이터로 덮어씌어져서 망가지는 상황을 방지하기 위해서 존재하는 것이다.
자 그럼 이제....

Revocation Block 구조이다.
빨간색은 journal header 영역이고, 파란색이 Revocation Block 구조이다.
필드 이름 | 설명 | 실제 디스크 값 (빅엔디안) |
r_count | 실제 사용된 바이트 수 | 0x20 (사진에도 보이지만 revocation block 영역은 0x20만큼 사용되었다.) |
blocks[0] | 저널 복원 시 무시되어야할 블록들의 번호 목록 | 0xFFF0112 (실제로 0xFFF0112 번째 블록이 저널 복원 시 무시되어야한다. 만약 2번째 무시되어야할 블록이 존재한다면~ |
blocks[1] | 저널 복원 시 무시되어야할 블록들의 번호 목록 | 0xFFF00E4 (이런식으로 나타난다!) |
추가적으로 journal 에서 csum v3 을 사용하기 때문에 Revocation Block 마지막에 4바이트 크기의 체크섬이 존재한다.

필드 이름 | 설명 | 실제 디스크 값 (빅엔디안) |
r_checksum | journal uuid + revocation block 의 체크섬 | 0xDEC6FFD4 |
수정해보면

이렇게 존재했던 것이다.
(revoke block과 revocation block 같은 말이다.)
4. Journal(Journal Log - Descriptor Block)
journal super block -> Revoke Block -> Jounral Log(Descriptor Block) 으로 나타난다.
(0x7ff8000000) (0x7ff8001000) (0x7ff8002000)
Descriptor Block은 트랜잭션 중 변경된 데이터 블록의 메타 데이터를 기록하는 영역이다.
예를 들어서 ext4 에서 파일을 수정하면 해당 데이터 블록의 디스크 위치, 체크섬 변경 내용을 descriptor 가 저장한다.
(ext4 파일시스템은 파일의 메타시간정보 같은건 GDT에 저장하고, 저널을 통해서는 블록 오프셋과 체크섬을 기록하는듯하다.)

0xC03B3998 로 시작하는 것으로 보아 journal block header 가 분명하고 그 다음으로 0x1 값이 h_blocktype으로 잡혀있는 것으로 보아 Descriptor Block이 확실하다. 이제는 header 정도는 눈에 훤히 보인다.
진짜 머리가 아프다 계속 16진수만 보고 구조를 머릿속에 떠오르니까 두통이 진짜 생김... 그래도 확실하게 외워졌으니까 좋은거겠지...
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
일단 빨간색은 header이고 나머지 부분은 값이 너무 많아서 따로 표시는 안했다.
필드 이름 | 설명 | 실제 디스크 값 (빅엔디안) |
h_magic | jbd2의 매직 넘버(시그니처) | 0xC03B3998 |
h_blocktype | 블록의 타입 | 0x1 (Descriptor 영역이다) |
h_sequence | 블록이 속한 트랜잭션 고유 번호 | 0x210A 각 트랜잭션 세트(Journal Log의 구성인 각 블록들을 하나의 고유 번호로 묶은 것) 번호 |
어? 잠깐만 왜지? 같은 트랜잭션 번호를 가진 Revoke Block과 Descriptor Block 의 순서가
Descriptor -> Revoke 가 아니라 Revoke -> Descriptor 이다.
하...일단 넘어가고 구조 분석부터 해보자.
먼저 journal header 이후에 나오면 Descriptor 영역은 여러 개의 배열이 곧바로 붙는 구조를 띈다.
csum v3 설정이 된 경우에는 16바이트 혹은 32바이트이고,
csum v3이 설정되지 않은 경우에는 8바이트,12바이트, 24바이트, 28바이트 중 하나 이다.
난 csum v3 설정이 된 journal 이기 때문에 16바이트 혹은 32바이트인데
16바이트인 경우는 0x4 오프셋의 t_flags 값이 0x2로 이전 블록과 동일한 uuid 값이라고 표기되는 경우.
32바이트인 경우는 0x4 오프셋의 t_flags 값이 0x2가 아니여서 uuid를 표기해야할 때 추가적으로 16바이트를 더 사용한다.

하나만 예시를 들어서 먼저 확인해보면
필드 이름 | 설명 | 실제 디스크 값 (빅엔디안) |
t_blocknr | 데이터 블록의 오프셋 하위 32비트 | 0x0 |
t_flags | 해당 디스크립터 플래그 | 0x0 자세한 값들은 https://archive.kernel.org/oldwiki/ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout.html#Descriptor_Block |
t_blocknr_high | 데이터 블록의 오프셋 상위 32비트 | 0x0 (JBD2_FEATURE_INCOMPAT_64BIT 기능이 비활성화된 경우는 0으로 채워진다고한다. JBD2_FEATURE_INCOMPAT은 s_feature_incompat 값이 위의 journal super block 영역에 존재하는데 이에 대해 설명이 적혀있다.) 근데 활성화되어있는데도 0으로 채워져있다 이거 왜 이러는걸까..? |
t_checksum | journal uuid + data block에 대한 체크섬 | 0x0644F9EB |
이후의 16바이트는 모두 0으로 채워져있는데 이게 uuid 값인지 모르겠다...
그나마 구조 분석이 가능한 영역은

해당 부분부터 t_flags 값이 0x2로 반복해서 나타나므로 같은 uuid 에 대한 배열들임을 알 수 있다.
구조를 나타내볼 것인데, t_flags 값이 0x2라서 uuid 영역은 생략되므로 32바이트가 아닌 16바이트이다.
필드 이름 | 설명 | 실제 디스크 값 (빅엔디안) |
t_blocknr | 데이터 블록의 오프셋 하위 32비트 | 0x2BB7 |
t_flags | 해당 디스크립터 플래그 | 0x2 (이전 블록과 같은 uuid를 사용한다. uuid가 생략된다.) |
t_blocknr_high | 데이터 블록의 오프셋 상위 32비트 | 0x0 |
t_checksum | journal uuid + data block에 대한 체크섬 | 0xD208A6F2 |
해당 Descriptor tag (배열)이 가리키는 데이터 블록의 오프셋은 t_blocknr_high + t_blocknr 로 계산되어
0x00 00 00 00 과 0x00 00 2B B7 이 붙어 0x2BB7 번째 블록이 된다. (물리적 블록 번호)
그리고 Revoke Block 과 같이 Descriptor Block 도 마지막 4바이트에 해당 블록에 대한 journal uuid + Descriptor Block의 체크섬이 존재한다.

필드 이름 | 설명 | 실제 디스크 값 (빅엔디안) |
t_checksum | journal uuid + revocation block 의 체크섬 | 0xF903E640 |
5. Journal(Journal Log - Metadata Backup Block(Journal data block))
통상적으로 Descriptor Block 이후에는 바로 데이터 블록이 나오며 이에 대한 구조는 따로 없고 데이터만 있다고한다.
위의 journal super block에서 블록 1개의 크기는 0x1000이라고 했으니 0x7ff8003000부터 데이터 영역인데...

0x1000 = 4096 바이트를 다 둘러보다가
0x7ff8003400에서 무언가 데이터가 나온 것을 확인했다!

/distro 라는 문자열의 위치를 보자마자...

전 포스팅에서 봤던 super block 영역과 굉장히 유사한 것을 확인했다.
superblock 구조에 대입하여 비교해보니 Volume UUID 가 같다.
하지만 Free Block Count 가 다르고, Free I-node Count 값도 다르다

.데이터 블록에 존재하는 super block의 체크섬은 0xA308D1B4 이고,

이전에 다뤘던 super block의 체크섬은 0xB398F0B0 이다.
다르긴하다...
근데 결국에 이게 왜 나온걸까...?
와 해결했다... 아래에 설명하도록하겠다.
일단 Metadata Backup Block이라는 영역은 공식적으로 정해진 개념은 아닌듯하다...?
아마 사람들이 말하는 Metadata Backup Block은 메타데이터의 이전 상태를 기록하는 블록인 journal data block 이다.
일단 잘 정리해야할 것은 Descriptor Block 에서 나오는 태그가 가리키는 오프셋에 존재하는 블록은 실제로 데이터의 블록이고, Descriptor Block 이후에 나타나는 Journal Data Block은 해당 태그를 통해서 오프셋에 존재하는 데이터 블록의 메타데이터 + 실제 데이터 값이 존재한다고한다.
그리고 ordered 모드 일땐 메타데이터가 저널에 커밋되기 전에 모든 데이터가 디스크에 플러시된다고하는데...

내 디스크 이미지는 ordered 모드이므로 메타데이터만 저장한다고한다.
(근데 문제는 journal data block에 메타데이터만 쓰는 줄 알았는데, 그냥 데이터 블록 자체를 journal data block에 쓰고 있다. 무슨 말이냐면 ordered 모드로 되어있지만, 실제로 그렇지 않다는 것인듯하다...)
그리고 만약

빨간색이 journal header 영역
하늘색이 Descriptor Block의 journal_block_tag3_t [0] (uuid 값이 0으로 채워져있지만 존재한다. 그래서 32바이트)
분홍색이 Descriptor Block의 journal_block_tag3_t [1] (uuid 값이 마찬가지로 0으로 잡혀서 flag가 0x2로 설정되고 uuid 값이 생략되므로 16바이트)
그러므로 하늘색은 0번째 블록인 super block의 임시 복사본 데이터가 나온거다.
(실제 슈퍼블록과 차이가 있는 이유는 복사 전 혹은 복사 후의 내용의 차이 때문이다.)
분홍색을 통해서 내 가정이 맞다는 확신을 할 수 있을듯하다.
0x2BB7 번째 블록과 Descriptor Block -> Data Block[0] -> Data Block[1] 에서 Data Block[1]의 내용이 같거나 비슷하면 확실하다.

다음은 Data Block[1] 영역이다.

그리고 이건 0x2BB7 번째 파티션 전체 물리 블록이다.
빨갛게 블록친 부분 빼고는 눈으로 대충 보면 다 맞아떨어진다.
여기서 정말 쐐기를 박을 수 있는 방법이 있다.
Descriptor Block 영역에서 나온 journal_block_tag3_t 의 갯수들이 Commit Block이 나오기까지 오프셋 차이 / 0x1000 해서 같으면 확실해진다.
0x7ff800202C부터의 값이 2개째로 세어지니까 어디까지 비슷한 구조가 반복되는지 Descriptor Block 영역 0x1000 만큼 뒤져보면...

0x7ff800291C부터 마지막 journal_block_tag3_t 이다. 플래그 값도 0xA로 0x8 + 0x2 이므로 같은 uuid이며, 마지막 태그임을 나타낸다.
0x7ff800202C 부터 2번째
0x7ff8002910 이면 journal_block_tag3_t는 총 91개 이다.
여기서 journal header 시그니처 값인 0xC03B3998 로 검색하여 오프셋을 계산해주면서 헤더의 h_blocktype 값이 0x2인 곳을 찾아주면 된다.

0x7ff8002000이 Descriptor Block 영역
0x7ff8094000이 Commit Block 영역
0x7ff8003000이 1번째
0x7ff8093000이 91번째 journal_block_tag3_t가 가리키는 journal data block이다.
그러므로 그 다음이 되는
0x7ff8094000이 Commit Block이 들어온다.
이로서 정리해서 구조를 보여주자면...

이런 상태인 것이다!
6. Journal(Journal Log - Commit Block)
원래 처음에 크게 나눠서 Commit Block과 Revoke Block을 여기에 같이 정리하려했는데
앞에서 journal super block과 첫번째 journal log 사이에 Revoke Block이 나와버려서 먼저 정리했으므로,
Commit Block 만 여기서 정리하면 끝이다!
진짜 구조가 왜 이런지 모르겠다...
블록들이 연속되어 나타나지 않는건 뭐 어찌보면 당연한거라고 가늠이 되지만,
journal super block이 0x7ff8000000 에서 나왔고 0x1000 단위로 블록이 나뉘는데
Commit Block은 계속 안나오길래 시그니처 값을 검색해서 찾아봤는데
0x7ff8094000 으로 95번째 블록에서 나왔다... 진짜 뭘까...?
저널 영역에서 0번째 블록부터 세어나가면....
Journal Super Block (0번째 블록) -> Revoke Block (1번째 블록) -> Descriptor Block (2번째 블록) -> 3번째 블록부터 superblock 으로 보이는 구조와 비트맵들이 보였음 -> Commit Block (95번째 블록)
이렇게 등장했다는 것이다...
그리고 공부하다보니 보던거는 old kernel 이라고 적혀있고, 새로 만든 정보는
https://www.kernel.org/doc/html/latest/filesystems/ext4/globals.html#commit-block
3. Global Structures — The Linux Kernel documentation
3. Global Structures The filesystem is sharded into a number of block groups, each of which have static metadata at fixed locations. 3.1. Super Block The superblock records various information about the enclosing filesystem, such as block counts, inode cou
www.kernel.org
여기 있었다. 결국에 거의 똑같긴한데 이게 좀 더 보기 편한듯하다.
이것도 결국 위의 Descriptor Block의 tag들과 Journal Block 들의 연관성을 해결해서 답을 찾아냈다!
이제 정말 Commit Block 영역을 구조 분석만 하면 된다.
일단 Commit Block의 기능은 해당 트랜잭션은 완전히 기록되었고 유효하다는 표시를 해준다.
현재까지 트랜잭션 번호로 0x210A로 묶였는데, 이 트랜잭션 자체의 유효성을 검증해주는 것이다.

Commit Block의 영역은 다음과 같다. 빨간색 부분이 journal header, 파란색부분이 Commit Block 영역이다.
journal header 이다.
필드 이름 | 설명 | 실제 디스크 값 (빅엔디안) |
h_magic | jbd2의 매직 넘버(시그니처) | 0xC03B3998 |
h_blocktype | 블록의 타입 | 0x2 (Commit 영역이다) |
h_sequence | 블록이 속한 트랜잭션 고유 번호 | 0x210A 각 트랜잭션 세트(Journal Log의 구성인 각 블록들을 하나의 고유 번호로 묶은 것) 번호 |
commit block 영역이다.
필드 이름 | 설명 | 실제 디스크 값 (빅엔디안) |
h_chksum_type | 체크섬 종류 | 0x0 |
h_chksum_size | 체크섬에 사용된 바이트 수 | 0x0 |
h_padding[2] | 단순 패딩 영역 | 0x0 패딩이라서 0으로 채워진다. |
h_chksum[JBD2_CHECKSUM_BYTES] | 체크섬을 저장하는 32바이트 공간 | 0x36C58A70 (CSUM_V3이 활성화 되어서 uuid + commit block에 대한 체크섬이다.) |
h_commit_sec | commit block 생성 시점으로 트랜잭션의 생성 시각이다. | 0x684287EE (DCode로 변환해보면 2025년 06월 06일 6시 17분 18초이다.) |
h_commit_nsec | 더 자세한 나노 단위의 초이다. | 0x1A5B5D9B (단순하게 이를 10진수로 변환 후 소수점에 붙이면된다. 18초 이후에 붙는 값은 0.442195355 이므로 2025년 06월 06일 6시 17분 18.442195355 초이다.) |
Commit Block의 마지막 4바이트에는 체크섬이 없다.
애초에 구조 자체에 있기 때문인듯하다!
참고)
[Digital Forensic] Android Ext4 File System Structure Analysis
Ext4Ext4(Extended File System): 리눅스 기반 시스템에서 널리 사용되는 파일 시스템으로, 주로 안드로이드의 파일 시스템으로 사용된다. 안드로이드는 리눅스 커널을 기반으로 하기 때문에,
digitalforensicmaster.tistory.com
https://blogs.oracle.com/linux/post/ondisk-journal-data-structures-jbd2
On-disk Journal Data Structures (JBD2)
A technical guide on how the JBD2 on-disk journaling layer works.
orasites-prodapp.cec.ocp.oraclecloud.com
https://archive.kernel.org/oldwiki/ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout.html#Super_Block
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
https://www.kernel.org/doc/html/latest/filesystems/ext4/globals.html#commit-block
3. Global Structures — The Linux Kernel documentation
3. Global Structures The filesystem is sharded into a number of block groups, each of which have static metadata at fixed locations. 3.1. Super Block The superblock records various information about the enclosing filesystem, such as block counts, inode cou
www.kernel.org
'포렌식 통합' 카테고리의 다른 글
Portable Executable - PE Header (0) | 2025.07.01 |
---|---|
ext4 file system - Block Group (I-node Entry Extent 영역) (0) | 2025.06.21 |
ext4 file system - Block Group (Super Block, GDT , Block & I-node Bitmap, I-node Table) (1) | 2025.06.07 |
이벤트 로그 (참고) [지속수정] (0) | 2024.11.16 |
참고문헌 및 파일 (지속 수정) (0) | 2024.10.23 |