Last active
August 28, 2025 07:03
-
-
Save joevt/a99e3af71343d8242e0078ab4af39b6c to your computer and use it in GitHub Desktop.
Revisions
-
joevt revised this gist
Aug 28, 2025 . 1 changed file with 30 additions and 8 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -133,7 +133,11 @@ inodestring () { local thepath; thepath="$(inodetopath "$deviceid" "$inode")" printf "%d" "$inode" if [[ -n $thepath ]]; then printf " => \"%s\"" "$thepath" elif ((inode == 2)); then printf " => root directory of volume" fi } forkdatastring () { @@ -255,6 +259,8 @@ DRIVELIST="$(sed -n -E " for PARTDRIVE in $(echo $DRIVELIST); do DRIVE=$(expr "$PARTDRIVE" : '.*_\([^_]*\)') DTYPE=$(expr "$PARTDRIVE" : '\(.*\)_[^_]*') #echo "DRIVE = <<$DRIVE>>" #echo "DTYPE = <<$DTYPE>>" echo "===============================================================================" diskutiloutput="$(sed -nE '/\/dev\/'"$DRIVE"'( |$)/,/^$/ p' <<< "${disklist}")" @@ -267,25 +273,29 @@ for PARTDRIVE in $(echo $DRIVELIST); do if [[ -z $BLOCKSIZE ]]; then BLOCKSIZE=512 fi #echo "BLOCKSIZE = <<$BLOCKSIZE>>" TOTALSIZE=$(( $(diskutil info -plist $DRIVE | perl -0777 -ne 'if (m|<key>TotalSize</key>\s*<integer>(\d+)</integer>|) { print $1 }') / BLOCKSIZE )) #echo "TOTALSIZE = <<$TOTALSIZE>>" MOUNTPOINTS="" if [[ -n $INPUTSLICE ]]; then SLICELIST="$(echo "$diskutiloutput" | sed -n -E "/^.* (disk[0-9]+s${INPUTSLICE})$/s//\1/p")" else SLICELIST="$(echo "$diskutiloutput" | sed -n -E "/^.* (disk[0-9]+s[0-9]+)$/s//\1/p")" fi #echo "SLICELIST = <<$SLICELIST>>" for THESLICE in $(echo $SLICELIST); do echo "---------------------------------------------" partinfo="$(diskutil info "$THESLICE")" echo "$partinfo" MOUNTPOINTS="${MOUNTPOINTS}${THESLICE}_$(sed -nE '/ *Mount Point: *(.*)/s//\1/p' <<< "$partinfo")"$'\n' done echo "MOUNTPOINTS: $MOUNTPOINTS" echo "---------------------------------------------" PARTLIST="" @@ -408,17 +418,29 @@ for PARTDRIVE in $(echo $DRIVELIST); do else DEVICEID=$(stat -f "%r" "/dev/${DRIVE}") fi #echo "PNUM = <<$PNUM>>" #echo "PSTART = <<$PSTART>>" #echo "PLENGTH = <<$PLENGTH>>" #echo "PTYPE = <<$PTYPE>>" #echo "DEVICEID = <<$DEVICEID>>" POFFSETS="_0" while [[ -n $POFFSETS ]]; do POFFSET=$( expr "$POFFSETS" : '_\([0-9]*\)') POFFSETS=$( expr "$POFFSETS" : '_[0-9]*\(_.*\)') #echo "POFFSET: <<$POFFSET>>" if (( POFFSET >= PLENGTH )); then continue fi blockbytes=$( { dd if="/dev/$DRIVE" bs="$BLOCKSIZE" skip=$((PSTART + POFFSET)) count=1 2> /dev/null || \ dd if="/dev/r$DRIVE" bs="$BLOCKSIZE" skip=$((PSTART + POFFSET)) count=1 2> /dev/null } | xxd -p -c 9999 ) #echo "blockbytes: <<$blockbytes>>" if [[ $PTYPE = "Apple_Patches" ]]; then -
joevt revised this gist
Mar 20, 2025 . 1 changed file with 92 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ # # Get Partition Info from all disks # # Written by joevt updated March 20, 2025 # Patches marked "rgh" July, 2010, to dump information beyond the # four bios partitions # @@ -33,6 +33,9 @@ else fi [[ "${apfslist:0:4}" == "Disk" ]] && apfslist="" #echo "disklist = <<${disklist}>>" #echo "apfslist = <<${apfslist}>>" MBRHASHES=" Windows_XP=d88d4f2dbc2c662db7d7d60ebf9e3e00 Windows_Vista=12c9d7ff4914c88a7f9eadf9211b861b @@ -172,6 +175,7 @@ dumpencoding () { local encoding="$2" ((encoding)) && { printf "%s 0x%08x" "$message" "$encoding" # 656e63 = enc (( (encoding & 0x656e6300) == 0x656e6300 )) && { case $((encoding & 0xff)) in 0) printf " = kTextEncodingMacRoman" ;; @@ -217,6 +221,9 @@ dumpencoding () { esac } printf "\n" } || { printf "%s 0x%08x" "$message" "$encoding" printf "\n" } } @@ -239,7 +246,11 @@ vsdbtouuid () { (( ALLDISKS )) && echo "$disklist" echo "$apfslist" DRIVELIST="$(sed -n -E " /^[ ]*0: [ ]{0,25}([A-Za-z_]+)[ ]*[+*][0-9.]+ [TGMK][iB][ ]+(disk[0-9]+)$/s//\1_\2/p; /^[ ]*0: [ ]{0,26} .* [*+][0-9.]+ [TGMK][iB][ ]+(disk[0-9]+)$/s//whole_\1/p " <<< "$disklist")" #echo "DRIVELIST = <<${DRIVELIST}>>" for PARTDRIVE in $(echo $DRIVELIST); do DRIVE=$(expr "$PARTDRIVE" : '.*_\([^_]*\)') @@ -257,6 +268,11 @@ for PARTDRIVE in $(echo $DRIVELIST); do BLOCKSIZE=512 fi TOTALSIZE=$(( $(diskutil info -plist disk16 | perl -0777 -ne 'if (m|<key>TotalSize</key>\s*<integer>(\d+)</integer>|) { print $1 }') / BLOCKSIZE )) MOUNTPOINTS="" if [[ -n $INPUTSLICE ]]; then DEVLIST="$(echo "$diskutiloutput" | sed -n -E "/^.* (disk[0-9]+s${INPUTSLICE})$/s//\1/p")" @@ -377,12 +393,21 @@ for PARTDRIVE in $(echo $DRIVELIST); do PARTLIST="$(sed -nE "/^${INPUTSLICE}_/p" <<< "$PARTLIST")" fi if [[ -z $PARTLIST ]]; then PARTLIST="0_0_$TOTALSIZE" fi #echo "PARTLIST = <<${PARTLIST}>>" for THEPART in $(echo $PARTLIST); do PNUM=$( expr "$THEPART" : '\([0-9]*\)_') PSTART=$( expr "$THEPART" : '[0-9]*_\([0-9]*\)_[0-9]*') PLENGTH=$(expr "$THEPART" : '[0-9]*_[0-9]*_\([0-9]*\)') PTYPE=$( expr "$THEPART" : '[0-9]*_[0-9]*_[0-9]*_\(.*\)') if ((PNUM)); then DEVICEID=$(stat -f "%r" "/dev/${DRIVE}s$PNUM") else DEVICEID=$(stat -f "%r" "/dev/${DRIVE}") fi POFFSETS="_0" while [[ -n $POFFSETS ]]; do @@ -646,6 +671,67 @@ for PARTDRIVE in $(echo $DRIVELIST); do #printf "queued first MDB after boot blocks: $POFFSETS\n" elif [[ ${blockbytes:0:4} == "D2D7" ]]; then # 'RW'+0x8080 # Master Directory Blocks # https://developer.apple.com/library/archive/documentation/mac/pdf/Files/File_Manager.pdf # MDB #drSigWord=${blockbytes:0x000*2:4} drCrDate=$((0x${blockbytes:0x002*2:8})) drLsBkUp=$((0x${blockbytes:0x006*2:8})) drAtrb=$((0x${blockbytes:0x00a*2:4})) drNmFls=$((0x${blockbytes:0x00c*2:4})) drDirSt=$((0x${blockbytes:0x00e*2:4})) drBlLen=$((0x${blockbytes:0x010*2:4})) drNmAlBlks=$((0x${blockbytes:0x012*2:4})) drAlBlkSiz=$((0x${blockbytes:0x014*2:8})) drClpSiz=$((0x${blockbytes:0x018*2:8})) drAlBlSt=$((0x${blockbytes:0x01c*2:4})) drNxtfNum=$((0x${blockbytes:0x01e*2:8})) drFreeBks=$((0x${blockbytes:0x022*2:4})) drVN="$(pascalstring "${blockbytes:0x024*2:28*2}")" echo echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): Master Directory Block contents" printf "000: drSigWord : 'RW'+0x8080 = kMFSSigWord\n" printf "002: drCrDate : %s\n" "$( ((drCrDate)) && date -r $((drCrDate-2082844800)))" printf "006: drLsBkUp : %s\n" "$( ((drLsBkUp )) && date -r $((drLsBkUp -2082844800)))" ((drAtrb)) && { attributestext=$( ((drAtrb & 0x0080)) && printf ",VolumeHardwareLock" ((drAtrb & 0x0100)) && printf ",VolumeUnmounted" ((drAtrb & 0x0200)) && printf ",VolumeSparedBlocks" ((drAtrb & 0x0400)) && printf ",VolumeNoCacheRequired" ((drAtrb & 0x0800)) && printf ",BootVolumeInconsistent" ((drAtrb & 0x1000)) && printf ",CatalogNodeIDsReused" ((drAtrb & 0x2000)) && printf ",VolumeJournaled" ((drAtrb & 0x4000)) && printf ",VolumeInconsistent" ((drAtrb & 0x8000)) && printf ",VolumeSoftwareLock" ((drAtrb & 0x007f)) && printf ",0x%04x?" $((drAtrb & 0x007f)) ) printf "00a: drAtrb : 0x%04x = %s\n" "$drAtrb" "${attributestext:1}" } printf "00c: drNmFls : %d\n" "$drNmFls" printf "00e: drDirSt : %d\n" "$drDirSt" printf "010: drBlLen : %d\n" "$drBlLen" printf "012: drNmAlBlks : %d\n" "$drNmAlBlks" printf "014: drAlBlkSiz : %d\n" "$drAlBlkSiz" printf "018: drClpSiz : %d\n" "$drClpSiz" printf "01c: drAlBlSt : %d\n" "$drAlBlSt" printf "01e: drNxtfNum : %d\n" "$drNxtfNum" printf "022: drFreeBks : %d\n" "$drFreeBks" printf "024: drVN : %s\n" "$drVN" echo xxd -p -r <<< "$blockbytes" | xxd -c 16 if ((POFFSET < drNmAlBlks * (drAlBlkSiz / 512) - 2)); then # queue up location of alternate Master Directory Block POFFSETS="_$((PLENGTH-2))_$((PLENGTH-1))${POFFSETS}" #printf "queued 2alternate MDB: $POFFSETS \n" fi elif [[ ${blockbytes:0:4} == "4244" ]]; then # 'BD' # Master Directory Blocks # https://developer.apple.com/library/archive/documentation/mac/pdf/Files/File_Manager.pdf @@ -784,7 +870,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do checkedDate=$((0x${blockbytes:0x01c*2:8})) fileCount=$((0x${blockbytes:0x020*2:8})) folderCount=$((0x${blockbytes:0x024*2:8})) mdbblockSize=$((0x${blockbytes:0x028*2:8})) totalBlocks=$((0x${blockbytes:0x02c*2:8})) freeBlocks=$((0x${blockbytes:0x030*2:8})) nextAllocation=$((0x${blockbytes:0x034*2:8})) @@ -844,7 +930,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do printf "01c: checkedDate : %s\n" "$( ((checkedDate)) && date -r $((checkedDate-2082844800)))" printf "020: fileCount : %d\n" "$fileCount" printf "024: folderCount : %d\n" "$folderCount" printf "028: blockSize : %d\n" "$mdbblockSize" printf "02c: totalBlocks : %d\n" "$totalBlocks" printf "030: freeBlocks : %d\n" "$freeBlocks" printf "034: nextAllocation : %d\n" "$nextAllocation" @@ -919,7 +1005,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do # queue up location of alternate HFS Plus Volume Header # HFS+ volume starts at POFFSET - 2 endoffset=$((POFFSET - 2 + totalBlocks * (mdbblockSize / 512))) POFFSETS="_$((endoffset - 2))_$((endoffset - 1))${POFFSETS}" #printf "queued alternate HFS+ Header: $POFFSETS\n" -
joevt revised this gist
Mar 16, 2024 . 1 changed file with 23 additions and 24 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ # # Get Partition Info from all disks # # Written by joevt updated March 16, 2024 # Patches marked "rgh" July, 2010, to dump information beyond the # four bios partitions # @@ -239,7 +239,7 @@ vsdbtouuid () { (( ALLDISKS )) && echo "$disklist" echo "$apfslist" DRIVELIST="$(sed -n -E "/^[ ]*0: [ ]{0,25}([A-Za-z_]+)[ ]*[+*][0-9.]+ [TGMK][iB][ ]+(disk[0-9]+)$/s//\1_\2/p;/^[ ]*0: [ ]{0,26} .* \*[0-9.]+ [TGMK][iB][ ]+(disk[0-9]+)$/s//whole_\1/p" <<< "$disklist")" for PARTDRIVE in $(echo $DRIVELIST); do DRIVE=$(expr "$PARTDRIVE" : '.*_\([^_]*\)') @@ -383,22 +383,22 @@ for PARTDRIVE in $(echo $DRIVELIST); do PLENGTH=$(expr "$THEPART" : '[0-9]*_[0-9]*_\([0-9]*\)') PTYPE=$( expr "$THEPART" : '[0-9]*_[0-9]*_[0-9]*_\(.*\)') DEVICEID=$(stat -f "%r" "/dev/${DRIVE}s$PNUM") POFFSETS="_0" while [[ -n $POFFSETS ]]; do POFFSET=$( expr "$POFFSETS" : '_\([0-9]*\)') POFFSETS=$( expr "$POFFSETS" : '_[0-9]*\(_.*\)') if (( POFFSET >= PLENGTH )); then continue fi blockbytes=$(dd if="/dev/$DRIVE" bs="$BLOCKSIZE" skip=$((PSTART + POFFSET)) count=1 2> /dev/null | xxd -p -c 9999) if [[ $PTYPE = "Apple_Patches" ]]; then # Patches # https://developer.apple.com/library/archive/technotes/tn/tn1189.html#SecretsOfThePartitionMap echo echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): Driver Patches" @@ -442,7 +442,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do printf "%03x: patchName : %s\n" $((byteoffset+28)) "$patchName" printf "%03x: patchVendor : %s\n" $((byteoffset+61)) "$patchVendor" [[ -n $patchPad ]] && printf "%03x: patchPad : %s\n" $((byteoffset+62+patchVendorLen)) "$patchPad" ((byteoffset+=patchDescriptorLen)) done # for numPatches @@ -486,7 +486,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do printf " %10d @ %-10d" \ "$pmPartBlkCnt" \ "$pmPyPartStart" [[ $pmSig != 504d ]] && printf " Sig:0x%s?" "$pmSig" [[ -n $pmParType ]] && printf " Type:\"%s\"" "$pmParType" [[ -n $pmPartName ]] && printf " Name:\"%s\"" "$pmPartName" @@ -543,7 +543,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do elif [[ ${blockbytes:0:4} == "4c4b" ]]; then # 'LK' # Boot Blocks # https://developer.apple.com/library/archive/documentation/mac/pdf/Files/File_Manager.pdf # BootBlkHdr #bbID=$((0x${blockbytes:0:4})) bbEntry=$((0x${blockbytes:4:8})) @@ -564,7 +564,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do filler=$((0x${blockbytes:276:4})) bbSysHeapExtra=$((0x${blockbytes:280:8})) bbSysHeapFract=$((0x${blockbytes:288:8})) echo echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): Boot Block Header contents" @@ -604,7 +604,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do } printf "\n" } ((bbPageFlags)) && { # https://developer.apple.com/library/archive/technotes/dv/dv_03.html#//apple_ref/doc/uid/DTS10002393 printf "008: bbPageFlags : 0x%04x =" "$bbPageFlags" @@ -640,15 +640,15 @@ for PARTDRIVE in $(echo $DRIVELIST); do echo echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): 2nd Boot Block contents" xxd -p -r <<< "$blockbytes" | xxd -c 16 ((POFFSET++)) POFFSETS="_${POFFSET}${POFFSETS}" #printf "queued first MDB after boot blocks: $POFFSETS\n" elif [[ ${blockbytes:0:4} == "4244" ]]; then # 'BD' # Master Directory Blocks # https://developer.apple.com/library/archive/documentation/mac/pdf/Files/File_Manager.pdf # MDB #drSigWord=${blockbytes:0x000*2:4} drCrDate=$((0x${blockbytes:0x002*2:8})) @@ -686,7 +686,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do drXTExtRec="${blockbytes:0x086*2:24}" drCTFlSize=$((0x${blockbytes:0x092*2:8})) drCTExtRec="${blockbytes:0x096*2:24}" echo echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): Master Directory Block contents" @@ -708,7 +708,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do ) printf "00a: drAtrb : 0x%04x = %s\n" "$drAtrb" "${attributestext:1}" } printf "00c: drNmFls : %d\n" "$drNmFls" printf "00e: drVBMSt : %d\n" "$drVBMSt" printf "010: drAllocPtr : %d\n" "$drAllocPtr" @@ -745,7 +745,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do printf "07e: drVBMCSize : %d\n" "$drVBMCSize" printf "080: drCtlCSize : %d\n" "$drCtlCSize" fi printf "082: drXTFlSize : %d\n" "$drXTFlSize" printf "086: drXTExtRec : %s\n" "$(extentstring "$drXTExtRec")" printf "092: drCTFlSize : %d\n" "$drCTFlSize" @@ -758,7 +758,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do # queue up location of alternate Master Directory Block POFFSETS="_$((PLENGTH-2))_$((PLENGTH-1))${POFFSETS}" #printf "queued 2alternate MDB: $POFFSETS \n" if (( drEmbedSigWord == 0x482b )); then # queue up location of wrapped HFS+ partition hfsplusblock=$(( drAlBlSt + drEmbedExtent_startBlock * (drAlBlkSiz / 512) )) @@ -769,7 +769,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do elif [[ ${blockbytes:0:4} == "482b" ]] || [[ ${blockbytes:0:4} == "4858" ]]; then # 'H+' or 'HX' # Master Directory Blocks # https://developer.apple.com/library/archive/documentation/mac/pdf/Files/File_Manager.pdf # HFS Plus Volume Header signature=$((0x${blockbytes:0x000*2:4})) signatureChars=$(sed -E 's/(00)+$//' <<< "${blockbytes:0x000*2:4}" | xxd -p -r | tr '\0' '.') @@ -807,7 +807,7 @@ for PARTDRIVE in $(echo $DRIVELIST); do ((signature == 0x482b )) && printf " = kHFSPlusSigWord" ((signature == 0x4858 )) && printf " = kHFSXSigWord" printf "\n" printf "002: version : %d" "$version" ((version == 4 )) && printf " = kHFSPlusVersion" ((version == 5 )) && printf " = kHFSXVersion" @@ -917,10 +917,10 @@ for PARTDRIVE in $(echo $DRIVELIST); do if ((POFFSET < PLENGTH-4)); then # queue up location of alternate HFS Plus Volume Header # HFS+ volume starts at POFFSET - 2 endoffset=$((POFFSET - 2 + totalBlocks * (blockSize / 512))) POFFSETS="_$((endoffset - 2))_$((endoffset - 1))${POFFSETS}" #printf "queued alternate HFS+ Header: $POFFSETS\n" fi @@ -935,10 +935,9 @@ for PARTDRIVE in $(echo $DRIVELIST); do ((POFFSET==0)) && printf "VBR " )contents" "$VBRHASHES" "$HASH" fi if [[ -n ${blockbytes//0/} ]]; then xxd -p -r <<< "$blockbytes" | xxd -c 16 elif [[ -z $POFFSETS ]] && (( POFFSET < 2 )); then POFFSETS="_$((POFFSET+1))" #printf "queued after zero block: $POFFSETS\n" @@ -955,7 +954,7 @@ if [[ -n $INPUTDISK ]]; then ioreg -w 0 -c IOMedia | sed -n -E "/^[ \|]*\+\-o (.*) <class IOMedia[^a-zA-Z]/,/^[ \|]+ }$/p" | { sed -n -E "/^[ \|]*\+\-o (.*)/s//\1/p;/^[ \|]* \| (.*)/s//\1/p;" } | { perl -0777 -n -e 'while (/(^.*? <class IOMedia.*\n\{\n( .*\n)*^ "BSD Name" = "('"$INPUTDISK"'[^\d]|'"${INPUTDISK/s[0-9]*/}"'").*\n( .*\n)*?^}\n)/mg) { printf "$1\n" }' } echo "===============================================================================" else -
joevt revised this gist
Aug 15, 2023 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ # # Get Partition Info from all disks # # Written by joevt updated August 15, 2023 # Patches marked "rgh" July, 2010, to dump information beyond the # four bios partitions # @@ -19,6 +19,7 @@ if [ ! "$USER" = "root" ]; then fi INPUTDISK="$1" INPUTDISK="${INPUTDISK#/dev/}" INPUTSLICE=$(expr "$INPUTDISK" : 'disk[0-9]*s\([0-9]*\)') if [[ -n $INPUTDISK ]]; then -
joevt revised this gist
Jul 28, 2023 . 1 changed file with 25 additions and 26 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ # # Get Partition Info from all disks # # Written by joevt updated July 28, 2023 # Patches marked "rgh" July, 2010, to dump information beyond the # four bios partitions # @@ -22,7 +22,7 @@ INPUTDISK="$1" INPUTSLICE=$(expr "$INPUTDISK" : 'disk[0-9]*s\([0-9]*\)') if [[ -n $INPUTDISK ]]; then disklist="$(diskutil list "$INPUTDISK" | perl -p -e 's|^/|\n/|')" apfslist="$(diskutil apfs list | sed -nE "/^\|/s// /; /^ $/s///; /\+.*$1 /,/^$/ { /^$/d ; p ; }" 2> /dev/null)" ALLDISKS=0 else @@ -219,7 +219,7 @@ dumpencoding () { } } command -v python > /dev/null 2>&1 && python=python || python=python3 vsdbtouuid0 () { "$python" -c ' import uuid ; from hashlib import md5 @@ -238,10 +238,9 @@ vsdbtouuid () { (( ALLDISKS )) && echo "$disklist" echo "$apfslist" DRIVELIST="$(sed -n -E "/^[ ]*0: [ ]{0,25}([A-Za-z_]+)[ ]*[+*][0-9.]+ [TGMK]B[ ]+(disk[0-9]+)$/s//\1_\2/p;/^[ ]*0: [ ]{0,26} .* \*[0-9.]+ [TGMK]B[ ]+(disk[0-9]+)$/s//whole_\1/p" <<< "$disklist")" for PARTDRIVE in $(echo $DRIVELIST); do DRIVE=$(expr "$PARTDRIVE" : '.*_\([^_]*\)') DTYPE=$(expr "$PARTDRIVE" : '\(.*\)_[^_]*') echo "===============================================================================" @@ -259,12 +258,12 @@ do MOUNTPOINTS="" if [[ -n $INPUTSLICE ]]; then DEVLIST="$(echo "$diskutiloutput" | sed -n -E "/^.* (disk[0-9]+s${INPUTSLICE})$/s//\1/p")" else DEVLIST="$(echo "$diskutiloutput" | sed -n -E "/^.* (disk[0-9]+s[0-9]+)$/s//\1/p")" fi for THEDEV in $(echo $DEVLIST); do echo "---------------------------------------------" partinfo="$(diskutil info "$THEDEV")" echo "$partinfo" @@ -377,7 +376,7 @@ do PARTLIST="$(sed -nE "/^${INPUTSLICE}_/p" <<< "$PARTLIST")" fi for THEPART in $(echo $PARTLIST); do PNUM=$( expr "$THEPART" : '\([0-9]*\)_') PSTART=$( expr "$THEPART" : '[0-9]*_\([0-9]*\)_[0-9]*') PLENGTH=$(expr "$THEPART" : '[0-9]*_[0-9]*_\([0-9]*\)') @@ -409,19 +408,19 @@ do byteoffset=4; for (( i=0; i < numPatches; i++ )); do printf "%03x: PatchDescriptor[%d]:\n" "$byteoffset" "$i" patchSig=$(sed -E 's/(00)+$//' <<< "${blockbytes:$byteoffset*2:8}" | xxd -p -r | tr '\0' '.') majorVers=$((0x${blockbytes:$byteoffset*2+8:4})); minorVers=$((0x${blockbytes:$byteoffset*2+12:4})); flags=$((0x${blockbytes:$byteoffset*2+16:8})); patchOffset=$((0x${blockbytes:$byteoffset*2+24:8})); patchSize=$((0x${blockbytes:$byteoffset*2+32:8})); patchCRC=$((0x${blockbytes:$byteoffset*2+40:8})); patchDescriptorLen=$((0x${blockbytes:$byteoffset*2+48:8})); patchNameLen=$((0x${blockbytes:$byteoffset*2+56:2})); patchName=$(pascalstring "${blockbytes:$byteoffset*2+56:$patchNameLen*2+2}") patchVendorLen=$((0x${blockbytes:$byteoffset*2+122:2})); patchVendor=$(pascalstring "${blockbytes:$byteoffset*2+122:$patchVendorLen*2+2}") patchPad="${blockbytes:$byteoffset*2+124+$patchVendorLen*2:$patchDescriptorLen*2 - (124+$patchVendorLen*2)}" printf "%03x: patchSig : '%s'\n" $((byteoffset+ 0)) "$patchSig" printf "%03x: majorVers : %d\n" $((byteoffset+ 4)) "$majorVers" @@ -569,7 +568,7 @@ do echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): Boot Block Header contents" CODESTART=$((0x94)) printf "000: bbID : 'LK'\n" printf "002: bbEntry : 0x%08x" "$bbEntry" if (( (bbEntry & 0xffff0000) == 0x60000000 )); then CODESTART=$(((bbEntry & 0xffff) + 4)) @@ -893,7 +892,7 @@ do ((encodingsBitmap & (1<<38))) && printf ",MacRomanian" ((encodingsBitmap & (1<<48))) && printf ",MacUkrainian" ((encodingsBitmap & (1<<49))) && printf ",MacFarsi" ((encodingsBitmap & (0xfffcff81 << 32))) && printf ",0x%016x?" $((encodingsBitmap & (0xfffcff81 << 32))) ) printf "048: encodingsBitmap : 0x%016x = %s" "$encodingsBitmap" "${encodings:1}" } @@ -905,7 +904,7 @@ do printf "05c: Alternate OS blessed file/folder : %s\n" "$(inodestring "$DEVICEID" "$((0x${finderInfo:24: 8}))" )" dumpencoding "060: Text encoding :" "$((0x${finderInfo:32: 8}))" printf "064: OS X blessed folder : %s\n" "$(inodestring "$DEVICEID" "$((0x${finderInfo:40: 8}))" )" printf "068: 64-bit VSDB volume id : 0x%016X => Volume UUID: %s\n" $(((0x${finderInfo:48:8} << 32) | 0x${finderInfo:56:8} )) "$(vsdbtouuid "${finderInfo:48:16}")" printf "070: allocationFile : %s\n" "$(forkdatastring "$allocationFile" )" printf "0c0: extentsFile : %s\n" "$(forkdatastring "$extentsFile" )" printf "110: catalogFile : %s\n" "$(forkdatastring "$catalogFile" )" -
joevt revised this gist
May 20, 2023 . 1 changed file with 19 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ # # Get Partition Info from all disks # # Written by joevt updated May 20, 2023 # Patches marked "rgh" July, 2010, to dump information beyond the # four bios partitions # @@ -219,6 +219,22 @@ dumpencoding () { } } command -V python > /dev/null && python=python || python=python3 vsdbtouuid0 () { "$python" -c ' import uuid ; from hashlib import md5 kFSUUIDNamespaceSHA1 = uuid.UUID("b3e20f39-f292-11d6-97a4-00306543ecac") digest = md5(kFSUUIDNamespaceSHA1.bytes + bytes.fromhex("'"$1"'"), usedforsecurity=False).digest() print ("%s" % uuid.UUID(bytes=digest[:16], version=3)) ' } vsdbtouuid () { local theuuid="" theuuid=$(printf "b3e20f39f29211d697a400306543ecac%s" "$1" | xxd -p -r | md5 | tr "a-f" "A-F" ) printf "%s" "${theuuid:0:8}-${theuuid:8:4}-3${theuuid:13:3}-$(printf "%X" $(((0x${theuuid:16:1} & 3) | 8)))${theuuid:17:3}-${theuuid:20:12}" } (( ALLDISKS )) && echo "$disklist" echo "$apfslist" @@ -718,7 +734,7 @@ do printf "068: Alternate OS blessed file/folder : %s\n" "$(inodestring "$DEVICEID" "$((0x${drFndrInfo:24: 8}))" )" dumpencoding "06c: Text encoding :" "$((0x${drFndrInfo:32: 8}))" printf "070: OS X blessed folder : %s\n" "$(inodestring "$DEVICEID" "$((0x${drFndrInfo:40: 8}))" )" printf "074: 64-bit VSDB volume id : 0x%016X => Volume UUID: %s\n" $((0x${drFndrInfo:48:16})) "$(vsdbtouuid "${drFndrInfo:48:16}")" if (( drEmbedSigWord == 0x482b )); then printf "07c: drEmbedSigWord: %d = 'H+' = kHFSPlusSigWord\n" "$drEmbedSigWord" @@ -889,7 +905,7 @@ do printf "05c: Alternate OS blessed file/folder : %s\n" "$(inodestring "$DEVICEID" "$((0x${finderInfo:24: 8}))" )" dumpencoding "060: Text encoding :" "$((0x${finderInfo:32: 8}))" printf "064: OS X blessed folder : %s\n" "$(inodestring "$DEVICEID" "$((0x${finderInfo:40: 8}))" )" printf "068: 64-bit VSDB volume id : 0x%016X => Volume UUID: %s\n" $((0x${finderInfo:48:16})) "$(vsdbtouuid "${finderInfo:48:16}")" printf "070: allocationFile : %s\n" "$(forkdatastring "$allocationFile" )" printf "0c0: extentsFile : %s\n" "$(forkdatastring "$extentsFile" )" printf "110: catalogFile : %s\n" "$(forkdatastring "$catalogFile" )" -
joevt revised this gist
Dec 2, 2022 . 1 changed file with 870 additions and 86 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,8 +2,8 @@ # # Get Partition Info from all disks # # Written by joevt updated Dec 2, 2022 # Patches marked "rgh" July, 2010, to dump information beyond the # four bios partitions # # sudo ./dumpvols.sh > dumpvols_result.txt 2>&1 @@ -18,46 +18,66 @@ if [ ! "$USER" = "root" ]; then exit fi INPUTDISK="$1" INPUTSLICE=$(expr "$INPUTDISK" : 'disk[0-9]*s\([0-9]*\)') if [[ -n $INPUTDISK ]]; then disklist="$(diskutil list "$1" | perl -p -e 's|^/|\n/|')" apfslist="$(diskutil apfs list | sed -nE "/^\|/s// /; /^ $/s///; /\+.*$1 /,/^$/ { /^$/d ; p ; }" 2> /dev/null)" ALLDISKS=0 else disklist="$(diskutil list | perl -p -e 's|^/|\n/|')" apfslist="$(diskutil apfs list 2> /dev/null)" ALLDISKS=1 fi [[ "${apfslist:0:4}" == "Disk" ]] && apfslist="" MBRHASHES=" Windows_XP=d88d4f2dbc2c662db7d7d60ebf9e3e00 Windows_Vista=12c9d7ff4914c88a7f9eadf9211b861b Windows_7=118eb70c44cb69284e5d8aa93096831e None_all_zeros=4ebc676ce4896613a3a9df6e2a1c77ae MSDOS_or_FreeDOS_on_FreeDOS=93dd2ee87a995e36cbab0c2d5c2f041a Windows_XP_On_BootCamp2_with_AHCI_patch=c3fb54174bc479899d4ef6e45308dc18 Windows_XP_On_BootCamp2=cb4dabdd862da0508083b05814e198b8 Windows_Vista_on_XP_with_AHCI_patch=4979e1b9d70738759280f6962c2ad298 Windows_7_on_XP=7db43c1425e9ff3077dd62b776a50419 Windows_7_with_AHCI_patch=a243d3475531b0f6f0d7199043c2eb5c Windows_7_on_XP_with_AHCI_patch=24977c27865adec9ac8298f1a8d214bf Apple_Partition_Map_Block0_Driver_Descriptor_Map_390721968_blocks_and_Tiger_OS_9_drivers=087f35e49a39d52a46e3a94882869f51 " #All VBR hashes use all the bytes starting from offset 0x60. It may be better to use a different range for each type of VBR... # GRUB2 hash was incorrectly named GRUB #rgh # added GRUB hash from observation of kununtu 9.04 #rgh # added Windows 8 VBRHASHES=" None_all_zeros=acf496fff71230daa6985a701f83ce49 NTFS_No_Loader=3be27456483746abb85cd614381dac5e NTFS_Windows_XP_NTLDR=dd1728a59343b9fa9458d80657f68771 NTFS_Windows_Vista_BOOTMGR=d1c278b56eeea9536d0eb5898fe6a0b5 NTFS_Windows_8_BOOTMGR=771df8b803f96296854316d3d5918812 GRUB_from_Ubuntu=332469fa146db809f58d6392e2e0bdce GRUB2_from_Ubuntu=9c249066e1eb9c842d8acdfe6d23a2e3 FAT32_FRDOS4.1=98050815221ee147066f99f806c23203 FAT32_FRDOS4.1_or_MSWIN4.1_BOOTMGR=aec608de8ac709d91e6f3340b643ab4d FAT32_NTFS_NTLDR=d9c3d66e975d2b3b122353951a598b32 FAT12_BSD_4.4_BOOTMGR=4cc92970d5a3350bc72d2b975e28b915 FAT16_Non_system_disk=2a3d0f51ad246f115aa7d37891788857 FAT32_Non_system_disk_or_EFI=34f2d1f3c3ecce5c00cae8f0b82c922b HFS_boot_block_0=28f5bc1563fbaedeb8dabbd4ef9eb4c2 APM_Driver_SCSI_patch=44dc8729f17b4de891fc93d8db04e393 APM_Driver_SCSI_chained_real=f13d0837e944353d07121dcda47f01c0 APM_Driver_ATA_patch=e1dd2732d4f0cfc3f79357f1bae992c7 APM_Driver_ATA_chained_real=4ccc33e59537e50e7831fc499a8672a5 " # APM drivers created by Leopard Install Mac OS 9 Drivers FindHash () { # $1: name of hashed contents @@ -80,93 +100,857 @@ FindHash () { fi } pascalstring () { # $1 pascal string bytes local thebytes; local thechars; local thelen; thebytes="$1" thelen=$((0x${thebytes:0:2})) thechars=$(sed -E 's/(00)+$//' <<< "${thebytes:2}" | xxd -p -r | tr '\0' '.') if (( thelen != ${#thechars} )); then printf "len:%d? " "$thelen" fi printf "\"%s\"" "$thechars" } GetFileInfo="GetFileInfo" command -v GetFileInfo > /dev/null 2>&1 || { GetFileInfo="/Developer/Tools/GetFileInfo" } inodetopath () { "$GetFileInfo" -P "/.vol/$1/$2" 2> /dev/null | sed -nE '/^(file|directory): "(.*)"/s//\2/p' } inodestring () { local deviceid="$1" local inode="$2" local thepath; thepath="$(inodetopath "$deviceid" "$inode")" printf "%d" "$inode" [[ -n $thepath ]] && printf " => \"%s\"" "$thepath" } forkdatastring () { local forkdata="$1" local extentslist if [[ -n ${forkdata//0/} ]]; then extentslist=$( extents="${forkdata:32}" while [[ -n $extents ]]; do if ((0x${extents:0:16})); then printf "(%d,%d)," $((0x${extents:0:8})) $((0x${extents:8:8})) else printf "," fi extents="${extents:16}" done ) printf "logicalSize:%d clumpSize:%d totalBlocks:%d extents:(%s)" $((0x${forkdata:0:16})) $((0x${forkdata:16:8})) $((0x${forkdata:24:8})) "${extentslist%"${extentslist##*[!,]}"}" fi } extentstring () { extents="$1" extentslist=$( while [[ -n $extents ]]; do if ((0x${extents:0:16})); then printf "(%d,%d)," $((0x${extents:0:4})) $((0x${extents:4:4})) else printf "," fi extents="${extents:8}" done ) printf "(%s)" "${extentslist%"${extentslist##*[!,]}"}" } dumpencoding () { local message="$1" local encoding="$2" ((encoding)) && { printf "%s 0x%08x" "$message" "$encoding" (( (encoding & 0x656e6300) == 0x656e6300 )) && { case $((encoding & 0xff)) in 0) printf " = kTextEncodingMacRoman" ;; 1) printf " = kTextEncodingMacJapanese" ;; 2) printf " = kTextEncodingMacChineseTrad" ;; 3) printf " = kTextEncodingMacKorean" ;; 4) printf " = kTextEncodingMacArabic" ;; 5) printf " = kTextEncodingMacHebrew" ;; 6) printf " = kTextEncodingMacGreek" ;; 7) printf " = kTextEncodingMacCyrillic" ;; 9) printf " = kTextEncodingMacDevanagari" ;; 10) printf " = kTextEncodingMacGurmukhi" ;; 11) printf " = kTextEncodingMacGujarati" ;; 12) printf " = kTextEncodingMacOriya" ;; 13) printf " = kTextEncodingMacBengali" ;; 14) printf " = kTextEncodingMacTamil" ;; 15) printf " = kTextEncodingMacTelugu" ;; 16) printf " = kTextEncodingMacKannada" ;; 17) printf " = kTextEncodingMacMalayalam" ;; 18) printf " = kTextEncodingMacSinhalese" ;; 19) printf " = kTextEncodingMacBurmese" ;; 20) printf " = kTextEncodingMacKhmer" ;; 21) printf " = kTextEncodingMacThai" ;; 22) printf " = kTextEncodingMacLaotian" ;; 23) printf " = kTextEncodingMacGeorgian" ;; 24) printf " = kTextEncodingMacArmenian" ;; 25) printf " = kTextEncodingMacChineseSimp" ;; 26) printf " = kTextEncodingMacTibetan" ;; 27) printf " = kTextEncodingMacMongolian" ;; 28) printf " = kTextEncodingMacEthiopic" ;; 29) printf " = kTextEncodingMacCentralEurRoman" ;; 30) printf " = kTextEncodingMacVietnamese" ;; 31) printf " = kTextEncodingMacExtArabic" ;; 33) printf " = kTextEncodingMacSymbol" ;; 34) printf " = kTextEncodingMacDingbats" ;; 35) printf " = kTextEncodingMacTurkish" ;; 36) printf " = kTextEncodingMacCroatian" ;; 37) printf " = kTextEncodingMacIcelandic" ;; 38) printf " = kTextEncodingMacRomanian" ;; 39) printf " = kTextEncodingMacCeltic" ;; 40) printf " = kTextEncodingMacGaelic" ;; 41) printf " = kTextEncodingMacKeyboardGlyphs" ;; esac } printf "\n" } } (( ALLDISKS )) && echo "$disklist" echo "$apfslist" DRIVELIST=$(sed -n -E "/^[ ]*0: [ ]{0,25}([A-Za-z_]+)[ ]*\*[0-9.]+ [TGMK]B[ ]+(disk[0-9]+)$/s//\1_\2/p;/^[ ]*0: [ ]{0,26} .* \*[0-9.]+ [TGMK]B[ ]+(disk[0-9]+)$/s//whole_\1/p" <<< "$disklist") for PARTDRIVE in $DRIVELIST; do DRIVE=$(expr "$PARTDRIVE" : '.*_\([^_]*\)') DTYPE=$(expr "$PARTDRIVE" : '\(.*\)_[^_]*') echo "===============================================================================" diskutiloutput="$(sed -nE '/\/dev\/'"$DRIVE"'( |$)/,/^$/ p' <<< "${disklist}")" echo "$diskutiloutput" echo "---------------------------------------------" diskinfo="$(diskutil info "$DRIVE")" echo "$diskinfo" BLOCKSIZE=$(sed -nE '/^ *Device Block Size: +([0-9]+).*/s//\1/p' <<< "$diskinfo") if [[ -z $BLOCKSIZE ]]; then BLOCKSIZE=512 fi MOUNTPOINTS="" if [[ -n $INPUTSLICE ]]; then DEVLIST=$(echo "$diskutiloutput" | sed -n -E "/^.* (disk[0-9]+s${INPUTSLICE})$/s//\1/p") else DEVLIST=$(echo "$diskutiloutput" | sed -n -E "/^.* (disk[0-9]+s[0-9]+)$/s//\1/p") fi for THEDEV in $DEVLIST; do echo "---------------------------------------------" partinfo="$(diskutil info "$THEDEV")" echo "$partinfo" MOUNTPOINTS="${MOUNTPOINTS}${THEDEV}_$(sed -nE '/ *Mount Point: *(.*)/s//\1/p' <<< "$partinfo")"$'\n' done echo "---------------------------------------------" PARTLIST="" blockbytes=$(dd if="/dev/$DRIVE" bs=512 count=1 2> /dev/null | xxd -p -c 9999) if [ "$DTYPE" = "Apple_partition_scheme" ]; then pdiskoutput="$(pdisk -r -l "/dev/$DRIVE" 2>&1)" pdiskoutput2="$(pdisk -r -l -f "/dev/$DRIVE" 2>&1)" echo "$pdiskoutput" [[ "$pdiskoutput" != "$pdiskoutput2" ]] && echo "$pdiskoutput2" i=0 if [[ ${blockbytes:0:4} == "4552" ]]; then # 'ER' sbBlkSize=$((0x${blockbytes:4:4})) sbBlkCount=$((0x${blockbytes:8:8})) sbDevType=$((0x${blockbytes:16:4})) sbDevId=$((0x${blockbytes:20:4})) sbData=$((0x${blockbytes:24:8})) sbDrvrCount=$((0x${blockbytes:32:4})) echo echo "APM Block 0 contents" printf "000: sbSig : 'ER' = sbSIGWord\n" printf "002: sbBlkSize : %d\n" "$sbBlkSize" printf "004: sbBlkCount : %d = %d MB\n" "$sbBlkCount" $((sbBlkCount*sbBlkSize / 1000 / 1000)) ((sbDevType != 0)) && printf "008: sbDevType : %d\n" "$sbDevType" ((sbDevId != 0)) && printf "00a: sbDevId : %d\n" "$sbDevId" ((sbData != 0)) && printf "00c: sbData : %d\n" "$sbData" ((sbDrvrCount > 10)) && printf "010: sbDrvrCount: %d\n" "$sbDrvrCount" for ((i=0; i < sbDrvrCount; i++)); do ddBlock=$((0x${blockbytes:36+i*16:8})) ddSize=$((0x${blockbytes:44+i*16:4})) ddType=$((0x${blockbytes:48+i*16:4})) printf "%03x: DDMap[%d]:%4d @ %-4d 0x%04x = %-27s\n" $((0x012 + i*8)) "$i" "$ddSize" "$ddBlock" "$ddType" "$( { ((ddType == 0x0001)) && printf "kDriverTypeMacSCSI" ; } || { ((ddType == 0x0701)) && printf "kDriverTypeMacATA" ; } || { ((ddType == 0xFFFF)) && printf "kDriverTypeMacSCSIChained"; } || { ((ddType == 0xF8FF)) && printf "kDriverTypeMacATAChained" ; } || printf "?" )" done ddPad="${blockbytes:52+i*16}" [[ -n ${ddPad//0/} ]] && printf "ddPad: %s\n" "$ddPad" echo xxd -p -r <<< "$blockbytes" | xxd -c 16 else # use the same bytes as MBR hash even though Block0 contents are totally different HASH=$(xxd -p -r <<< "${blockbytes:0:440*2}" | xxd -p | md5) FindHash "Block0 contents" "$MBRHASHES" "$HASH" xxd -p -r <<< "$blockbytes" | xxd -c 16 fi PARTTYPE="APM" PARTLIST=$(echo "$pdiskoutput" | sed -nE "/ *[0-9]+: +Apple_Free /d; /[0-9]+: +[0-9]+ @ [0-9]+, type=0x/d; / *([0-9]+): +([^ ]+) .* ([0-9]+) @ ([0-9]+).*/s//\1_\4_\3_\2/p") elif [ "$DTYPE" = "GUID_partition_scheme" ] || [ "$DTYPE" = "FDisk_partition_scheme" ]; then gptoutput="$(gpt -r show "$DRIVE" 2>&1)" gptoutput2="$(gpt -r show -l "$DRIVE" 2>&1)" fdiskoutput="$(fdisk "/dev/r$DRIVE")" echo echo "$gptoutput" ! grep -q "illegal option -- l" <<< "$gptoutput2" && { echo echo "$gptoutput2" } echo echo "$fdiskoutput" HASH=$(xxd -p -r <<< "${blockbytes:0:440*2}" | xxd -p | md5) FindHash "MBR contents" "$MBRHASHES" "$HASH" xxd -p -r <<< "$blockbytes" | xxd -c 16 if [ "$DTYPE" = "FDisk_partition_scheme" ]; then PARTLIST=$(echo "$fdiskoutput" | sed -n -E "/^[ \*]+([0-9])\: ([0-9A-F]{2}) .*\[[ ]*([0-9]+) \-[ ]+([1-9][0-9]*)\].*$/s//\1_\3_\4_\2/p") PARTTYPE="MBR" else blockbytes=$(dd if="/dev/$DRIVE" bs="$BLOCKSIZE" skip=1 count=1 2> /dev/null | xxd -p -c 9999) HASH=$(xxd -p -r <<< "${blockbytes:96*2:416*2}" | xxd -p | md5) FindHash "GPT Header @ 1: GPT Header contents" "$VBRHASHES" "$HASH" xxd -p -r <<< "$blockbytes" | xxd -c 16 PARTLIST=$(echo "$gptoutput" | sed -n -E "/^[ ]+([0-9]+)[ ]+([0-9]+)[ ]+([0-9]+)[ ]+GPT part \- (.*)$/s//\3_\1_\2_\4/p") PARTTYPE="GPT" fi elif [ "$DTYPE" = "whole" ]; then HASH=$(xxd -p -r <<< "${blockbytes:0:416*2}" | xxd -p | md5) FindHash "0 @ 0: VBR contents" "$VBRHASHES" "$HASH" xxd -p -r <<< "$blockbytes" | xxd -c 16 else echo "Unknown partition scheme" fi if [[ -n $INPUTSLICE ]]; then PARTLIST="$(sed -nE "/^${INPUTSLICE}_/p" <<< "$PARTLIST")" fi for THEPART in $PARTLIST; do PNUM=$( expr "$THEPART" : '\([0-9]*\)_') PSTART=$( expr "$THEPART" : '[0-9]*_\([0-9]*\)_[0-9]*') PLENGTH=$(expr "$THEPART" : '[0-9]*_[0-9]*_\([0-9]*\)') PTYPE=$( expr "$THEPART" : '[0-9]*_[0-9]*_[0-9]*_\(.*\)') DEVICEID=$(stat -f "%r" "/dev/${DRIVE}s$PNUM") POFFSETS="_0" while [[ -n $POFFSETS ]]; do POFFSET=$( expr "$POFFSETS" : '_\([0-9]*\)') POFFSETS=$( expr "$POFFSETS" : '_[0-9]*\(_.*\)') if (( POFFSET >= PLENGTH )); then continue fi blockbytes=$(dd if="/dev/$DRIVE" bs="$BLOCKSIZE" skip=$((PSTART + POFFSET)) count=1 2> /dev/null | xxd -p -c 9999) if [[ $PTYPE = "Apple_Patches" ]]; then # Patches # https://developer.apple.com/library/archive/technotes/tn/tn1189.html#SecretsOfThePartitionMap echo echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): Driver Patches" numPatchBlocks=$((0x${blockbytes:0:4})) numPatches=$((0x${blockbytes:4:4})) printf "000: numPatchBlocks: %d\n" "$numPatchBlocks" byteoffset=4; for (( i=0; i < numPatches; i++ )); do printf "%03x: PatchDescriptor[%d]:\n" "$byteoffset" "$i" patchSig=$(sed -E 's/(00)+$//' <<< "${blockbytes:byteoffset*2:8}" | xxd -p -r | tr '\0' '.') majorVers=$((0x${blockbytes:byteoffset*2+8:4})); minorVers=$((0x${blockbytes:byteoffset*2+12:4})); flags=$((0x${blockbytes:byteoffset*2+16:8})); patchOffset=$((0x${blockbytes:byteoffset*2+24:8})); patchSize=$((0x${blockbytes:byteoffset*2+32:8})); patchCRC=$((0x${blockbytes:byteoffset*2+40:8})); patchDescriptorLen=$((0x${blockbytes:byteoffset*2+48:8})); patchName=$((0x${blockbytes:byteoffset*2+56:33*2})); patchVendorLen=$((0x${blockbytes:byteoffset*2+122:2})); patchVendor=$(pascalstring "${blockbytes:byteoffset*2+122:patchVendorLen*2+2}") patchPad="${blockbytes:byteoffset*2+124+patchVendorLen*2:patchDescriptorLen*2 - (124+patchVendorLen*2)}" printf "%03x: patchSig : '%s'\n" $((byteoffset+ 0)) "$patchSig" printf "%03x: majorVers : %d\n" $((byteoffset+ 4)) "$majorVers" printf "%03x: minorVers : %d\n" $((byteoffset+ 6)) "$minorVers" printf "%03x: flags : 0x%08x" $((byteoffset+ 8)) "$flags" if (( flags )); then flagtext=$( ((flags & 1)) && printf ",kRequiredPatch" ((flags & ~1)) && printf ",0x%08x?" $((flags & ~1)) ) printf " = %s" "${flagtext:1}" fi printf "\n" printf "%03x: patchOffset : %d\n" $((byteoffset+12)) "$patchOffset" printf "%03x: patchSize : %d\n" $((byteoffset+16)) "$patchSize" printf "%03x: patchCRC : 0x%08x\n" $((byteoffset+20)) "$patchCRC" printf "%03x: patchDescriptorLen : %d\n" $((byteoffset+24)) "$patchDescriptorLen" printf "%03x: patchName : %s\n" $((byteoffset+28)) "$patchName" printf "%03x: patchVendor : %s\n" $((byteoffset+61)) "$patchVendor" [[ -n $patchPad ]] && printf "%03x: patchPad : %s\n" $((byteoffset+62+patchVendorLen)) "$patchPad" ((byteoffset+=patchDescriptorLen)) done # for numPatches echo xxd -p -r <<< "$blockbytes" | xxd -c 16 elif [[ ${blockbytes:0:4} == "504d" ]]; then # 'PM' first_pmMapBlkCnt=$((0x${blockbytes:8:8})) echo echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): Partition Map contents (${first_pmMapBlkCnt} partitions)" for ((i=0;i<PLENGTH;i++)); do if (( i > 0 )); then blockbytes=$(dd if="/dev/$DRIVE" bs="$BLOCKSIZE" skip=$((PSTART + POFFSET + i)) count=1 2> /dev/null | xxd -p -c 9999) fi if [[ -n ${blockbytes//0/} ]]; then # Partition pmSig="${blockbytes:0:4}" pmSigPad=$((0x${blockbytes:4:4})) pmMapBlkCnt=$((0x${blockbytes:8:8})) pmPyPartStart=$((0x${blockbytes:16:8})) pmPartBlkCnt=$((0x${blockbytes:24:8})) pmPartName=$(sed -E 's/(00)+$//' <<< "${blockbytes:32:64}" | xxd -p -r | tr '\0' '.') pmParType=$(sed -E 's/(00)+$//' <<< "${blockbytes:96:64}" | xxd -p -r | tr '\0' '.') pmLgDataStart=$((0x${blockbytes:160:8})) pmDataCnt=$((0x${blockbytes:168:8})) pmPartStatus=$((0x${blockbytes:176:8})) pmLgBootStart=$((0x${blockbytes:184:8})) pmBootSize=$((0x${blockbytes:192:8})) pmBootAddr=$((0x${blockbytes:200:8})) pmBootAddr2=$((0x${blockbytes:208:8})) pmBootEntry=$((0x${blockbytes:216:8})) pmBootEntry2=$((0x${blockbytes:224:8})) pmBootCksum=$((0x${blockbytes:232:8})) pmProcessor=$(sed -E 's/(00)+$//' <<< "${blockbytes:240:32}" | xxd -p -r | tr '\0' '.') pmPad1="${blockbytes:272:256}" pmPad2=$(sed -E 's/(00)+$//' <<< "${blockbytes:528}") printf "%2d:" "$((i+1))" printf " %10d @ %-10d" \ "$pmPartBlkCnt" \ "$pmPyPartStart" [[ $pmSig != 504d ]] && printf " Sig:0x%s?" "$pmSig" [[ -n $pmParType ]] && printf " Type:\"%s\"" "$pmParType" [[ -n $pmPartName ]] && printf " Name:\"%s\"" "$pmPartName" (( pmSigPad )) && printf " SigPad:0x%04X" "$pmSigPad" (( pmMapBlkCnt != first_pmMapBlkCnt )) && printf " MapBlkCnt:%d" "$pmMapBlkCnt" (( pmLgDataStart )) && printf " LgDataStart:%d" "$pmLgDataStart" blockbytes2=${blockbytes:160} if [[ -n ${blockbytes2//0/} ]]; then (( pmDataCnt != pmPartBlkCnt )) && printf " DataCnt:%d" "$pmDataCnt" (( pmPartStatus )) && { statustext=$( (( pmPartStatus & 0x00000001 )) && printf ",Valid" # AUX (( pmPartStatus & 0x00000002 )) && printf ",Allocated" # AUX (( pmPartStatus & 0x00000004 )) && printf ",InUse" # AUX (( pmPartStatus & 0x00000008 )) && printf ",Bootable" # AUX (( pmPartStatus & 0x00000010 )) && printf ",Readable" # AUX (( pmPartStatus & 0x00000020 )) && printf ",Writeable" # AUX and Mac OS (( pmPartStatus & 0x00000040 )) && printf ",BootCodePositionIndependent" # AUX (( pmPartStatus & 0x00000080 )) && printf ",OSSpecific2" # ? (( pmPartStatus & 0x00000100 )) && printf ",ChainCompatible" # driver (( pmPartStatus & 0x00000200 )) && printf ",RealDeviceDriver" # driver (( pmPartStatus & 0x00000400 )) && printf ",CanChainToNext" # driver (( pmPartStatus & 0x40000000 )) && printf ",MountedAtStartup" # Mac OS (( pmPartStatus & 0x80000000 )) && printf ",Startup" # Mac OS (( pmPartStatus & 0x3FFFF800 )) && printf ",0x%x?" $((pmPartStatus & 0x3FFFF800)) ) printf " Status:%08X=%s" "$pmPartStatus" "${statustext:1}" } (( pmLgBootStart )) && printf " LgBootStart:%d" "$pmLgBootStart" (( pmBootSize )) && printf " BootSize:%d" "$pmBootSize" (( pmBootAddr )) && printf " BootAddr:0x%08X" "$pmBootAddr" (( pmBootAddr2 )) && printf " BootAddr2:0x%08X" "$pmBootAddr2" (( pmBootEntry )) && printf " BootEntry:0x%08X" "$pmBootEntry" (( pmBootEntry2 )) && printf " BootEntry2:0x%08X" "$pmBootEntry2" (( pmBootCksum )) && printf " BootCksum:0x%08X" "$pmBootCksum" [[ -n $pmProcessor ]] && printf " Processor:\"%s\"" "$pmProcessor" [[ -n ${pmPad1//0/} ]] && { printf " Pad1:%s" "$(sed -E 's/(00)+$//' <<< "${pmPad1}")" [ "${pmPad1:0:8}" = 70744452 ] && printf " = 'ptDR' = kPatchDriverSignature" [ "${pmPad1:0:8}" = 00010600 ] && printf "00 = kSCSIDriverSignature" [ "${pmPad1:0:8}" = 77696b69 ] && printf " = 'wiki' = kATADriverSignature" [ "${pmPad1:0:8}" = 43447672 ] && printf " = 'CDvr' = kSCSICDDriverSignature" [ "${pmPad1:0:8}" = 41545049 ] && printf " = 'ATPI' = kATAPIDriverSignature" [ "${pmPad1:0:8}" = 44535531 ] && printf " = 'DSU1' = kDriveSetupHFSSignature" } [[ -n $pmPad2 ]] && printf " Pad2:%s" "$pmPad2" fi printf "\n" fi done # for APM block elif [[ ${blockbytes:0:4} == "4c4b" ]]; then # 'LK' # Boot Blocks # https://developer.apple.com/library/archive/documentation/mac/pdf/Files/File_Manager.pdf # BootBlkHdr #bbID=$((0x${blockbytes:0:4})) bbEntry=$((0x${blockbytes:4:8})) bbVersion=$((0x${blockbytes:12:4})) bbPageFlags=$((0x${blockbytes:16:4})) bbSysName=$( pascalstring "${blockbytes:20:32}" ) bbShellName=$( pascalstring "${blockbytes:52:32}" ) bbDbg1Name=$( pascalstring "${blockbytes:84:32}" ) bbDbg2Name=$( pascalstring "${blockbytes:116:32}" ) bbScreenName=$(pascalstring "${blockbytes:148:32}" ) bbHelloName=$( pascalstring "${blockbytes:180:32}" ) bbScrapName=$( pascalstring "${blockbytes:212:32}" ) bbCntFCBs=$((0x${blockbytes:244:4})) bbCntEvts=$((0x${blockbytes:248:4})) bb128KSHeap=$((0x${blockbytes:252:8})) bb256KSHeap=$((0x${blockbytes:260:8})) bbSysHeapSize=$((0x${blockbytes:268:8})) filler=$((0x${blockbytes:276:4})) bbSysHeapExtra=$((0x${blockbytes:280:8})) bbSysHeapFract=$((0x${blockbytes:288:8})) echo echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): Boot Block Header contents" CODESTART=$((0x94)) printf "000: bbID : \'LK'\n" printf "002: bbEntry : 0x%08x" "$bbEntry" if (( (bbEntry & 0xffff0000) == 0x60000000 )); then CODESTART=$(((bbEntry & 0xffff) + 4)) printf " = BRA.S *+$%X to offset 0x%03x" $(( CODESTART - 2)) "$CODESTART" (( CODESTART - 2 == 0x8a )) && printf " (after old header)" (( CODESTART - 2 == 0x94 )) && printf " (after new header)" fi printf "\n" printf "006: bbVersion : 0x%04x" "$bbVersion" (( bbVersion )) && { printf " =" (( bbVersion & 0xff00 )) && { printf " flags:(" if (( bbVersion & 0x8000 )); then printf "new header" (( bbVersion & 0x4000 )) && printf ", execute boot code" (( bbVersion & 0x2000 )) && printf ", use relative system heap - bbSysHeapExtra and bbSysHeapFract instead of bbSysHeapSize" (( bbVersion & 0x1f00 )) && printf ", 0x%02x?" $(( (bbVersion & 0x1f00) >> 8 )) else printf "old header" (( bbVersion & 0x7f00 )) && printf ", 0x%02x?" $(( (bbVersion & 0x7f00) >> 8 )) fi printf ")" } (( bbVersion & 0xff )) && { (( bbVersion & 0xff00 )) && printf "," printf " version:%d.%d:(" $(( (bbVersion >> 4) & 15 )) $(( bbVersion & 15 )) (( (bbVersion & 0xff) < 0x15 )) && printf "ignore bb128KSHeap and bb256KSHeap and use default of bbSysHeapSize" (( (bbVersion & 0xff) >= 0x15 )) && printf "use bbSysHeapSize" # How is this different than < 0x15? the documentation for this is bad (( (bbVersion & 0xff) == 0xD )) && printf ", don't execute boot code" # I don't know if this is correct; the documentation for this is bad printf ")" } printf "\n" } ((bbPageFlags)) && { # https://developer.apple.com/library/archive/technotes/dv/dv_03.html#//apple_ref/doc/uid/DTS10002393 printf "008: bbPageFlags : 0x%04x =" "$bbPageFlags" if ((bbPageFlags & 0x8000)); then printf "allocate both video and sound buffers" else ((bbPageFlags > 0)) && printf "allocate only the secondary sound buffer" fi printf "\n" } printf "00a: bbSysName : %s\n" "$bbSysName" printf "01a: bbShellName : %s\n" "$bbShellName" printf "02a: bbDbg1Name : %s\n" "$bbDbg1Name" printf "03a: bbDbg2Name : %s\n" "$bbDbg2Name" printf "04a: bbScreenName : %s\n" "$bbScreenName" printf "05a: bbHelloName : %s\n" "$bbHelloName" printf "06a: bbScrapName : %s\n" "$bbScrapName" printf "07a: bbCntFCBs : %d\n" "$bbCntFCBs" printf "07c: bbCntEvts : %d\n" "$bbCntEvts" printf "07e: bb128KSHeap : %d\n" "$bb128KSHeap" printf "082: bb256KSHeap : %d\n" "$bb256KSHeap" printf "086: bbSysHeapSize : %d\n" "$bbSysHeapSize" ((CODESTART > 0x8a)) && printf "08a: filler : 0x%08x\n" "$filler" ((CODESTART > 0x8c)) && printf "08c: bbSysHeapExtra: 0x%08x\n" "$bbSysHeapExtra" ((CODESTART > 0x90)) && printf "090: bbSysHeapFract: 0x%08x\n" "$bbSysHeapFract" printf "%03x: boot code\n" "$CODESTART" echo xxd -p -r <<< "$blockbytes" | xxd -c 16 ((POFFSET++)) blockbytes=$(dd if="/dev/$DRIVE" bs="$BLOCKSIZE" skip=$((PSTART + POFFSET)) count=1 2> /dev/null | xxd -p -c 9999) echo echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): 2nd Boot Block contents" xxd -p -r <<< "$blockbytes" | xxd -c 16 ((POFFSET++)) POFFSETS="_${POFFSET}${POFFSETS}" #printf "queued first MDB after boot blocks: $POFFSETS\n" elif [[ ${blockbytes:0:4} == "4244" ]]; then # 'BD' # Master Directory Blocks # https://developer.apple.com/library/archive/documentation/mac/pdf/Files/File_Manager.pdf # MDB #drSigWord=${blockbytes:0x000*2:4} drCrDate=$((0x${blockbytes:0x002*2:8})) drLsMod=$((0x${blockbytes:0x006*2:8})) drAtrb=$((0x${blockbytes:0x00a*2:4})) drNmFls=$((0x${blockbytes:0x00c*2:4})) drVBMSt=$((0x${blockbytes:0x00e*2:4})) drAllocPtr=$((0x${blockbytes:0x010*2:4})) drNmAlBlks=$((0x${blockbytes:0x012*2:4})) drAlBlkSiz=$((0x${blockbytes:0x014*2:8})) drClpSiz=$((0x${blockbytes:0x018*2:8})) drAlBlSt=$((0x${blockbytes:0x01c*2:4})) drNxtCNID=$((0x${blockbytes:0x01e*2:8})) drFreeBks=$((0x${blockbytes:0x022*2:4})) drVN="$(pascalstring "${blockbytes:0x024*2:28*2}")" drVolBkUp=$((0x${blockbytes:0x040*2:8})) drVSeqNum=$((0x${blockbytes:0x044*2:4})) drWrCnt=$((0x${blockbytes:0x046*2:8})) drXTClpSiz=$((0x${blockbytes:0x04a*2:8})) drCTClpSiz=$((0x${blockbytes:0x04e*2:8})) drNmRtDirs=$((0x${blockbytes:0x052*2:4})) drFilCnt=$((0x${blockbytes:0x054*2:8})) drDirCnt=$((0x${blockbytes:0x058*2:8})) drFndrInfo="${blockbytes:0x05c*2:64}" drVCSize=$((0x${blockbytes:0x07c*2:4})) drVBMCSize=$((0x${blockbytes:0x07e*2:4})) drCtlCSize=$((0x${blockbytes:0x080*2:4})) drEmbedSigWord="$drVCSize" drEmbedExtent_startBlock="$drVBMCSize" drEmbedExtent_blockCount="$drCtlCSize" drXTFlSize=$((0x${blockbytes:0x082*2:8})) drXTExtRec="${blockbytes:0x086*2:24}" drCTFlSize=$((0x${blockbytes:0x092*2:8})) drCTExtRec="${blockbytes:0x096*2:24}" echo echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): Master Directory Block contents" printf "000: drSigWord : 'BD' = kHFSSigWord\n" printf "002: drCrDate : %s\n" "$( ((drCrDate)) && date -r $((drCrDate-2082844800)))" printf "006: drLsMod : %s\n" "$( ((drLsMod )) && date -r $((drLsMod -2082844800)))" ((drAtrb)) && { attributestext=$( ((drAtrb & 0x0080)) && printf ",VolumeHardwareLock" ((drAtrb & 0x0100)) && printf ",VolumeUnmounted" ((drAtrb & 0x0200)) && printf ",VolumeSparedBlocks" ((drAtrb & 0x0400)) && printf ",VolumeNoCacheRequired" ((drAtrb & 0x0800)) && printf ",BootVolumeInconsistent" ((drAtrb & 0x1000)) && printf ",CatalogNodeIDsReused" ((drAtrb & 0x2000)) && printf ",VolumeJournaled" ((drAtrb & 0x4000)) && printf ",VolumeInconsistent" ((drAtrb & 0x8000)) && printf ",VolumeSoftwareLock" ((drAtrb & 0x007f)) && printf ",0x%04x?" $((drAtrb & 0x007f)) ) printf "00a: drAtrb : 0x%04x = %s\n" "$drAtrb" "${attributestext:1}" } printf "00c: drNmFls : %d\n" "$drNmFls" printf "00e: drVBMSt : %d\n" "$drVBMSt" printf "010: drAllocPtr : %d\n" "$drAllocPtr" printf "012: drNmAlBlks : %d\n" "$drNmAlBlks" printf "014: drAlBlkSiz : %d\n" "$drAlBlkSiz" printf "018: drClpSiz : %d\n" "$drClpSiz" printf "01c: drAlBlSt : %d\n" "$drAlBlSt" printf "01e: drNxtCNID : %d\n" "$drNxtCNID" printf "022: drFreeBks : %d\n" "$drFreeBks" printf "024: drVN : %s\n" "$drVN" printf "040: drVolBkUp : %s\n" "$( ((drVolBkUp)) && date -r $((drVolBkUp-2082844800)))" printf "044: drVSeqNum : %d\n" "$drVSeqNum" printf "046: drWrCnt : %d\n" "$drWrCnt" printf "04a: drXTClpSiz : %d\n" "$drXTClpSiz" printf "04e: drCTClpSiz : %d\n" "$drCTClpSiz" printf "052: drNmRtDirs : %d\n" "$drNmRtDirs" printf "054: drFilCnt : %d\n" "$drFilCnt" printf "058: drDirCnt : %d\n" "$drDirCnt" printf "05c: drFndrInfo:\n" printf "05c: Blessed System Folder : %s\n" "$(inodestring "$DEVICEID" "$((0x${drFndrInfo: 0: 8}))" )" printf "060: Blessed System File : %s\n" "$(inodestring "$DEVICEID" "$((0x${drFndrInfo: 8: 8}))" )" printf "064: Open-folder linked list : %s\n" "$(inodestring "$DEVICEID" "$((0x${drFndrInfo:16: 8}))" )" printf "068: Alternate OS blessed file/folder : %s\n" "$(inodestring "$DEVICEID" "$((0x${drFndrInfo:24: 8}))" )" dumpencoding "06c: Text encoding :" "$((0x${drFndrInfo:32: 8}))" printf "070: OS X blessed folder : %s\n" "$(inodestring "$DEVICEID" "$((0x${drFndrInfo:40: 8}))" )" printf "074: 64-bit VSDB volume id : 0x%016X\n" $((0x${drFndrInfo:48:16})) if (( drEmbedSigWord == 0x482b )); then printf "07c: drEmbedSigWord: %d = 'H+' = kHFSPlusSigWord\n" "$drEmbedSigWord" printf "07e: drEmbedExtent.startBlock : %d\n" "$drEmbedExtent_startBlock" printf "080: drEmbedExtent.blockCount : %d\n" "$drEmbedExtent_blockCount" else printf "07c: drVCSize : %d\n" "$drVCSize" printf "07e: drVBMCSize : %d\n" "$drVBMCSize" printf "080: drCtlCSize : %d\n" "$drCtlCSize" fi printf "082: drXTFlSize : %d\n" "$drXTFlSize" printf "086: drXTExtRec : %s\n" "$(extentstring "$drXTExtRec")" printf "092: drCTFlSize : %d\n" "$drCTFlSize" printf "096: drCTExtRec : %s\n" "$(extentstring "$drCTExtRec")" echo xxd -p -r <<< "$blockbytes" | xxd -c 16 if ((POFFSET < drNmAlBlks * (drAlBlkSiz / 512) - 2)); then # queue up location of alternate Master Directory Block POFFSETS="_$((PLENGTH-2))_$((PLENGTH-1))${POFFSETS}" #printf "queued 2alternate MDB: $POFFSETS \n" if (( drEmbedSigWord == 0x482b )); then # queue up location of wrapped HFS+ partition hfsplusblock=$(( drAlBlSt + drEmbedExtent_startBlock * (drAlBlkSiz / 512) )) POFFSETS="${POFFSETS}_$((hfsplusblock))_$((hfsplusblock+1))_$((hfsplusblock+2))" #printf "queued 3wrapped: $POFFSETS \n" fi fi elif [[ ${blockbytes:0:4} == "482b" ]] || [[ ${blockbytes:0:4} == "4858" ]]; then # 'H+' or 'HX' # Master Directory Blocks # https://developer.apple.com/library/archive/documentation/mac/pdf/Files/File_Manager.pdf # HFS Plus Volume Header signature=$((0x${blockbytes:0x000*2:4})) signatureChars=$(sed -E 's/(00)+$//' <<< "${blockbytes:0x000*2:4}" | xxd -p -r | tr '\0' '.') version=$((0x${blockbytes:0x002*2:4})) attributes=$((0x${blockbytes:0x004*2:8})) lastMountedVersion=$((0x${blockbytes:0x008*2:8})) lastMountedVersionChars=$(sed -E 's/(00)+$//' <<< "${blockbytes:0x008*2:8}" | xxd -p -r | tr '\0' '.') journalInfoBlock=$((0x${blockbytes:0x00c*2:8})) createDate=$((0x${blockbytes:0x010*2:8})) modifyDate=$((0x${blockbytes:0x014*2:8})) backupDate=$((0x${blockbytes:0x018*2:8})) checkedDate=$((0x${blockbytes:0x01c*2:8})) fileCount=$((0x${blockbytes:0x020*2:8})) folderCount=$((0x${blockbytes:0x024*2:8})) blockSize=$((0x${blockbytes:0x028*2:8})) totalBlocks=$((0x${blockbytes:0x02c*2:8})) freeBlocks=$((0x${blockbytes:0x030*2:8})) nextAllocation=$((0x${blockbytes:0x034*2:8})) rsrcClumpSize=$((0x${blockbytes:0x038*2:8})) dataClumpSize=$((0x${blockbytes:0x03c*2:8})) nextCatalogID=$((0x${blockbytes:0x040*2:8})) writeCount=$((0x${blockbytes:0x044*2:8})) encodingsBitmap=$((0x${blockbytes:0x048*2:16})) finderInfo="${blockbytes:0x050*2:64}" allocationFile="${blockbytes:0x070*2:160}" extentsFile="${blockbytes:0x0c0*2:160}" catalogFile="${blockbytes:0x110*2:160}" attributesFile="${blockbytes:0x160*2:160}" startupFile="${blockbytes:0x1b0*2:160}" echo echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): HFS Plus Volume Header contents" printf "000: signature : '%s'" "$signatureChars" ((signature == 0x482b )) && printf " = kHFSPlusSigWord" ((signature == 0x4858 )) && printf " = kHFSXSigWord" printf "\n" printf "002: version : %d" "$version" ((version == 4 )) && printf " = kHFSPlusVersion" ((version == 5 )) && printf " = kHFSXVersion" printf "\n" ((attributes)) && { attributestext=$( ((attributes & 0x00000080)) && printf ",VolumeHardwareLock" ((attributes & 0x00000100)) && printf ",VolumeUnmounted" ((attributes & 0x00000200)) && printf ",VolumeSparedBlocks" ((attributes & 0x00000400)) && printf ",VolumeNoCacheRequired" ((attributes & 0x00000800)) && printf ",BootVolumeInconsistent" ((attributes & 0x00001000)) && printf ",CatalogNodeIDsReused" ((attributes & 0x00002000)) && printf ",VolumeJournaled" ((attributes & 0x00004000)) && printf ",VolumeInconsistent" ((attributes & 0x00008000)) && printf ",VolumeSoftwareLock" ((attributes & 0x40000000)) && printf ",ContentProtection" ((attributes & 0x80000000)) && printf ",UnusedNodeFix" ((attributes & 0x3fff007f)) && printf ",0x%08x?" $((drAtrb & 0x3fff007f)) ) printf "004: attributes : 0x%08x = %s\n" "$attributes" "${attributestext:1}" } printf "008: lastMountedVersion : 0x%08x = '%s'" "$lastMountedVersion" "$lastMountedVersionChars" ((lastMountedVersion == 0x31302E30 )) && printf " = kHFSPlusMountVersion" # '10.0'; (Mac OS 8.1 to 9.2.2 is '8.10') ((lastMountedVersion == 0x4846534a )) && printf " = kHFSJMountVersion" ((lastMountedVersion == 0x46534b21 )) && printf " = kFSKMountVersion" printf "\n" ((journalInfoBlock || (attributes & 0x00002000) )) && printf "00c: journalInfoBlock : %d\n" "$journalInfoBlock" printf "010: createDate : %s\n" "$( ((createDate )) && date -r $((createDate -2082844800)))" printf "014: modifyDate : %s\n" "$( ((modifyDate )) && date -r $((modifyDate -2082844800)))" printf "018: backupDate : %s\n" "$( ((backupDate )) && date -r $((backupDate -2082844800)))" printf "01c: checkedDate : %s\n" "$( ((checkedDate)) && date -r $((checkedDate-2082844800)))" printf "020: fileCount : %d\n" "$fileCount" printf "024: folderCount : %d\n" "$folderCount" printf "028: blockSize : %d\n" "$blockSize" printf "02c: totalBlocks : %d\n" "$totalBlocks" printf "030: freeBlocks : %d\n" "$freeBlocks" printf "034: nextAllocation : %d\n" "$nextAllocation" printf "038: rsrcClumpSize : %d\n" "$rsrcClumpSize" printf "03c: dataClumpSize : %d\n" "$dataClumpSize" printf "040: nextCatalogID : %d\n" "$nextCatalogID" printf "044: writeCount : %d\n" "$writeCount" ((encodingsBitmap)) && { encodings=$( ((encodingsBitmap & (1<< 0))) && printf ",MacRoman" ((encodingsBitmap & (1<< 1))) && printf ",MacJapanese" ((encodingsBitmap & (1<< 2))) && printf ",MacChineseTrad" ((encodingsBitmap & (1<< 3))) && printf ",MacKorean" ((encodingsBitmap & (1<< 4))) && printf ",MacArabic" ((encodingsBitmap & (1<< 5))) && printf ",MacHebrew" ((encodingsBitmap & (1<< 6))) && printf ",MacGreek" ((encodingsBitmap & (1<< 7))) && printf ",MacCyrillic" ((encodingsBitmap & (1<< 9))) && printf ",MacDevanagari" ((encodingsBitmap & (1<<10))) && printf ",MacGurmukhi" ((encodingsBitmap & (1<<11))) && printf ",MacGujarati" ((encodingsBitmap & (1<<12))) && printf ",MacOriya" ((encodingsBitmap & (1<<13))) && printf ",MacBengali" ((encodingsBitmap & (1<<14))) && printf ",MacTamil" ((encodingsBitmap & (1<<15))) && printf ",MacTelugu" ((encodingsBitmap & (1<<16))) && printf ",MacKannada" ((encodingsBitmap & (1<<17))) && printf ",MacMalayalam" ((encodingsBitmap & (1<<18))) && printf ",MacSinhalese" ((encodingsBitmap & (1<<19))) && printf ",MacBurmese" ((encodingsBitmap & (1<<20))) && printf ",MacKhmer" ((encodingsBitmap & (1<<21))) && printf ",MacThai" ((encodingsBitmap & (1<<22))) && printf ",MacLaotian" ((encodingsBitmap & (1<<23))) && printf ",MacGeorgian" ((encodingsBitmap & (1<<24))) && printf ",MacArmenian" ((encodingsBitmap & (1<<25))) && printf ",MacChineseSimp" ((encodingsBitmap & (1<<26))) && printf ",MacTibetan" ((encodingsBitmap & (1<<27))) && printf ",MacMongolian" ((encodingsBitmap & (1<<28))) && printf ",MacEthiopic" ((encodingsBitmap & (1<<29))) && printf ",MacCentralEurRoman" ((encodingsBitmap & (1<<30))) && printf ",MacVietnamese" ((encodingsBitmap & (1<<31))) && printf ",MacExtArabic" ((encodingsBitmap & (1<<33))) && printf ",MacSymbol" ((encodingsBitmap & (1<<34))) && printf ",MacDingbats" ((encodingsBitmap & (1<<35))) && printf ",MacTurkish" ((encodingsBitmap & (1<<36))) && printf ",MacCroatian" ((encodingsBitmap & (1<<37))) && printf ",MacIcelandic" ((encodingsBitmap & (1<<38))) && printf ",MacRomanian" ((encodingsBitmap & (1<<48))) && printf ",MacUkrainian" ((encodingsBitmap & (1<<49))) && printf ",MacFarsi" ((encodingsBitmap & 0xfffcff8100000000)) && printf ",0x%016x?" $((encodingsBitmap & 0xfffcff8100000000)) ) printf "048: encodingsBitmap : 0x%016x = %s" "$encodingsBitmap" "${encodings:1}" } printf "\n" printf "050: finderInfo:\n" printf "050: Blessed System Folder : %s\n" "$(inodestring "$DEVICEID" "$((0x${finderInfo: 0: 8}))" )" printf "054: Blessed System File : %s\n" "$(inodestring "$DEVICEID" "$((0x${finderInfo: 8: 8}))" )" printf "058: Open-folder linked list : %s\n" "$(inodestring "$DEVICEID" "$((0x${finderInfo:16: 8}))" )" printf "05c: Alternate OS blessed file/folder : %s\n" "$(inodestring "$DEVICEID" "$((0x${finderInfo:24: 8}))" )" dumpencoding "060: Text encoding :" "$((0x${finderInfo:32: 8}))" printf "064: OS X blessed folder : %s\n" "$(inodestring "$DEVICEID" "$((0x${finderInfo:40: 8}))" )" printf "068: 64-bit VSDB volume id : 0x%016X\n" $((0x${finderInfo:48:16})) printf "070: allocationFile : %s\n" "$(forkdatastring "$allocationFile" )" printf "0c0: extentsFile : %s\n" "$(forkdatastring "$extentsFile" )" printf "110: catalogFile : %s\n" "$(forkdatastring "$catalogFile" )" printf "160: attributesFile : %s\n" "$(forkdatastring "$attributesFile" )" printf "1b0: startupFile : %s\n" "$(forkdatastring "$startupFile" )" echo xxd -p -r <<< "$blockbytes" | xxd -c 16 if ((POFFSET < PLENGTH-4)); then # queue up location of alternate HFS Plus Volume Header # HFS+ volume starts at POFFSET - 2 endoffset=$((POFFSET - 2 + totalBlocks * (blockSize / 512))) POFFSETS="_$((endoffset - 2))_$((endoffset - 1))${POFFSETS}" #printf "queued alternate HFS+ Header: $POFFSETS\n" fi else if (( 0x${blockbytes:0x20*2:8} == 0x4e585342 )); then # 'NXSB' echo echo "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): APFS Container contents" else HASH=$(xxd -p -r <<< "${blockbytes:96*2:416*2}" | xxd -p | md5) FindHash "$PARTTYPE $PNUM @ ${PSTART}$( ((POFFSET > 0)) && printf "+%d" "$POFFSET" ): $( ((POFFSET==0)) && printf "VBR " )contents" "$VBRHASHES" "$HASH" fi if [[ -n ${blockbytes//0/} ]]; then xxd -p -r <<< "$blockbytes" | xxd -c 16 POFFSETS="" elif [[ -z $POFFSETS ]] && (( POFFSET < 2 )); then POFFSETS="_$((POFFSET+1))" #printf "queued after zero block: $POFFSETS\n" fi fi done # while POFFSETS done # while THEPART done #exit if [[ -n $INPUTDISK ]]; then echo "===============================================================================" ioreg -w 0 -c IOMedia | sed -n -E "/^[ \|]*\+\-o (.*) <class IOMedia[^a-zA-Z]/,/^[ \|]+ }$/p" | { sed -n -E "/^[ \|]*\+\-o (.*)/s//\1/p;/^[ \|]* \| (.*)/s//\1/p;" } | { perl -0777 -nE 'while (/(^.*? <class IOMedia.*\n\{\n( .*\n)*^ "BSD Name" = "('"$INPUTDISK"'[^\d]|'"${INPUTDISK/s[0-9]*/}"'").*\n( .*\n)*?^}\n)/mg) { printf "$1\n" }' } echo "===============================================================================" else echo "===============================================================================" ioreg -w 0 -c IOMedia | sed -n -E "/^[ \|]*\+\-o (.*) <class IOMedia[^a-zA-Z]/,/^[ \|]+ }$/p" | sed -n -E "/^[ \|]*\+\-o (.*)/s//\1/p;/^[ \|]* \| (.*)/s//\1/p;" echo "===============================================================================" bless --verbose --getBoot echo "===============================================================================" bless --verbose --info echo "===============================================================================" #ioreg -rw 0 -n AppleEFINVRAM 2> /dev/null | sed -n -E "/^[ \|]+[ ]+(\".*)$/s//\1/p;" ioreg -lw0 -p IODeviceTree 2> /dev/null | sed -nE '/o chosen/,/}$/p ; /o option/,/}$/p ; /o aliases/,/}$/p ' | sed -nE "/^[ \|]+[ ]+(\".*)$/s// \1/p; / +\+\-o (.*) +<class ([^,]+).*/s//\1 <\2>/p" echo "===============================================================================" fi -
joevt created this gist
Jan 16, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,172 @@ #!/bin/bash # # Get Partition Info from all disks # # Written by joevt updated Dec 29. 2020 # Patches marked "rgh" July, 2010, to dump information beyond the # four bios partitions # # sudo ./dumpvols.sh > dumpvols_result.txt 2>&1 # # Based on johnsock's AHCI Master Boot Record Patch. # # This script is freely distributable. # if [ ! "$USER" = "root" ]; then echo WARNING: This script must be run as root. exit fi MBRHASHES=\ "Windows_XP=d88d4f2dbc2c662db7d7d60ebf9e3e00 "\ "Windows_Vista=12c9d7ff4914c88a7f9eadf9211b861b "\ "Windows_7=118eb70c44cb69284e5d8aa93096831e "\ "None_all_zeros=4ebc676ce4896613a3a9df6e2a1c77ae "\ ""\ "MSDOS_or_FreeDOS_on_FreeDOS=93dd2ee87a995e36cbab0c2d5c2f041a "\ ""\ "Windows_XP_On_BootCamp2_with_AHCI_patch=c3fb54174bc479899d4ef6e45308dc18 "\ "Windows_XP_On_BootCamp2=cb4dabdd862da0508083b05814e198b8 "\ "Windows_Vista_on_XP_with_AHCI_patch=4979e1b9d70738759280f6962c2ad298 "\ "Windows_7_on_XP=7db43c1425e9ff3077dd62b776a50419 "\ "Windows_7_with_AHCI_patch=a243d3475531b0f6f0d7199043c2eb5c "\ "Windows_7_on_XP_with_AHCI_patch=24977c27865adec9ac8298f1a8d214bf "\ ""\ "Apple_Partition_Map_Block0_Driver_Descriptor_Map_390721968_blocks_and_Tiger_OS_9_drivers=087f35e49a39d52a46e3a94882869f51 "\ "" #All VBR hashes use all the bytes starting from offset 0x60. It may be better to use a different range for each type of VBR... # GRUB2 hash was incorrectly named GRUB #rgh # added GRUB hash from observation of kununtu 9.04 #rgh # added Windows 8 VBRHASHES=\ "None_all_zeros=acf496fff71230daa6985a701f83ce49 "\ "NTFS_No_Loader=3be27456483746abb85cd614381dac5e "\ "NTFS_Windows_XP_NTLDR=dd1728a59343b9fa9458d80657f68771 "\ "NTFS_Windows_Vista_BOOTMGR=d1c278b56eeea9536d0eb5898fe6a0b5 "\ "NTFS_Windows_8_BOOTMGR=771df8b803f96296854316d3d5918812 "\ "GRUB_from_Ubuntu=332469fa146db809f58d6392e2e0bdce "\ "GRUB2_from_Ubuntu=9c249066e1eb9c842d8acdfe6d23a2e3 "\ "FAT32_FRDOS4.1=98050815221ee147066f99f806c23203 "\ "FAT32_FRDOS4.1_or_MSWIN4.1_BOOTMGR=aec608de8ac709d91e6f3340b643ab4d "\ "FAT32_NTFS_NTLDR=d9c3d66e975d2b3b122353951a598b32 "\ "FAT12_BSD_4.4_BOOTMGR=4cc92970d5a3350bc72d2b975e28b915 "\ "FAT16_Non_system_disk=2a3d0f51ad246f115aa7d37891788857 "\ "FAT32_Non_system_disk_or_EFI=34f2d1f3c3ecce5c00cae8f0b82c922b "\ "HFS_boot_block_0=28f5bc1563fbaedeb8dabbd4ef9eb4c2 "\ "" FindHash () { # $1: name of hashed contents # $2: list of known hashes # $3: the hash to search for DIDFIND=0 for CURHASH in $2; do THEHASH=$(expr "$CURHASH" : '[^=]*=\(.*\)') THEOS=$(expr "$CURHASH" : '^\([^=]*\)=') if [ "$3" = "$THEHASH" ]; then DIDFIND=1 break fi done echo "" if [ $DIDFIND = 1 ]; then echo "$1: $THEOS" else echo "$1: Unrecognized (hash=$3)" fi } disklist="$(diskutil list)" echo "$disklist" echo diskutil apfs list DRIVELIST=$(sed -n -E "/^[ ]*0: [ ]{0,25}([A-Za-z_]+)[ ]*\*[0-9.]+ [TGMK]B[ ]+(disk[0-9]+)$/s//\1_\2/p;/^[ ]*0: [ ]{0,26} .* \*[0-9.]+ [TGMK]B[ ]+(disk[0-9]+)$/s//whole_\1/p" <<< "$disklist") for PARTDRIVE in $DRIVELIST; do DRIVE=$(expr "$PARTDRIVE" : '.*_\([^_]*\)') PTYPE=$(expr "$PARTDRIVE" : '\(.*\)_[^_]*') echo "===============================================================================" diskutiloutput="$(sed -nE '/\/dev\/'$DRIVE' /,/^$/ p' <<< "${disklist}")" echo "$diskutiloutput" echo "---------------------------------------------" diskinfo="$(diskutil info $DRIVE)" echo "$diskinfo" echo BLOCKSIZE=$(sed -nE '/^ *Device Block Size: +([0-9]+).*/s//\1/p' <<< "$diskinfo") if [[ -z $BLOCKSIZE ]]; then BLOCKSIZE=512 fi DEVLIST=$(echo "$diskutiloutput" | sed -n -E "/^.* (disk[0-9]+s[0-9]+)$/s//\1/p") for THEDEV in $DEVLIST; do echo "---------------------------------------------" diskutil info $THEDEV done if [ "$PTYPE" = "Apple_partition_scheme" ]; then pdisk -r -l "/dev/$DRIVE" pdisk -r -l -f "/dev/$DRIVE" # use the same bytes as MBR hash even though Block0 contents are totally different HASH=$(dd if="/dev/$DRIVE" bs=1 count=446 2> /dev/null | xxd -p -l 440 | md5) FindHash "Block0 contents" "$MBRHASHES" "$HASH" dd if="/dev/$DRIVE" bs=1 count=512 2> /dev/null | xxd -c 16 elif [ "$PTYPE" = "GUID_partition_scheme" -o "$PTYPE" = "FDisk_partition_scheme" ]; then gptoutput="$(gpt -r show $DRIVE 2>&1)" gptoutput2="$(gpt -r show -l $DRIVE 2>&1)" fdiskoutput="$(fdisk /dev/r$DRIVE)" echo "$gptoutput" echo "$gptoutput2" echo "$fdiskoutput" HASH=$(dd if="/dev/$DRIVE" bs=1 count=446 2> /dev/null | xxd -p -l 440 | md5) FindHash "MBR contents" "$MBRHASHES" "$HASH" dd if="/dev/$DRIVE" bs=1 count=512 2> /dev/null | xxd -c 16 if [ "$PTYPE" = "FDisk_partition_scheme" ]; then PARTLIST=$(echo "$fdiskoutput" | sed -n -E "/^[ \*]+([0-9])\: .*\[[ ]*([0-9]+) \-[ ]+([1-9][0-9]*)\].*$/s//\1_\2_\3/p") PARTTYPE="MBR" else HASH=$(dd if="/dev/$DRIVE" bs=1 skip=$((BLOCKSIZE + 96)) count=416 2> /dev/null | xxd -p -l 440 | md5) FindHash "GPT Header @ 1: GPT Header contents" "$VBRHASHES" "$HASH" dd if="/dev/$DRIVE" bs=1 skip=$BLOCKSIZE count=$BLOCKSIZE 2> /dev/null | xxd -c 16 PARTLIST=$(echo "$gptoutput" | sed -n -E "/^[ ]+([0-9]+)[ ]+([0-9]+)[ ]+([0-9]+)[ ]+GPT part \-.*$/s//\3_\1_\2/p") PARTTYPE="GPT" fi for THEPART in $PARTLIST; do PNUM=$(expr "$THEPART" : '\([0-9]*\)_') PSTART=$(expr "$THEPART" : '[0-9]*_\([0-9]*\)_[0-9]*') PLENGTH=$(expr "$THEPART" : '[0-9]*_[0-9]*_\([0-9]*\)') HASH=$(dd if="/dev/$DRIVE" bs=1 skip=$((PSTART * BLOCKSIZE + 96)) count=416 2> /dev/null | xxd -p -l 440 | md5) FindHash "$PARTTYPE $PNUM @ $PSTART: VBR contents" "$VBRHASHES" "$HASH" dd if="/dev/$DRIVE" bs=1 skip=$((PSTART * BLOCKSIZE)) count=$BLOCKSIZE 2> /dev/null | xxd -c 16 done elif [ "$PTYPE" = "whole" ]; then HASH=$(dd if="/dev/$DRIVE" bs=1 count=416 2> /dev/null | xxd -p -l 440 | md5) FindHash "0 @ 0: VBR contents" "$VBRHASHES" "$HASH" dd if="/dev/$DRIVE" bs=512 count=1 2> /dev/null | xxd -c 16 else echo "Unknown partition scheme" fi done echo "===============================================================================" ioreg -rw 0 -c IOMedia | sed -n -E "/^[ \|]*\+\-o (.*) <class IOMedia[^a-zA-Z]/,/^[ \|]+ }$/p" | sed -n -E "/^[ \|]*\+\-o (.*)/s//\1/p;/^[ \|]* \| (.*)/s//\1/p;" echo "===============================================================================" bless --verbose --getboot echo "===============================================================================" bless --verbose --info echo "===============================================================================" ioreg -rw 0 -n AppleEFINVRAM | sed -n -E "/^[ \|]+[ ]+(\".*)$/s//\1/p;" echo "==============================================================================="