-
-
Save zhangyoufu/b85496abe9d9301e2d422858330a471a to your computer and use it in GitHub Desktop.
| #!./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 |
thank you @jon1scr, today I placed a logger on TclEvalObjvInternal and found (sha256->encrypt*16000->sha256) is belong of a64bL, too.
209 binary +++++++
209 binary -------
1 a64bL +++++++
1 sha2::sha256 +++++++
::sha2::sha256 buflen: 11, buf:
00000000: 7A 31 32 33 34 35 36 37 38 39 30 | z1234567890
1 ::sha2::_sha256 +++++++
8346 array +++++++
8346 array -------
........
1183 unset +++++++
1183 unset -------
2 SHA256Final -------
2 ::sha2::_sha256 -------
sha256 hash:
00000000: 50 8A 8C 5F EE 98 49 AA 1A 9B 85 9A BA 19 4D 67 | P.._..I.......Mg
00000010: FA 4D A2 D3 58 4E 7F 4C 32 59 A4 B7 59 FC 96 04 | .M..XN.L2Y..Y...
2 sha2::sha256 -------
1 a64bL -------
1 tcltwofish::decrypt +++++++
::tcltwofish::decrypt buflen: 64, buf:
00000000: 05 8A 77 A1 15 85 96 D3 62 33 04 CC F3 2D B4 67 | ..w.....b3...-.g
00000010: C1 0E 28 6A 2C A9 EF 30 B4 BC 67 86 B2 F9 D1 2D | ..(j,..0..g....-
00000020: F6 29 C3 9F 4E EB 33 AE 7C 28 96 B6 F0 C2 4F 58 | .)..N.3.|(....OX
00000030: 02 B9 4A D7 21 30 E2 37 62 C3 60 45 65 42 46 AF | ..J.!0.7b.`EeBF.
1 tcltwofish::decrypt -------
I'll try verify your decompiled code on known password installers.
PS: how do you decompile the bytecode from maui-utils, is there any tools sugguested?
Tbc is not good at protecting string literals. They can be decoded directly.
I think use installbuilder to build a empty installer with payload encrypt option enabled, then the built installer's metakit will have tcltwofish now.
@banxian You can always extract pre-built tcltwofish for win/linux/mac from optional.pak under InstallBuilder installation directory.
Infact I compared metakit content between built installer and windows-noupx.pak, the installer contains all package plus tcltwofish and 8 extra project files than windows-noupx.pak.
I mean it's a better start point which does not require additional optional.pak dependency, so it's easy to use tcltksh to pack the script and runtime to a single executable.
Uh oh!
There was an error while loading. Please reload this page.