updates, remove apfs

This commit is contained in:
overcuriousity 2025-10-20 23:11:43 +02:00
parent 2cd74695c7
commit 217951b632
2 changed files with 86 additions and 168 deletions

View File

@ -4,7 +4,7 @@ A comprehensive toolkit for creating disk images with various filesystems for fo
## Features
- **Multiple Filesystem Support**: NTFS, FAT32, exFAT, ext2/3/4, XFS, swap
- **Multiple Filesystem Support**: NTFS, FAT32, exFAT, ext2/3/4, XFS, HFS+, swap
- **Preset Layouts**: Pre-configured layouts for Windows, Linux, and macOS systems
- **Multi-Partition Support**: Create up to 4 partitions in a single disk image
- **Partition Schemes**: GPT (modern) and MBR (legacy)
@ -39,6 +39,9 @@ sudo apt-get install exfat-fuse exfat-utils
# For XFS support
sudo apt-get install xfsprogs
# For HFS+ support
sudo apt-get install hfsprogs
```
## Preset Layouts
@ -61,8 +64,7 @@ Choose from pre-configured layouts that simulate real operating systems:
- Minimal Linux (MBR, Single ext4)
**macOS Presets:**
- Modern macOS (GPT, EFI + APFS)
- Legacy macOS (GPT, Single HFS+)
- macOS (GPT, EFI + HFS+)
**Custom Layout:**
- Full manual configuration with 1-4 partitions
@ -113,7 +115,7 @@ The script will:
- Partition Scheme: GPT or MBR
- Partition Count: 1-4 partitions
- Per-Partition Configuration:
- Filesystem type (NTFS, FAT32, exFAT, ext2/3/4, XFS, swap, etc.)
- Filesystem type (NTFS, FAT32, exFAT, ext2/3/4, XFS, HFS+, swap, etc.)
- Size in MB (last partition uses remaining space)
- Volume label (except for swap)
- **Mount**: Option to mount filesystems immediately after creation
@ -137,7 +139,6 @@ Checking filesystem tool availability...
✓ ext4 (mkfs.ext4 available)
✓ XFS (mkfs.xfs available)
✓ HFS+ (mkfs.hfsplus available)
✓ APFS (limited Linux support; creation typically requires macOS)
✓ swap (mkswap available)
✓ Unallocated (no mkfs required)
@ -182,13 +183,12 @@ Layout Presets:
11) Minimal Linux (MBR, Single ext4)
macOS Presets:
12) Modern macOS (GPT, EFI + APFS)
13) Legacy macOS (GPT, Single HFS+)
12) macOS (GPT, EFI + HFS+)
Custom:
14) Custom layout (manual configuration)
13) Custom layout (manual configuration)
Select layout [1-14]: 1
Select layout [1-13]: 1
[INFO] Preset: Windows 11/10 (GPT)
[NOTE] EFI System Partition (260MB) + Main Windows (auto) + Recovery (500MB)
@ -471,4 +471,14 @@ sudo lsof | grep /mnt/forensic
# Force unmount (use with caution)
sudo umount -l /mnt/forensic
```
```
## Notes on Filesystem Support
- **NTFS**: Full read/write support via ntfs-3g
- **FAT12/16/32**: Full support on all Linux systems
- **exFAT**: Requires exfatprogs or exfat-utils
- **ext2/3/4**: Native Linux support
- **XFS**: Native Linux support
- **HFS+**: Limited support (often read-only on Linux)
- **APFS**: Not supported on Linux (requires macOS)

View File

@ -2,7 +2,7 @@
# Forensic Practice Disk Image Creator - Enhanced Version
# Creates disk images with various filesystems for forensic analysis practice
# Now with improved UX, sanity checks, and extended filesystem support
# APFS support removed - not functional on Linux
set -e
set -o pipefail
@ -62,7 +62,6 @@ FS_MIN_SIZE["ext3"]=1
FS_MIN_SIZE["ext4"]=1
FS_MIN_SIZE["xfs"]=16
FS_MIN_SIZE["hfsplus"]=8
FS_MIN_SIZE["apfs"]=1
FS_MIN_SIZE["swap"]=1
FS_MIN_SIZE["unallocated"]=1
@ -77,7 +76,6 @@ FS_MAX_SIZE["ext3"]=16777216
FS_MAX_SIZE["ext4"]=16777216
FS_MAX_SIZE["xfs"]=16777216
FS_MAX_SIZE["hfsplus"]=2097152 # 2TB
FS_MAX_SIZE["apfs"]=16777216
FS_MAX_SIZE["swap"]=128000 # 128GB practical max
FS_MAX_SIZE["unallocated"]=16777216 # No real limit
@ -122,7 +120,6 @@ check_filesystem_tools() {
"ext4|mkfs.ext4 mke2fs|sudo apt-get install e2fsprogs"
"XFS|mkfs.xfs|sudo apt-get install xfsprogs"
"HFS+|mkfs.hfsplus newfs_hfs|sudo apt-get install hfsprogs"
"APFS|mkfs.apfs apfs-fuse|limited support — creation typically requires macOS or specialized tools"
"swap|mkswap|should be present in util-linux"
"Unallocated|:|no mkfs required"
)
@ -446,13 +443,12 @@ get_preset_or_custom() {
echo " 11) Minimal Linux (MBR, Single ext4)"
echo ""
echo " macOS Presets:"
echo " 12) Modern macOS (GPT, EFI + APFS)"
echo " 13) Legacy macOS (GPT, Single HFS+)"
echo " 12) macOS (GPT, EFI + HFS+)"
echo ""
echo " Custom:"
echo " 14) Custom layout (manual configuration)"
echo " 13) Custom layout (manual configuration)"
echo ""
read -p "Select layout [1-14]: " PRESET_CHOICE
read -p "Select layout [1-13]: " PRESET_CHOICE
case $PRESET_CHOICE in
1) # Windows 11/10
@ -536,23 +532,15 @@ get_preset_or_custom() {
print_info "Preset: Minimal Linux (MBR)"
print_note "Single ext4 partition"
;;
12) # Modern macOS
12) # macOS
USE_PRESET=true
PARTITION_SCHEME="gpt"
PARTITION_COUNT=2
print_info "Preset: Modern macOS (GPT)"
print_note "EFI (200MB) + APFS (auto)"
print_warning "APFS support on Linux is very limited"
print_info "Preset: macOS (GPT)"
print_note "EFI (200MB) + HFS+ (auto)"
print_warning "HFS+ support on Linux is limited (read-only in most cases)"
;;
13) # Legacy macOS
USE_PRESET=true
PARTITION_SCHEME="gpt"
PARTITION_COUNT=1
print_info "Preset: Legacy macOS (GPT)"
print_note "Single HFS+ partition"
print_warning "HFS+ support on Linux is limited"
;;
14) # Custom
13) # Custom
USE_PRESET=false
print_info "Custom layout selected"
;;
@ -635,11 +623,8 @@ apply_preset() {
11) # Minimal Linux
PARTITION_CONFIGS+=("ext4|remaining|rootfs")
;;
12) # Modern macOS
12) # macOS
PARTITION_CONFIGS+=("vfat|200|EFI")
PARTITION_CONFIGS+=("apfs|remaining|MacintoshHD")
;;
13) # Legacy macOS
PARTITION_CONFIGS+=("hfsplus|remaining|MacintoshHD")
;;
esac
@ -723,12 +708,11 @@ get_partition_configs() {
echo " 7) ext3 (Linux, journaling)"
echo " 8) ext4 (Linux default, modern)"
echo " 9) XFS (High-performance Linux)"
echo " 10) HFS+ (macOS legacy)"
echo " 11) APFS (macOS modern - limited Linux support)"
echo " 12) swap (Linux swap space)"
echo " 13) unallocated (Empty space - for forensic practice)"
echo " 10) HFS+ (macOS - limited Linux support)"
echo " 11) swap (Linux swap space)"
echo " 12) unallocated (Empty space - for forensic practice)"
echo ""
read -p "Select filesystem for partition $i [1-13]: " FS_CHOICE
read -p "Select filesystem for partition $i [1-12]: " FS_CHOICE
case $FS_CHOICE in
1)
@ -814,18 +798,9 @@ get_partition_configs() {
get_partition_configs
return
fi
print_warning "HFS+ support on Linux is limited"
print_warning "HFS+ support on Linux is limited (typically read-only)"
;;
11)
PART_FS="apfs"
print_warning "APFS has very limited Linux support and may not work properly"
read -p "Continue anyway? (y/n): " continue
if [ "$continue" != "y" ]; then
get_partition_configs
return
fi
;;
12)
PART_FS="swap"
if ! command -v mkswap >/dev/null 2>&1; then
print_error "mkswap not found. Install: sudo apt-get install util-linux"
@ -833,7 +808,7 @@ get_partition_configs() {
return
fi
;;
13)
12)
PART_FS="unallocated"
print_note "Unallocated space - useful for practicing partition recovery"
;;
@ -1028,10 +1003,10 @@ create_partitions() {
parted -s "$LOOP_DEVICE" mklabel "$PARTITION_SCHEME"
# Reserve a small margin at the end of the disk to avoid creating partitions that
# extend into GPT backup header / metadata. This mirrors the -2MB reserve used
# interactively elsewhere in the script.
local PARTITION_TABLE_RESERVED_MB=2
# Reserve space for partition table metadata
# GPT needs ~1MB at start and ~1MB at end
# MBR needs less but we use same reserve for simplicity
local PARTITION_TABLE_RESERVED_MB=3
if [ "$DISK_SIZE_MB" -le $PARTITION_TABLE_RESERVED_MB ]; then
print_error "Disk size (${DISK_SIZE_MB}MB) too small to reserve required metadata space"
cleanup
@ -1138,65 +1113,11 @@ create_partitions() {
exit 1
fi
# Create partitions. We'll iterate in forward order, but the last mkpart will be explicitly ended
# before any trailing unallocated space so that 'unallocated' regions remain as requested.
# Create partitions with proper alignment
# Start at 1MiB for alignment
local start_mb=1
local part_num=1
# Attempt to create a partition, retrying with shrinking end boundary when parted
# complains the end is outside the device (handles alignment/metadata rounding)
try_mkpart() {
local loopdev="$1"
local start_mb="$2"
local end_mb="$3" # numeric MB
local fstype="$4" # optional parted fs type (e.g. ntfs, ext4)
local max_attempts=8
local attempt_end=$end_mb
local output ret last_output
for ((try=0; try<max_attempts; try++)); do
local end_str="${attempt_end}MiB"
if [ -n "$fstype" ]; then
output=$(parted -s "$loopdev" mkpart primary "$fstype" "${start_mb}MiB" "$end_str" 2>&1)
ret=$?
else
output=$(parted -s "$loopdev" mkpart primary "${start_mb}MiB" "$end_str" 2>&1)
ret=$?
fi
if [ $ret -eq 0 ]; then
return 0
fi
last_output="$output"
# If the error looks like 'outside device' / 'not enough space' try shrinking the end
if echo "$output" | grep -Ei 'outside|out of range|not enough space|beyond|außerhalb|außer' >/dev/null 2>&1; then
print_warning "parted failed to create partition with end ${end_str} - retrying with ${attempt_end-1}MiB: $output"
attempt_end=$((attempt_end - 1))
if [ "$attempt_end" -le "$start_mb" ]; then
print_error "Cannot allocate partition: insufficient space after retries"
echo "$last_output"
cleanup
exit 1
fi
continue
else
print_error "parted failed creating partition: $output"
cleanup
exit 1
fi
done
print_error "Failed to create partition after ${max_attempts} retries: $last_output"
cleanup
exit 1
}
for i in $(seq 0 $((count - 1))); do
fs="${fs_arr[$i]}"
size_mb=${numeric_size[$i]}
@ -1208,60 +1129,56 @@ create_partitions() {
continue
fi
# determine end for this partition
# Calculate end position
if [ "$i" -eq "$last_mkpart_idx" ]; then
# Make sure last mkpart ends before any trailing unallocated space and within usable area
# Last partition: use remaining space minus trailing unallocated
end_mb=$((usable_mb - trailing_unalloc_sum))
if [ "$start_mb" -ge "$end_mb" ]; then
print_error "Not enough space to create partition $((i+1)): needed ${size_mb}MB, available $((end_mb - start_mb))MB"
cleanup
exit 1
fi
end="${end_mb}MiB"
numeric_end_mb=$end_mb
else
end_val=$((start_mb + size_mb))
# ensure we don't exceed usable area (should be caught by earlier checks)
if [ "$end_val" -gt "$usable_mb" ]; then
print_error "Partition $((i+1)) would exceed usable disk area (end ${end_val}MB > usable ${usable_mb}MB)"
cleanup
exit 1
fi
end="${end_val}MiB"
numeric_end_mb=$end_val
# Not last partition: use specified size
end_mb=$((start_mb + size_mb))
fi
print_info "Creating partition $part_num: ${start_mb}MiB -> $end"
# Sanity check
if [ "$start_mb" -ge "$end_mb" ]; then
print_error "Invalid partition $((i+1)): start ${start_mb}MB >= end ${end_mb}MB"
cleanup
exit 1
fi
print_info "Creating partition $part_num: ${start_mb}MiB -> ${end_mb}MiB"
# Use parted with optimal alignment
# The -a optimal flag lets parted choose the best alignment
local parted_fs_type=""
case $fs in
swap)
try_mkpart "$LOOP_DEVICE" "$start_mb" "$numeric_end_mb" linux-swap
;;
fat12|fat16|vfat)
try_mkpart "$LOOP_DEVICE" "$start_mb" "$numeric_end_mb" fat32
;;
ntfs)
try_mkpart "$LOOP_DEVICE" "$start_mb" "$numeric_end_mb" ntfs
;;
ext2|ext3|ext4)
try_mkpart "$LOOP_DEVICE" "$start_mb" "$numeric_end_mb" ext4
;;
xfs)
try_mkpart "$LOOP_DEVICE" "$start_mb" "$numeric_end_mb" xfs
;;
hfsplus)
try_mkpart "$LOOP_DEVICE" "$start_mb" "$numeric_end_mb" hfs+
;;
*)
try_mkpart "$LOOP_DEVICE" "$start_mb" "$numeric_end_mb" ""
;;
swap) parted_fs_type="linux-swap" ;;
fat12|fat16|vfat) parted_fs_type="fat32" ;;
ntfs) parted_fs_type="ntfs" ;;
ext2|ext3|ext4) parted_fs_type="ext4" ;;
xfs) parted_fs_type="xfs" ;;
hfsplus) parted_fs_type="hfs+" ;;
esac
# advance start pointer for next partition (skip this for the explicitly-ended last mkpart)
# Create partition
if [ -n "$parted_fs_type" ]; then
if ! parted -s -a optimal "$LOOP_DEVICE" mkpart primary "$parted_fs_type" "${start_mb}MiB" "${end_mb}MiB"; then
print_error "Failed to create partition $part_num"
cleanup
exit 1
fi
else
if ! parted -s -a optimal "$LOOP_DEVICE" mkpart primary "${start_mb}MiB" "${end_mb}MiB"; then
print_error "Failed to create partition $part_num"
cleanup
exit 1
fi
fi
# Move to next partition start
if [ "$i" -ne "$last_mkpart_idx" ]; then
start_mb=$((start_mb + size_mb))
else
start_mb=$((end_mb))
start_mb=$end_mb
fi
part_num=$((part_num + 1))
@ -1312,7 +1229,6 @@ format_partitions() {
cleanup
exit 1
fi
echo "$output" | sed -n '1,50p'
;;
fat16)
output=$(mkfs.fat -F 16 -n "$label" "$PARTITION" 2>&1)
@ -1323,7 +1239,6 @@ format_partitions() {
cleanup
exit 1
fi
echo "$output" | sed -n '1,50p'
;;
vfat)
output=$(mkfs.vfat -F 32 -n "$label" "$PARTITION" 2>&1)
@ -1334,7 +1249,6 @@ format_partitions() {
cleanup
exit 1
fi
echo "$output" | sed -n '1,50p'
;;
ntfs)
output=$(mkfs.ntfs -f -L "$label" "$PARTITION" 2>&1)
@ -1345,7 +1259,6 @@ format_partitions() {
cleanup
exit 1
fi
echo "$output" | grep -E "^(Cluster|Creating|mkntfs completed)" || true
;;
exfat)
output=$(mkfs.exfat -n "$label" "$PARTITION" 2>&1)
@ -1356,7 +1269,6 @@ format_partitions() {
cleanup
exit 1
fi
echo "$output" | sed -n '1,50p'
;;
ext2|ext3|ext4)
output=$(mkfs."$fs" -L "$label" "$PARTITION" 2>&1)
@ -1367,7 +1279,6 @@ format_partitions() {
cleanup
exit 1
fi
echo "$output" | grep -E "^(Creating|Writing|mke2fs)" || true
;;
xfs)
output=$(mkfs.xfs -f -L "$label" "$PARTITION" 2>&1)
@ -1378,7 +1289,6 @@ format_partitions() {
cleanup
exit 1
fi
echo "$output" | sed -n '1,50p'
;;
hfsplus)
output=$(mkfs.hfsplus -v "$label" "$PARTITION" 2>&1)
@ -1389,11 +1299,6 @@ format_partitions() {
cleanup
exit 1
fi
echo "$output" | sed -n '1,50p'
;;
apfs)
print_warning "APFS formatting on Linux is not well supported"
print_info "Skipping format for APFS partition"
;;
swap)
output=$(mkswap -L "SWAP${actual_part_num}" "$PARTITION" 2>&1)
@ -1404,7 +1309,6 @@ format_partitions() {
cleanup
exit 1
fi
echo "$output" | grep -E "^Setting up" || true
;;
*)
print_warning "Unknown filesystem type: $fs - skipping format"
@ -1470,8 +1374,8 @@ mount_filesystems() {
for config in "${PARTITION_CONFIGS[@]}"; do
IFS='|' read -r fs size label <<< "$config"
# Skip swap, apfs, and unallocated filesystems
if [ "$fs" = "swap" ] || [ "$fs" = "apfs" ] || [ "$fs" = "unallocated" ]; then
# Skip swap and unallocated filesystems
if [ "$fs" = "swap" ] || [ "$fs" = "unallocated" ]; then
print_info "Skipping mount for $fs partition $part_num"
part_num=$((part_num + 1))
continue
@ -1649,6 +1553,10 @@ main() {
if [ "$modify" = "y" ]; then
get_partition_configs
fi
else
get_partition_scheme
get_partition_count
get_partition_configs
fi
# Show final summary and confirm