Skip to content

Instantly share code, notes, and snippets.

@NyaMisty
Forked from zhangyoufu/extract-installbuilder.tcl
Last active September 3, 2023 11:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NyaMisty/3d3b9a39fca463ca9e16628e96877b5c to your computer and use it in GitHub Desktop.
Save NyaMisty/3d3b9a39fca463ca9e16628e96877b5c 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
This file has been truncated, but you can view the full file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment