Last active
August 26, 2024 08:55
-
-
Save mickael9/0b902da7c13207d1b86e to your computer and use it in GitHub Desktop.
Bitrock unpacking script
This file contains 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 characters
#!/usr/bin/env tclkit | |
# | |
# Bitrock unpacking script | |
# | |
# This script must be executed using 32-bit tclkit | |
# | |
# Author : mickael9 <mickael9 at gmail dot com> | |
# | |
# Latest version can be found at: | |
# https://gist.github.com/mickael9/0b902da7c13207d1b86e | |
source /usr/bin/sdx.kit | |
if {$argc < 2} { | |
puts "Usage: $argv0 installerFile outputDirectory" | |
exit 1 | |
} | |
set installerFile [lindex $argv 0] | |
set destDir [lindex $argv 1] | |
set installerMount /installer | |
set dataMount /installerData | |
vfs::mk4::Mount $installerFile $installerMount -readonly | |
lappend auto_path $installerMount/libraries/ | |
package require vfs::cookfs | |
catch {package require Tcllzmadec} | |
# progress from http://wiki.tcl.tk/16939 (sligtly modified) | |
# thanks to the author | |
proc progress {cur tot} { | |
# set to total width of progress bar | |
set total 76 | |
if {$cur == $tot} { | |
# cleanup | |
set str "\r[string repeat " " [expr $total + 4]]\r" | |
} else { | |
set half [expr {$total/2}] | |
set percent [expr {100.*$cur/$tot}] | |
set val (\ [format "%6.2f%%" $percent]\ ) | |
set str "\r|[string repeat = [ | |
expr {round($percent*$total/100)}]][ | |
string repeat { } [expr {$total-round($percent*$total/100)}]]|" | |
set str "[string range $str 0 $half]$val[string range $str [expr {$half+[string length $val]-1}] end]" | |
} | |
puts -nonewline stderr $str | |
} | |
# Read cookfs options | |
set optionsFile [open $installerMount/cookfsinfo.txt] | |
set options [read $optionsFile] | |
close $optionsFile | |
# Read the manifest | |
set manifestFile [open $installerMount/manifest.txt] | |
set manifest [read $manifestFile] | |
close $manifestFile | |
# Mount the files to $dataMount | |
vfs::cookfs::Mount {*}$options $installerFile $dataMount | |
puts "Creating directories..." | |
foreach {fileName props} $manifest { | |
set type [lindex $props 0] | |
if {$type == "directory"} { | |
set mode [lindex $props 1] | |
file mkdir $destDir/$fileName | |
file attributes $destDir/$fileName -permissions $mode | |
} | |
} | |
puts "Unpacking files, please wait..." | |
set entryCount [expr [llength $manifest] / 2] | |
set entryIndex 0 | |
foreach {fileName props} $manifest { | |
set type [lindex $props 0] | |
if {$type == "file"} { | |
set mode [lindex $props 1] | |
set sizes [lindex $props 4] | |
set nparts [llength $sizes] | |
set index 1 | |
file mkdir [file dirname $destDir/$fileName] | |
file copy -force $dataMount/$fileName $destDir/$fileName | |
if {$nparts > 0} { | |
set fp [open $destDir/$fileName a] | |
fconfigure $fp -translation binary | |
while {$index < $nparts} { | |
set chunkName $dataMount/${fileName}___bitrockBigFile$index | |
set fp2 [open $chunkName r] | |
fconfigure $fp2 -translation binary | |
puts -nonewline $fp [read $fp2] | |
close $fp2 | |
incr index | |
} | |
close $fp | |
} | |
file attributes $destDir/$fileName -permissions $mode | |
} | |
incr entryIndex | |
progress $entryIndex $entryCount | |
} | |
puts "Creating links..." | |
foreach {fileName props} $manifest { | |
set type [lindex $props 0] | |
if {$type == "link"} { | |
set linkTarget [lindex $props 1] | |
file delete $destDir/$fileName | |
file link -symbolic $destDir/$fileName $linkTarget | |
} | |
} | |
puts "Done" |
@zhangyoufu excellent hack , seems it applies Tcl_EvalEx invoke in TclKit_AppInit?
I have never used tcl before, my goal is extract payload encryption algorithm (I guess it decrypted by tcltwofish10.dll and cookfs14.dll), so I decide hook Tcl_CreateObjCommand in installer stub and hijack ::sha2::sha256c_update/::tcltwofish::decrypt to insert logger.
I think my way is somewhat ugly, could you point me better tcl style methods?
PS: I can't find maui::util package over web. is it contains in sdx.kit or somewhere else?
thank you
@banxian maui
is a proprietary package of Bitrock InstallBuilder, you can find it inside the metakit VFS.
I posted my code at https://gist.github.com/zhangyoufu/b85496abe9d9301e2d422858330a471a
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@mickael9 It seems that Tcl treat \x1A (Ctrl-Z) as eofchar by default.
By terminate execution before reaching main.tcl, an installer is effectively a tclkit without payload script to execute.
I really like this idea because I don’t have to looking for dependencies. The installer already packs them together. You only need to set auto_path correctly and load them.
I use
paks/linux-x64-noupx.pak
&paks/optional.pak
from InstallBuilder installation directory. It’s handy for CI, and it works pretty well against win/mac installers.