Skip to content

Commit

Permalink
basic structs
Browse files Browse the repository at this point in the history
  • Loading branch information
BijanRegmi committed May 1, 2023
0 parents commit d43cc0b
Show file tree
Hide file tree
Showing 9 changed files with 300 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "ext4_impl"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
dbg_hex = "0.1.1"
libc = "0.2.142"
8 changes: 8 additions & 0 deletions src/ext4_structs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
mod block_group_descriptor;
mod inode;
mod loadable;
mod superblock;
pub use self::block_group_descriptor::Ext4GroupDesc;
pub use self::inode::Ext4Inode;
pub use self::loadable::LoadAble;
pub use self::superblock::Ext4SuperBlock;
44 changes: 44 additions & 0 deletions src/ext4_structs/block_group_descriptor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use super::loadable::LoadAble;

#[allow(dead_code)]
#[derive(Debug)]
#[repr(C)]
pub struct Ext4GroupDesc {
/// Lower 32-bits of location of block bitmap.
pub bg_block_bitmap_lo: u32,

/// Lower 32-bits of location of inode bitmap.
pub bg_inode_bitmap_lo: u32,

/// Lower 32-bits of location of inode table.
pub bg_inode_table_lo: u32,

/// Lower 16-bits of free block count.
pub bg_free_blocks_count_lo: u16,

/// Lower 16-bits of free inode count.
pub bg_free_inodes_count_lo: u16,

/// Lower 16-bits of directory count.
pub bg_used_dirs_count_lo: u16,

pub bg_flags: u16,
pub bg_exclude_bitmap_lo: u32,
pub bg_block_bitmap_csum_lo: u16,
pub bg_inode_bitmap_csum_lo: u16,
pub bg_itable_unused_lo: u16,
pub bg_checksum: u16,
pub bg_block_bitmap_hi: u32,
pub bg_inode_bitmap_hi: u32,
pub bg_inode_table_hi: u32,
pub bg_free_blocks_count_hi: u16,
pub bg_free_inodes_count_hi: u16,
pub bg_used_dirs_count_hi: u16,
pub bg_itable_unused_hi: u16,
pub bg_exclude_bitmap_hi: u32,
pub bg_block_bitmap_csum_hi: u16,
pub bg_inode_bitmap_csum_hi: u16,
pub bg_reserved: u32,
}

impl LoadAble for Ext4GroupDesc {}
41 changes: 41 additions & 0 deletions src/ext4_structs/inode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use super::loadable::LoadAble;

#[allow(dead_code)]
#[derive(Debug)]
#[repr(C)]
pub struct Ext4Inode {
pub i_mode: u16,
pub i_uid: u16,
pub i_size_lo: u32,
pub i_atime: u32,
pub i_ctime: u32,
pub i_mtime: u32,
pub i_dtime: u32,
pub i_gid: u16,
pub i_links_count: u16,
pub i_blocks_lo: u32,
pub i_flags: u32,
pub l_i_version: u32,
pub i_block: [u16; 15 * 2],
pub i_generation: u32,
pub i_file_acl_lo: u32,
pub i_size_high: u32,
pub i_obso_faddr: u32,
pub l_i_blocks_high: u16,
pub l_i_file_acl_high: u16,
pub l_i_uid_high: u16,
pub l_i_gid_high: u16,
pub l_i_checksum_lo: u16,
pub l_i_reserved: u16,
pub i_extra_isize: u16,
pub i_checksum_hi: u16,
pub i_ctime_extra: u32,
pub i_mtime_extra: u32,
pub i_atime_extra: u32,
pub i_crtime: u32,
pub i_crtime_extra: u32,
pub i_version_hi: u32,
pub i_projid: u32,
}

impl LoadAble for Ext4Inode {}
26 changes: 26 additions & 0 deletions src/ext4_structs/loadable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use libc::memcpy;
use std::fs::File;
use std::io::{Read, Seek, SeekFrom};
use std::mem::size_of;
use std::os::raw::c_void;

pub trait LoadAble: Sized {
fn from_file_offset(file: &mut File, offset: u64) -> std::io::Result<Self> {
let mut bytes = vec![0u8; size_of::<Self>()];

file.seek(SeekFrom::Start(offset))?;
file.read_exact(&mut bytes[..])?;

let size = size_of::<Self>();
let mut result = unsafe { std::mem::MaybeUninit::<Self>::uninit().assume_init() };

unsafe {
memcpy(
&mut result as *mut Self as *mut c_void,
bytes.as_ptr() as *const c_void,
size,
);
}
Ok(result)
}
}
114 changes: 114 additions & 0 deletions src/ext4_structs/superblock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use super::loadable::LoadAble;

pub const SIZE: u32 = 0x400;

