Skip to content

Instantly share code, notes, and snippets.

@drvink
Forked from zhangyoufu/extract-installbuilder.tcl
Created September 13, 2020 17:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drvink/29f27f120d9d7a57d998182ce06daa4f to your computer and use it in GitHub Desktop.
Save drvink/29f27f120d9d7a57d998182ce06daa4f to your computer and use it in GitHub Desktop.
extract password-protected InstallBuilder installer
#!./tclkit
## prepare runtime environment
proc init {} {
## mount optional.pak (for tcltwofish)
set optionalPak installbuilder/paks/optional.pak
vfs::mk4::Mount $optionalPak $optionalPak -readonly
## adjust library search path
set ::auto_path [list $tcl::kitpath/lib/tcl$::tcl_version $tcl::kitpath/lib $tcl::kitpath/libraries $optionalPak/linux-x64 $tcl::kitpath]
## load packages
package require maui::util
package require vfs::cookfs
}
proc extract_metakit {src dst} {
## mount metakit
set db [tclKitMkOpen $src]
vfs::filesystem mount $src [list vfs::mk4::handler $db]
vfs::RegisterMount $src [list vfs::mk4::Unmount $db]
## ensure destination directory
file mkdir $dst
## read cookfsinfo.txt
set f [open $src/cookfsinfo.txt]
gets $f cookfsinfo
close $f
## read manifest.txt
set f [open $src/manifest.txt]
set manifest [read $f]
close $f
## copy project.xml
file copy -- $src/project.xml $dst
## copy images/
file copy -- $src/images $dst
## unmount metakit
vfs::filesystem unmount $src
return [list $cookfsinfo $manifest]
}
proc extract {src password dst} {
## clean up destination
file delete -force $dst
## copy images/ to dst, get manifest, mount cookfs
lassign [extract_metakit $src $dst] cookfsinfo manifest
## mount cookfs
set cookfsHandle [vfs::cookfs::Mount $src $src -readonly {*}$cookfsinfo]
## prepare decryption
set payloadinfo [$cookfsHandle getmetadata "installbuilder.payloadinfo"]
maui::util::m4ZQu $password $payloadinfo
## copy cookfs content to components/
set dst $dst/components
## extract directory/file/link
foreach {fileName props} $manifest {
puts "$fileName"
# directory mode mtime 0 {0 0}
# file mode mtime 0 {{0 size} {0 size}}
# link target mtime {0 0}
lassign $props type arg mtime
switch -- $type {
directory {
file mkdir $dst/$fileName
file attributes $dst/$fileName -permissions $arg
}
file {
file mkdir [file dirname $dst/$fileName]
file copy $src/$fileName $dst/$fileName
set numParts [llength [lindex $props 4]]
if {$numParts > 0} {
set fdst [open $dst/$fileName {WRONLY APPEND BINARY}]
for {set i 1} {$i < $numParts} {incr i} {
set fsrc [open $src/${fileName}___bitrockBigFile$i {RDONLY BINARY}]
fcopy $fsrc $fdst
close $fsrc
}
close $fdst
}
file attributes $dst/$fileName -permissions $arg
file mtime $dst/$fileName $mtime
}
link {
file mkdir [file dirname $dst/$fileName]
# file link -symbolic $dst/$fileName $arg
# file mtime $dst/$fileName $mtime
exec ln -s -- $arg $dst/$fileName
exec touch -h -t [clock format $mtime -format %Y%m%d%H%M.%S] $dst/$fileName
}
default {
error "not implemented"
}
}
}
## restore directory mtime
foreach {fileName props} $manifest {
lassign $props type arg mtime
if {$type == "directory"} {
file mtime $dst/$fileName $mtime
}
}
## unmount cookfs
vfs::filesystem unmount $src
}
init
extract {*}$argv
#!/bin/sh
cp installbuilder/paks/linux-x64-noupx.pak tclkit
sed --in-place --null-data --expression='/^if {\[file isfile \[file join \$::tcl::kitpath main.tcl/{s/^./\x1A/}' tclkit
chmod +x tclkit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment