add raid creation, improve ux
This commit is contained in:
54
README.md
54
README.md
@@ -1,9 +1,10 @@
|
|||||||
# pseudodisk
|
# pseudodisk
|
||||||
|
|
||||||
A comprehensive toolkit for creating disk images with various filesystems for forensic analysis practice and education.
|
A comprehensive toolkit for creating disk images with various filesystems and RAID arrays for forensic analysis practice and education.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
### Disk Image Creator (`pseudodisk.sh`)
|
||||||
- **Multiple Filesystem Support**: NTFS, FAT32, exFAT, ext2/3/4, XFS, HFS+, swap
|
- **Multiple Filesystem Support**: NTFS, FAT32, exFAT, ext2/3/4, XFS, HFS+, swap
|
||||||
- **Preset Layouts**: Pre-configured layouts for Windows, Linux, and macOS systems
|
- **Preset Layouts**: Pre-configured layouts for Windows, Linux, and macOS systems
|
||||||
- **Multi-Partition Support**: Create up to 4 partitions in a single disk image
|
- **Multi-Partition Support**: Create up to 4 partitions in a single disk image
|
||||||
@@ -14,6 +15,15 @@ A comprehensive toolkit for creating disk images with various filesystems for fo
|
|||||||
- **Filesystem Availability Check**: Verifies required tools before operation
|
- **Filesystem Availability Check**: Verifies required tools before operation
|
||||||
- **Forensic-Ready**: Pre-configured for hex editor and forensic tool analysis
|
- **Forensic-Ready**: Pre-configured for hex editor and forensic tool analysis
|
||||||
|
|
||||||
|
### Universal RAID Creator (`raid_creator.sh`)
|
||||||
|
- **Three Implementation Modes**: mdadm (production), manual (educational), hybrid (both)
|
||||||
|
- **Complete RAID Support**: RAID 0, 1, 4, 5, 6, and 10
|
||||||
|
- **Advanced Configuration**: Custom stripe directions, algorithms, and parity layouts
|
||||||
|
- **Minimal Dependencies**: Works with or without mdadm
|
||||||
|
- **Educational Value**: Shows internal RAID mechanics
|
||||||
|
- **Forensic Practice**: Creates realistic RAID arrays for analysis
|
||||||
|
- **Comprehensive Documentation**: Extensive guides included
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
### Required Packages
|
### Required Packages
|
||||||
@@ -211,6 +221,31 @@ sudo ./cleanup.sh
|
|||||||
# Type 'all' when prompted
|
# Type 'all' when prompted
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Creating RAID Arrays
|
||||||
|
|
||||||
|
### Universal RAID Creator
|
||||||
|
|
||||||
|
The universal RAID creator combines production-quality mdadm arrays with educational manual implementations:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ./raid_creator.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Three Modes:**
|
||||||
|
1. **mdadm (Production)** - Real RAID with metadata, mountable immediately
|
||||||
|
2. **Manual (Educational)** - Raw striping showing internal mechanics
|
||||||
|
3. **Hybrid** - Manual layout + mdadm metadata for comprehensive learning
|
||||||
|
|
||||||
|
**Supported RAID Levels:** 0, 1, 4, 5, 6, 10
|
||||||
|
|
||||||
|
**Advanced Options:**
|
||||||
|
- Custom stripe directions (forward, backward, inside-out, outside-in)
|
||||||
|
- Stripe algorithms (standard, delayed, interleaved, random)
|
||||||
|
- Multiple parity layouts
|
||||||
|
- Configurable chunk sizes
|
||||||
|
- Hot spare support (mdadm mode)
|
||||||
|
|
||||||
|
|
||||||
## Forensic Analysis Guide
|
## Forensic Analysis Guide
|
||||||
|
|
||||||
### Basic Hex Analysis
|
### Basic Hex Analysis
|
||||||
@@ -230,6 +265,23 @@ xxd -l 512 win11.dd
|
|||||||
xxd -s 0x1BE -l 64 win11.dd
|
xxd -s 0x1BE -l 64 win11.dd
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### RAID Array Analysis
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View stripe patterns across disks
|
||||||
|
for i in {0..3}; do
|
||||||
|
echo "=== Disk $i ==="
|
||||||
|
dd if=raid_disk_${i}.dd bs=64k count=1 2>/dev/null | xxd | head -5
|
||||||
|
done
|
||||||
|
|
||||||
|
# Examine RAID metadata (if present)
|
||||||
|
sudo mdadm --examine raid_disk_0.dd
|
||||||
|
|
||||||
|
# Reassemble and mount
|
||||||
|
sudo mdadm --assemble --scan
|
||||||
|
sudo mount /dev/md0 /mnt/raid
|
||||||
|
```
|
||||||
|
|
||||||
#### GUI Hex Editors
|
#### GUI Hex Editors
|
||||||
```bash
|
```bash
|
||||||
# Install Bless (GTK hex editor)
|
# Install Bless (GTK hex editor)
|
||||||
|
|||||||
@@ -250,7 +250,8 @@ auto_cleanup() {
|
|||||||
done <<< "$devices"
|
done <<< "$devices"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
read -p "Clean up all $count device(s)? (yes/no): " confirm
|
read -p "Clean up all $count device(s)? (yes/no, default: no): " confirm
|
||||||
|
confirm=${confirm:-no}
|
||||||
|
|
||||||
if [ "$confirm" != "yes" ]; then
|
if [ "$confirm" != "yes" ]; then
|
||||||
print_info "Cancelled"
|
print_info "Cancelled"
|
||||||
@@ -350,7 +351,8 @@ interactive_cleanup() {
|
|||||||
echo " [q] Quit"
|
echo " [q] Quit"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
read -p "Enter selection: " selection
|
read -p "Enter selection (default: q): " selection
|
||||||
|
selection=${selection:-q}
|
||||||
|
|
||||||
if [ "$selection" = "q" ]; then
|
if [ "$selection" = "q" ]; then
|
||||||
print_info "Cancelled"
|
print_info "Cancelled"
|
||||||
@@ -404,7 +406,8 @@ main() {
|
|||||||
echo " 3) Enter filename manually"
|
echo " 3) Enter filename manually"
|
||||||
echo " 4) Quit"
|
echo " 4) Quit"
|
||||||
echo ""
|
echo ""
|
||||||
read -p "Select option [1-4]: " option
|
read -p "Select option [1-4, default: 4]: " option
|
||||||
|
option=${option:-4}
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
|||||||
@@ -227,7 +227,8 @@ validate_fs_size() {
|
|||||||
|
|
||||||
if [ -n "$max" ] && [ "$size" -gt "$max" ]; then
|
if [ -n "$max" ] && [ "$size" -gt "$max" ]; then
|
||||||
print_warning "Partition size ${size}MB exceeds recommended maximum for $fs (${max}MB)"
|
print_warning "Partition size ${size}MB exceeds recommended maximum for $fs (${max}MB)"
|
||||||
read -p "Continue anyway? (y/n): " continue
|
read -p "Continue anyway? (y/n, default: n): " continue
|
||||||
|
continue=${continue:-n}
|
||||||
if [ "$continue" != "y" ]; then
|
if [ "$continue" != "y" ]; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@@ -309,7 +310,8 @@ get_filename() {
|
|||||||
# Check if file exists
|
# Check if file exists
|
||||||
if [ -f "$FILENAME" ]; then
|
if [ -f "$FILENAME" ]; then
|
||||||
print_warning "File already exists: $FILENAME"
|
print_warning "File already exists: $FILENAME"
|
||||||
read -p "Overwrite? (y/n): " OVERWRITE
|
read -p "Overwrite? (y/n, default: n): " OVERWRITE
|
||||||
|
OVERWRITE=${OVERWRITE:-n}
|
||||||
if [ "$OVERWRITE" != "y" ]; then
|
if [ "$OVERWRITE" != "y" ]; then
|
||||||
print_info "Please choose a different filename"
|
print_info "Please choose a different filename"
|
||||||
get_filename
|
get_filename
|
||||||
@@ -329,7 +331,8 @@ get_disk_size() {
|
|||||||
echo " 5) 10 GB (very large)"
|
echo " 5) 10 GB (very large)"
|
||||||
echo " 6) Custom size"
|
echo " 6) Custom size"
|
||||||
echo ""
|
echo ""
|
||||||
read -p "Select disk size [1-6]: " SIZE_CHOICE
|
read -p "Select disk size [1-6, default: 3]: " SIZE_CHOICE
|
||||||
|
SIZE_CHOICE=${SIZE_CHOICE:-3}
|
||||||
|
|
||||||
case $SIZE_CHOICE in
|
case $SIZE_CHOICE in
|
||||||
1) DISK_SIZE_MB=100 ;;
|
1) DISK_SIZE_MB=100 ;;
|
||||||
@@ -392,7 +395,8 @@ get_init_method() {
|
|||||||
echo ""
|
echo ""
|
||||||
print_tip "For forensic practice, /dev/zero (option 1) is recommended"
|
print_tip "For forensic practice, /dev/zero (option 1) is recommended"
|
||||||
echo ""
|
echo ""
|
||||||
read -p "Select initialization method [1-3]: " INIT_CHOICE
|
read -p "Select initialization method [1-3, default: 1]: " INIT_CHOICE
|
||||||
|
INIT_CHOICE=${INIT_CHOICE:-1}
|
||||||
|
|
||||||
case $INIT_CHOICE in
|
case $INIT_CHOICE in
|
||||||
1) INIT_METHOD="zero" ;;
|
1) INIT_METHOD="zero" ;;
|
||||||
@@ -448,7 +452,8 @@ get_preset_or_custom() {
|
|||||||
echo " Custom:"
|
echo " Custom:"
|
||||||
echo " 13) Custom layout (manual configuration)"
|
echo " 13) Custom layout (manual configuration)"
|
||||||
echo ""
|
echo ""
|
||||||
read -p "Select layout [1-13]: " PRESET_CHOICE
|
read -p "Select layout [1-13, default: 1]: " PRESET_CHOICE
|
||||||
|
PRESET_CHOICE=${PRESET_CHOICE:-1}
|
||||||
|
|
||||||
case $PRESET_CHOICE in
|
case $PRESET_CHOICE in
|
||||||
1) # Windows 11/10
|
1) # Windows 11/10
|
||||||
@@ -639,7 +644,8 @@ get_partition_scheme() {
|
|||||||
echo ""
|
echo ""
|
||||||
print_tip "GPT is recommended for modern systems and disks >2TB"
|
print_tip "GPT is recommended for modern systems and disks >2TB"
|
||||||
echo ""
|
echo ""
|
||||||
read -p "Select partition scheme [1-2]: " PARTITION_CHOICE_SCHEME
|
read -p "Select partition scheme [1-2, default: 1]: " PARTITION_CHOICE_SCHEME
|
||||||
|
PARTITION_CHOICE_SCHEME=${PARTITION_CHOICE_SCHEME:-1}
|
||||||
|
|
||||||
case $PARTITION_CHOICE_SCHEME in
|
case $PARTITION_CHOICE_SCHEME in
|
||||||
1) PARTITION_SCHEME="gpt" ;;
|
1) PARTITION_SCHEME="gpt" ;;
|
||||||
@@ -665,7 +671,8 @@ get_partition_scheme() {
|
|||||||
# Get number of partitions
|
# Get number of partitions
|
||||||
get_partition_count() {
|
get_partition_count() {
|
||||||
echo ""
|
echo ""
|
||||||
read -p "How many partitions? (1-4): " PARTITION_COUNT
|
read -p "How many partitions? (1-4, default: 1): " PARTITION_COUNT
|
||||||
|
PARTITION_COUNT=${PARTITION_COUNT:-1}
|
||||||
|
|
||||||
if ! [[ "$PARTITION_COUNT" =~ ^[1-4]$ ]]; then
|
if ! [[ "$PARTITION_COUNT" =~ ^[1-4]$ ]]; then
|
||||||
print_error "Invalid number. Must be between 1 and 4"
|
print_error "Invalid number. Must be between 1 and 4"
|
||||||
@@ -712,7 +719,8 @@ get_partition_configs() {
|
|||||||
echo " 11) swap (Linux swap space)"
|
echo " 11) swap (Linux swap space)"
|
||||||
echo " 12) unallocated (Empty space - for forensic practice)"
|
echo " 12) unallocated (Empty space - for forensic practice)"
|
||||||
echo ""
|
echo ""
|
||||||
read -p "Select filesystem for partition $i [1-12]: " FS_CHOICE
|
read -p "Select filesystem for partition $i [1-12, default: 8]: " FS_CHOICE
|
||||||
|
FS_CHOICE=${FS_CHOICE:-8}
|
||||||
|
|
||||||
case $FS_CHOICE in
|
case $FS_CHOICE in
|
||||||
1)
|
1)
|
||||||
@@ -1365,7 +1373,8 @@ cleanup() {
|
|||||||
# Mount filesystems
|
# Mount filesystems
|
||||||
mount_filesystems() {
|
mount_filesystems() {
|
||||||
echo ""
|
echo ""
|
||||||
read -p "Do you want to mount the filesystem(s) now? (y/n): " MOUNT_NOW
|
read -p "Do you want to mount the filesystem(s) now? (y/n, default: n): " MOUNT_NOW
|
||||||
|
MOUNT_NOW=${MOUNT_NOW:-n}
|
||||||
|
|
||||||
if [ "$MOUNT_NOW" = "y" ]; then
|
if [ "$MOUNT_NOW" = "y" ]; then
|
||||||
local part_num=1
|
local part_num=1
|
||||||
@@ -1583,7 +1592,8 @@ main() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
read -p "Proceed with creation? (y/n): " CONFIRM
|
read -p "Proceed with creation? (y/n, default: y): " CONFIRM
|
||||||
|
CONFIRM=${CONFIRM:-y}
|
||||||
|
|
||||||
if [ "$CONFIRM" != "y" ]; then
|
if [ "$CONFIRM" != "y" ]; then
|
||||||
print_info "Operation cancelled"
|
print_info "Operation cancelled"
|
||||||
@@ -1598,6 +1608,50 @@ main() {
|
|||||||
mount_filesystems
|
mount_filesystems
|
||||||
|
|
||||||
show_summary
|
show_summary
|
||||||
|
|
||||||
|
# Ask if user wants to create a RAID array from the created image
|
||||||
|
ask_create_raid
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ask if user wants to create RAID array from the created image
|
||||||
|
ask_create_raid() {
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
echo " RAID Array Creation"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
read -p "Create a RAID array from this image? (y/n, default: n): " create_raid
|
||||||
|
create_raid=${create_raid:-n}
|
||||||
|
|
||||||
|
if [ "$create_raid" = "y" ]; then
|
||||||
|
print_info "Preparing to create RAID array..."
|
||||||
|
|
||||||
|
# Check if raid_creator.sh exists
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
RAID_CREATOR="$SCRIPT_DIR/raid_creator.sh"
|
||||||
|
|
||||||
|
if [ ! -f "$RAID_CREATOR" ]; then
|
||||||
|
print_error "raid_creator.sh not found in $SCRIPT_DIR"
|
||||||
|
print_info "Please ensure raid_creator.sh is in the same directory"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$RAID_CREATOR" ]; then
|
||||||
|
print_warning "raid_creator.sh is not executable, attempting to make it executable..."
|
||||||
|
chmod +x "$RAID_CREATOR" || {
|
||||||
|
print_error "Failed to make raid_creator.sh executable"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_success "Launching RAID creator with image: $FILENAME"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Execute raid_creator.sh with the created image as parameter
|
||||||
|
"$RAID_CREATOR" "$FILENAME"
|
||||||
|
else
|
||||||
|
print_info "Skipping RAID array creation"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Run main function
|
# Run main function
|
||||||
|
|||||||
1556
raid_creator.sh
Executable file
1556
raid_creator.sh
Executable file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user