#[allow(dead_code)]
#[derive(Debug)]
#[repr(C)]
pub struct Ext4SuperBlock {
pub s_inodes_count: u32,
pub s_blocks_count_lo: u32,
pub s_r_blocks_count_lo: u32,
pub s_free_blocks_count_lo: u32,
pub s_free_inodes_count: u32,
pub s_first_data_block: u32,
pub s_log_block_size: u32,
pub s_log_cluster_size: u32,
pub s_blocks_per_group: u32,
pub s_clusters_per_group: u32,
pub s_inodes_per_group: u32,
pub s_mtime: u32,
pub s_wtime: u32,
pub s_mnt_count: u16,
pub s_max_mnt_count: u16,
pub s_magic: u16,
pub s_state: u16,
pub s_errors: u16,
pub s_minor_rev_level: u16,
pub s_lastcheck: u32,
pub s_checkinterval: u32,
pub s_creator_os: u32,
pub s_rev_level: u32,
pub s_def_resuid: u16,
pub s_def_resgid: u16,
pub s_first_ino: u32,
pub s_inode_size: u16,
pub s_block_group_nr: u16,
pub s_feature_compat: u32,
pub s_feature_incompat: u32,
pub s_feature_ro_compat: u32,
pub s_uuid: [u8; 16],
pub s_volume_name: [u8; 16],
pub s_last_mounted: [u8; 64],
pub s_algorithm_usage_bitmap: u32,
pub s_prealloc_blocks: u8,
pub s_prealloc_dir_blocks: u8,
pub s_reserved_gdt_blocks: u16,
pub s_journal_uuid: [u8; 16],
pub s_journal_inum: u32,
pub s_journal_dev: u32,
pub s_last_orphan: u32,
pub s_hash_seed: [u32; 4],
pub s_def_hash_version: u8,
pub s_jnl_backup_type: u8,
pub s_desc_size: u16,
pub s_default_mount_opts: u32,
pub s_first_meta_bg: u32,
pub s_mkfs_time: u32,
pub s_jnl_blocks: [u32; 17],
pub s_blocks_count_hi: u32,
pub s_r_blocks_count_hi: u32,
pub s_free_blocks_count_hi: u32,
pub s_min_extra_isize: u16,
pub s_want_extra_isize: u16,
pub s_flags: u32,
pub s_raid_stride: u16,
pub s_mmp_update_interval: u16,
pub s_mmp_block: u64,
pub s_raid_stripe_width: u32,
pub s_log_groups_per_flex: u8,
pub s_checksum_type: u8,
pub s_encryption_level: u8,
pub s_reserved_pad: u8,
pub s_kbytes_written: u64,
pub s_snapshot_inum: u32,
pub s_snapshot_id: u32,
pub s_snapshot_r_blocks_count: u64,
pub s_snapshot_list: u32,
pub s_error_count: u32,
pub s_first_error_time: u32,
pub s_first_error_ino: u32,
pub s_first_error_block: u64,
pub s_first_error_func: [u8; 32],
pub s_first_error_line: u32,
pub s_last_error_time: u32,
pub s_last_error_ino: u32,
pub s_last_error_line: u32,
pub s_last_error_block: u64,
pub s_last_error_func: [u8; 32],
pub s_mount_opts: [u8; 64],
pub s_usr_quota_inum: u32,
pub s_grp_quota_inum: u32,
pub s_overhead_clusters: u32,
pub s_backup_bgs: [u32; 2],
pub s_encrypt_algos: [u8; 4],
pub s_encrypt_pw_salt: [u8; 16],
pub s_lpf_ino: u32,
pub s_prj_quota_inum: u32,
pub s_checksum_seed: u32,
pub s_wtime_hi: u8,
pub s_mtime_hi: u8,
pub s_mkfs_time_hi: u8,
pub s_lastcheck_hi: u8,
pub s_first_error_time_hi: u8,
pub s_last_error_time_hi: u8,
pub s_first_error_errcode: u8,
pub s_last_error_errcode: u8,
pub s_encoding: u16,
pub s_encoding_flags: u16,
pub s_orphan_file_inum: u32,
pub s_reserved: [u32; 94],
pub s_checksum: u32,
}

impl LoadAble for Ext4SuperBlock {}
33 changes: 33 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
mod ext4_structs;
use dbg_hex::dbg_hex;
use ext4_structs::LoadAble;

use std::{fs::File, mem::size_of};

fn main() -> std::io::Result<()> {
let mut file = File::open("../iso/sda1.img")?;
let sb = ext4_structs::Ext4SuperBlock::from_file_offset(&mut file, 0x400)?;
let gd = ext4_structs::Ext4GroupDesc::from_file_offset(&mut file, 0x400 + 1024)?;

let block_size: u64 = (2 as u64).pow(10 + sb.s_log_block_size) as u64;

let inode_table_address: u64 =
((gd.bg_inode_table_hi as u64) << 8) + (gd.bg_inode_table_lo as u64) * block_size;

let inode_num = 2;
let inode_index_in_table = (inode_num - 1) % sb.s_inodes_per_group;
let inode_offset_in_table = inode_index_in_table * sb.s_inode_size as u32;
let inode_address = inode_table_address + (inode_offset_in_table as u64);
let i = ext4_structs::Ext4Inode::from_file_offset(&mut file, inode_address)?;
dbg!(sb.s_blocks_per_group, 8 * block_size);
dbg_hex!(
block_size,
inode_table_address,
inode_num,
inode_index_in_table,
inode_offset_in_table,
inode_address,
i
);
Ok(())
}

0 comments on commit d43cc0b

Please sign in to comment.