├── README.md └── bitrock-unpacker.tcl /README.md: -------------------------------------------------------------------------------- 1 | # bitrock-unpacker 2 | 3 | Archived. Use the original and more recent script by mickael9: https://gist.github.com/mickael9/0b902da7c13207d1b86e 4 | 5 | ## About 6 | 7 | The binaries in this repository are intended to help in getting the unpacker script to run on Windows. 8 | 9 | Usage: `bitrock-unpacker.exe INSTALLER.EXE OUTPUT_DIR [--metakit-only]` 10 | -------------------------------------------------------------------------------- /bitrock-unpacker.tcl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env tclkit 2 | # 3 | # Bitrock unpacking script 4 | # 5 | # Fork of a script made by mickael9 6 | # https://gist.github.com/mickael9/0b902da7c13207d1b86e 7 | # 8 | # Added an option to only extract Metakit files, inspired by dfir-it's fork 9 | # https://gist.github.com/dfir-it/06f3baa4556bba6822998103db43bc74 10 | 11 | #source /usr/bin/sdx.kit 12 | 13 | if {$argc < 2} { 14 | puts "Usage: $argv0 installerFile outputDirectory [--metakit-only]" 15 | exit 1 16 | } 17 | 18 | set installerFile [lindex $argv 0] 19 | set destDir [lindex $argv 1] 20 | 21 | set installerMount /installer 22 | set dataMount /installerData 23 | 24 | puts "Mounting the installer as a Metakit database..." 25 | vfs::mk4::Mount $installerFile $installerMount -readonly 26 | 27 | if {[lindex $argv 2] == "--metakit-only"} { 28 | puts "Copying files from the Metakit database to the output directory..." 29 | file copy -force $installerMount $destDir 30 | puts "Done" 31 | exit 32 | } 33 | 34 | lappend auto_path $installerMount/libraries/ 35 | package require vfs::cookfs 36 | catch {package require Tcllzmadec} 37 | 38 | # progress from http://wiki.tcl.tk/16939 (sligtly modified) 39 | # thanks to the author 40 | proc progress {cur tot} { 41 | # set to total width of progress bar 42 | set total 76 43 | 44 | if {$cur == $tot} { 45 | # cleanup 46 | set str "\r[string repeat " " [expr $total + 4]]\r" 47 | } else { 48 | set half [expr {$total/2}] 49 | set percent [expr {100.*$cur/$tot}] 50 | set val (\ [format "%6.2f%%" $percent]\ ) 51 | set str "\r|[string repeat = [ 52 | expr {round($percent*$total/100)}]][ 53 | string repeat { } [expr {$total-round($percent*$total/100)}]]|" 54 | set str "[string range $str 0 $half]$val[string range $str [expr {$half+[string length $val]-1}] end]" 55 | } 56 | puts -nonewline stderr $str 57 | } 58 | 59 | # Read cookfs options 60 | set optionsFile [open $installerMount/cookfsinfo.txt] 61 | set options [read $optionsFile] 62 | close $optionsFile 63 | 64 | # Read the manifest 65 | set manifestFile [open $installerMount/manifest.txt] 66 | set manifest [read $manifestFile] 67 | close $manifestFile 68 | 69 | # Mount the files to $dataMount 70 | puts "Mounting the installer files as a Cookfs archive..." 71 | vfs::cookfs::Mount {*}$options $installerFile $dataMount 72 | 73 | puts "Creating directories..." 74 | foreach {fileName props} $manifest { 75 | set type [lindex $props 0] 76 | 77 | if {$type == "directory"} { 78 | set mode [lindex $props 1] 79 | file mkdir $destDir/$fileName 80 | #file attributes $destDir/$fileName -permissions $mode 81 | } 82 | } 83 | 84 | puts "Unpacking files, please wait..." 85 | 86 | set entryCount [expr [llength $manifest] / 2] 87 | set entryIndex 0 88 | 89 | foreach {fileName props} $manifest { 90 | set type [lindex $props 0] 91 | 92 | if {$type == "file"} { 93 | set mode [lindex $props 1] 94 | set sizes [lindex $props 4] 95 | set nparts [llength $sizes] 96 | set index 1 97 | 98 | file mkdir [file dirname $destDir/$fileName] 99 | file copy -force $dataMount/$fileName $destDir/$fileName 100 | 101 | if {$nparts > 0} { 102 | set fp [open $destDir/$fileName a] 103 | fconfigure $fp -translation binary 104 | 105 | while {$index < $nparts} { 106 | set chunkName $dataMount/${fileName}___bitrockBigFile$index 107 | set fp2 [open $chunkName r] 108 | fconfigure $fp2 -translation binary 109 | puts -nonewline $fp [read $fp2] 110 | close $fp2 111 | incr index 112 | } 113 | close $fp 114 | } 115 | 116 | #file attributes $destDir/$fileName -permissions $mode 117 | } 118 | 119 | incr entryIndex 120 | progress $entryIndex $entryCount 121 | } 122 | 123 | puts "Creating links..." 124 | 125 | foreach {fileName props} $manifest { 126 | set type [lindex $props 0] 127 | 128 | if {$type == "link"} { 129 | set linkTarget [lindex $props 1] 130 | file delete $destDir/$fileName 131 | file link -symbolic $destDir/$fileName $linkTarget 132 | } 133 | } 134 | puts "Done" 135 | --------------------------------------------------------------------------------