From 13644041235615b02de1b178221609114ffd20c2 Mon Sep 17 00:00:00 2001 From: Odboy Date: Sat, 20 Dec 2025 10:01:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(core):=20=E5=AE=9E=E7=8E=B0=E6=89=AB?= =?UTF-8?q?=E6=8F=8F=E5=B9=B6=E5=88=A0=E9=99=A4iPhone=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E7=9B=B8=E5=86=8C=E4=B8=AD=E7=9A=84=E5=AE=9E=E5=86=B5=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增文件扫描逻辑,遍历目录下所有文件并记录路径与元信息 - 新增核心处理逻辑,识别.HEIC图片及其对应的.MOV实况视频 - 自动将匹配的实况视频移动至 duplicates 目录以供用户确认删除 - 添加构建脚本build.sh用于编译和压缩可执行文件 - 更新.gitignore忽略.idea目录 - 重写README.md,明确工具用途、需求及效果预览 - 初始化模块依赖管理(go.mod, go.sum)及相关工具类和变量定义 --- .gitignore | 1 + README.en.md | 36 -- README.md | 41 +- build.sh | 7 + core/file_scanner.go | 41 ++ core/handle_image.go | 74 +++ doc/QQ20251220-095717.png | Bin 0 -> 38427 bytes doc/QQ20251220-095800.png | Bin 0 -> 35813 bytes go.mod | 15 + go.sum | 13 + main.go | 24 + upx.1 | 1042 +++++++++++++++++++++++++++++++++++++ util/init.go | 26 + vars/init.go | 9 + 14 files changed, 1260 insertions(+), 69 deletions(-) delete mode 100644 README.en.md create mode 100644 build.sh create mode 100644 core/file_scanner.go create mode 100644 core/handle_image.go create mode 100644 doc/QQ20251220-095717.png create mode 100644 doc/QQ20251220-095800.png create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 upx.1 create mode 100644 util/init.go create mode 100644 vars/init.go diff --git a/.gitignore b/.gitignore index 66fd13c..474488e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ # Dependency directories (remove the comment below to include it) # vendor/ +.idea diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 61452c6..0000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# kenaito-iphone-export-photo-remove-duplicates - -#### Description -IPhone导出的相册中存在图片和实况视频,这个工具用来删除图片对应的实况视频,从而减小占用空间。 - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index ae52ca4..e298dec 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,12 @@ -# kenaito-iphone-export-photo-remove-duplicates +## IPhone导出相册删除实况工具 -#### 介绍 -IPhone导出的相册中存在图片和实况视频,这个工具用来删除图片对应的实况视频,从而减小占用空间。 +#### 需求 -#### 软件架构 -软件架构说明 +- 扫描某个目录 +- 找到与照片对应的实况视频 +- 删除实况视频 +#### 效果预览 +![1](./doc/QQ20251220-095717.png) -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +![1](./doc/QQ20251220-095800.png) diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..8e078be --- /dev/null +++ b/build.sh @@ -0,0 +1,7 @@ +rm -f kenaito-media-group-tool.exe +rm -f kenaito-media-group-tool-release.exe +# build +go build -o kenaito-media-group-tool.exe main.go +# upx compress +./upx -o kenaito-media-group-tool-release.exe kenaito-media-group-tool.exe +rm -f kenaito-media-group-tool.exe diff --git a/core/file_scanner.go b/core/file_scanner.go new file mode 100644 index 0000000..c008dad --- /dev/null +++ b/core/file_scanner.go @@ -0,0 +1,41 @@ +package core + +import ( + "fmt" + "kenaito-media-group-tool/util" + "kenaito-media-group-tool/vars" + "log" + "os" + "path" + "path/filepath" +) + +type FileScanner struct { +} + +func (FileScanner) DoScan(rootDir string) { + fmt.Printf("=== 开始扫描文件 \n") + if err := filepath.Walk(rootDir, visitFile); err != nil { + log.Fatal(err) + } +} + +// 定义walkFn回调函数visit +func visitFile(currentPath string, info os.FileInfo, err error) error { + if err != nil { + return err // 如果有错误,直接返回 + } + if !info.IsDir() { + ext := path.Ext(currentPath) + if ".exe" != ext { + vars.GlobalFilePathList = append(vars.GlobalFilePathList, currentPath) + // filename, include ext + vars.GlobalFilePath2FileNameExtMap[currentPath] = filepath.Base(currentPath) + // filename, exclude ext + vars.GlobalFilePath2FileNameMap[currentPath] = util.GetFileNameWithoutExt(currentPath) + // file ext + vars.GlobalFilePath2FileExtMap[currentPath] = ext + } + } + return nil +} diff --git a/core/handle_image.go b/core/handle_image.go new file mode 100644 index 0000000..58f75c4 --- /dev/null +++ b/core/handle_image.go @@ -0,0 +1,74 @@ +package core + +import ( + "fmt" + "github.com/redmask-hb/GoSimplePrint/goPrint" + uuid "github.com/satori/go.uuid" + "kenaito-media-group-tool/util" + "kenaito-media-group-tool/vars" + "os" + "strings" +) + +func DoDeleteLiveVideo(rootDir string) { + pathSep := string(os.PathSeparator) + uid := strings.ReplaceAll(uuid.NewV4().String(), "-", "") + total := len(vars.GlobalFilePathList) + fmt.Printf("=== 文件总数: %d \n", total) + + for _, filePath := range vars.GlobalFilePathList { + fileExt := vars.GlobalFilePath2FileExtMap[filePath] + if ".HEIC" == fileExt { + vars.GlobalHEICFilePathNameMap[filePath] = vars.GlobalFilePath2FileNameMap[filePath] + continue + } + if ".MOV" == fileExt { + vars.GlobalMOVFilePathPathNameMap[filePath] = vars.GlobalFilePath2FileNameMap[filePath] + } + } + + var movFilePath []string + for _, heicName := range vars.GlobalHEICFilePathNameMap { + for movPath, movName := range vars.GlobalMOVFilePathPathNameMap { + if heicName == movName { + println(movPath) + movFilePath = append(movFilePath, movPath) + } + } + } + fmt.Printf("=== 发现实况视频文件数量: %d\n", len(movFilePath)) + + duplicatesDir := rootDir + pathSep + "duplicates-" + uid + util.CreateDir(duplicatesDir) + + fmt.Printf("=== 开始移动实况视频文件") + doMoveFileToDir(movFilePath, duplicatesDir) + fmt.Printf("=== 实况视频已移动到: %v 中\n", duplicatesDir) + +} + +// 批量移动文件到目录 +func doMoveFileToDir(filePathList []string, videoDirPath string) { + total := len(filePathList) + var count = 0 + bar := goPrint.NewBar(100) + bar.SetNotice("=== 移动文件到目录:") + bar.SetGraph(">") + pathSeparator := string(os.PathSeparator) + for _, videoFilePath := range filePathList { + moveFileToDir(videoFilePath, videoDirPath+pathSeparator) + count = count + 1 + bar.PrintBar(util.CalcPercentage(count, total)) + } + bar.PrintEnd("=== Finish") +} + +// 移动文件到目录 +func moveFileToDir(sourceFilePath string, targetDirectory string) bool { + splits := strings.Split(sourceFilePath, string(os.PathSeparator)) + fileName := splits[len(splits)-1] + targetFilePath := targetDirectory + fileName + err := os.Rename(sourceFilePath, targetFilePath) + //fmt.Printf("=== 移动文件, 源: %s, 目标: %s \n", sourceFilePath, targetFilePath) + return err == nil +} diff --git a/doc/QQ20251220-095717.png b/doc/QQ20251220-095717.png new file mode 100644 index 0000000000000000000000000000000000000000..f9b7e1410f7e300ccaa001ddae45c8434ee48fab GIT binary patch literal 38427 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 literal 0 HcmV?d00001 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e16e641 --- /dev/null +++ b/go.mod @@ -0,0 +1,15 @@ +module kenaito-media-group-tool + +go 1.21 + +require ( + github.com/gabriel-vasile/mimetype v1.4.3 + github.com/redmask-hb/GoSimplePrint v0.0.0-20210302075413-3a3af92bcb7d + github.com/satori/go.uuid v1.2.0 + golang.org/x/image v0.16.0 +) + +require ( + golang.org/x/net v0.17.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..f923da1 --- /dev/null +++ b/go.sum @@ -0,0 +1,13 @@ +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/redmask-hb/GoSimplePrint v0.0.0-20210302075413-3a3af92bcb7d h1:h/hohIqMUCML2Rp9BXXAu0I3ZR68d7eqMHLPNq7N2tg= +github.com/redmask-hb/GoSimplePrint v0.0.0-20210302075413-3a3af92bcb7d/go.mod h1:LiYo3EFlYfk46Re4zgQysMo6yO3/kAXslB2fyMdl+uw= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/main.go b/main.go new file mode 100644 index 0000000..8fbf441 --- /dev/null +++ b/main.go @@ -0,0 +1,24 @@ +package main + +import ( + _ "embed" + "fmt" + "kenaito-media-group-tool/core" + "os" + "time" +) + +func main() { + fmt.Println("=== 警告:该程序会改变目录结构,将在5秒后开始执行") + time.Sleep(time.Second * 5) + rootDir, err := os.Getwd() + if err != nil { + fmt.Println("=== 获取当前路径异常", err) + return + } + scanner := core.FileScanner{} + scanner.DoScan(rootDir) + core.DoDeleteLiveVideo(rootDir) + fmt.Println("=== 3s后自动退出") + time.Sleep(time.Second * 3) +} diff --git a/upx.1 b/upx.1 new file mode 100644 index 0000000..a4d59c4 --- /dev/null +++ b/upx.1 @@ -0,0 +1,1042 @@ +.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "UPX 1" +.TH UPX 1 "2024-03-27" "upx 4.2.3" " " +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +upx \- compress or expand executable files +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +\&\fBupx\fR [\ \fIcommand\fR\ ] [\ \fIoptions\fR\ ] \fIfilename\fR... +.SH "ABSTRACT" +.IX Header "ABSTRACT" +.Vb 3 +\& The Ultimate Packer for eXecutables +\& Copyright (c) 1996\-2024 Markus Oberhumer, Laszlo Molnar & John Reiser +\& https://upx.github.io +.Ve +.PP +\&\fB\s-1UPX\s0\fR is a portable, extendable, high-performance executable packer for +several different executable formats. It achieves an excellent compression +ratio and offers \fI*very*\fR fast decompression. Your executables suffer +no memory overhead or other drawbacks for most of the formats supported, +because of in-place decompression. +.SH "DISCLAIMER" +.IX Header "DISCLAIMER" +\&\fB\s-1UPX\s0\fR comes with \s-1ABSOLUTELY NO WARRANTY\s0; for details see the file \s-1COPYING.\s0 +.PP +Please report all problems or suggestions to the authors. Thanks. +.SH "SECURITY CONTEXT" +.IX Header "SECURITY CONTEXT" +\&\s-1IMPORTANT NOTE:\s0 \fB\s-1UPX\s0\fR inherits the security context of any files it handles. +.PP +This means that packing, unpacking, or even testing or listing a file requires +the same security considerations as actually executing the file. +.PP +Use \fB\s-1UPX\s0\fR on trusted files only! +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +\&\fB\s-1UPX\s0\fR is a versatile executable packer with the following features: +.PP +.Vb 3 +\& \- secure: as UPX is documented Open Source since many years any relevant +\& Security/Antivirus software is able to peek inside UPX compressed +\& apps to verify them +\& +\& \- excellent compression ratio: typically compresses better than Zip, +\& use UPX to decrease the size of your distribution ! +\& +\& \- very fast decompression: more than 500 MB/sec on any reasonably modern +\& machine +\& +\& \- no memory overhead for your compressed executables for most of the +\& supported formats because of in\-place decompression +\& +\& \- safe: you can list, test and unpack your executables. +\& Also, a checksum of both the compressed and uncompressed file is +\& maintained internally. +\& +\& \- universal: UPX can pack a number of executable formats, including +\& Windows programs and DLLs, macOS apps and Linux executables +\& +\& \- portable: UPX is written in portable endian\-neutral C++ +\& +\& \- extendable: because of the class layout it\*(Aqs very easy to support +\& new executable formats or add new compression algorithms +\& +\& \- free: UPX is distributed with full source code under the GNU General +\& Public License v2+, with special exceptions granting the free usage +\& for commercial programs +.Ve +.PP +You probably understand now why we call \fB\s-1UPX\s0\fR the "\fIultimate\fR" +executable packer. +.SH "COMMANDS" +.IX Header "COMMANDS" +.SS "Compress" +.IX Subsection "Compress" +This is the default operation, eg. \fBupx yourfile.exe\fR will compress the file +specified on the command line. +.SS "Decompress" +.IX Subsection "Decompress" +All \fB\s-1UPX\s0\fR supported file formats can be unpacked using the \fB\-d\fR switch, eg. +\&\fBupx \-d yourfile.exe\fR will uncompress the file you've just compressed. +.SS "Test" +.IX Subsection "Test" +The \fB\-t\fR command tests the integrity of the compressed and uncompressed +data, eg. \fBupx \-t yourfile.exe\fR check whether your file can be safely +decompressed. Note, that this command doesn't check the whole file, only +the part that will be uncompressed during program execution. This means +that you should not use this command instead of a virus checker. +.SS "List" +.IX Subsection "List" +The \fB\-l\fR command prints out some information about the compressed files +specified on the command line as parameters, eg \fBupx \-l yourfile.exe\fR +shows the compressed / uncompressed size and the compression ratio of +\&\fIyourfile.exe\fR. +.SH "OPTIONS" +.IX Header "OPTIONS" +\&\fB\-q\fR: be quiet, suppress warnings +.PP +\&\fB\-q \-q\fR (or \fB\-qq\fR): be very quiet, suppress errors +.PP +\&\fB\-q \-q \-q\fR (or \fB\-qqq\fR): produce no output at all +.PP +\&\fB\-\-help\fR: prints the help +.PP +\&\fB\-\-version\fR: print the version of \fB\s-1UPX\s0\fR +.PP +\&\fB\-\-exact\fR: when compressing, require to be able to get a byte-identical file +after decompression with option \fB\-d\fR. [\s-1NOTE:\s0 this is work in progress and is +not supported for all formats yet. If you do care, as a workaround you can +compress and then decompress your program a first time \- any further +compress-decompress steps should then yield byte-identical results +as compared to the first decompressed version.] +.PP +\&\fB\-k\fR: keep backup files +.PP +\&\fB\-o file\fR: write output to file +.PP +[ ...more docs need to be written... \- type `\fBupx \-\-help\fR' for now ] +.SH "COMPRESSION LEVELS & TUNING" +.IX Header "COMPRESSION LEVELS & TUNING" +\&\fB\s-1UPX\s0\fR offers ten different compression levels from \fB\-1\fR to \fB\-9\fR, +and \fB\-\-best\fR. The default compression level is \fB\-8\fR for files +smaller than 512 KiB, and \fB\-7\fR otherwise. +.IP "\(bu" 4 +Compression levels 1, 2 and 3 are pretty fast. +.IP "\(bu" 4 +Compression levels 4, 5 and 6 achieve a good time/ratio performance. +.IP "\(bu" 4 +Compression levels 7, 8 and 9 favor compression ratio over speed. +.IP "\(bu" 4 +Compression level \fB\-\-best\fR may take a long time. +.PP +Note that compression level \fB\-\-best\fR can be somewhat slow for large +files, but you definitely should use it when releasing a final version +of your program. +.PP +Quick info for achieving the best compression ratio: +.IP "\(bu" 4 +Try \fBupx \-\-brute \-\-no\-lzma myfile.exe\fR or even +\&\fBupx \-\-ultra\-brute \-\-no\-lzma myfile.exe\fR. +.IP "\(bu" 4 +The option \fB\-\-lzma\fR enables \s-1LZMA\s0 compression, which compresses better but +is *significantly slower* at decompression. You probably do not want +to use it for large files. +.Sp +(Note that \fB\-\-lzma\fR is automatically enabled by \fB\-\-all\-methods\fR and +\&\fB\-\-brute\fR, use \fB\-\-no\-lzma\fR to override.) +.IP "\(bu" 4 +Try if \fB\-\-overlay=strip\fR works. +.IP "\(bu" 4 +For win32/pe programs there's \fB\-\-strip\-relocs=0\fR. See notes below. +.SH "OVERLAY HANDLING OPTIONS" +.IX Header "OVERLAY HANDLING OPTIONS" +Info: An \*(L"overlay\*(R" means auxiliary data attached after the logical end of +an executable, and it often contains application specific data +(this is a common practice to avoid an extra data file, though +it would be better to use resource sections). +.PP +\&\fB\s-1UPX\s0\fR handles overlays like many other executable packers do: it simply +copies the overlay after the compressed image. This works with some +files, but doesn't work with others, depending on how an application +actually accesses this overlaid data. +.PP +.Vb 1 +\& \-\-overlay=copy Copy any extra data attached to the file. [DEFAULT] +\& +\& \-\-overlay=strip Strip any overlay from the program instead of +\& copying it. Be warned, this may make the compressed +\& program crash or otherwise unusable. +\& +\& \-\-overlay=skip Refuse to compress any program which has an overlay. +.Ve +.SH "ENVIRONMENT VARIABLE" +.IX Header "ENVIRONMENT VARIABLE" +The environment variable \fB\s-1UPX\s0\fR can hold a set of default +options for \fB\s-1UPX\s0\fR. These options are interpreted first and +can be overwritten by explicit command line parameters. +For example: +.PP +.Vb 3 +\& for DOS/Windows: set UPX=\-9 \-\-compress\-icons#0 +\& for sh/ksh/zsh: UPX="\-9 \-\-compress\-icons=0"; export UPX +\& for csh/tcsh: setenv UPX "\-9 \-\-compress\-icons=0" +.Ve +.PP +Under DOS/Windows you must use '#' instead of '=' when setting the +environment variable because of a \s-1COMMAND.COM\s0 limitation. +.PP +Not all of the options are valid in the environment variable \- +\&\fB\s-1UPX\s0\fR will tell you. +.PP +You can explicitly use the \fB\-\-no\-env\fR option to ignore the +environment variable. +.SH "NOTES FOR THE SUPPORTED EXECUTABLE FORMATS" +.IX Header "NOTES FOR THE SUPPORTED EXECUTABLE FORMATS" +.SS "\s-1NOTES FOR ATARI/TOS\s0" +.IX Subsection "NOTES FOR ATARI/TOS" +This is the executable format used by the Atari \s-1ST/TT,\s0 a Motorola 68000 +based personal computer which was popular in the late '80s. Support +of this format is only because of nostalgic feelings of one of +the authors and serves no practical purpose :\-). +See https://freemint.github.io for more info. +.PP +Packed programs will be byte-identical to the original after uncompression. +All debug information will be stripped, though. +.PP +Extra options available for this executable format: +.PP +.Vb 4 +\& \-\-all\-methods Compress the program several times, using all +\& available compression methods. This may improve +\& the compression ratio in some cases, but usually +\& the default method gives the best results anyway. +.Ve +.SS "\s-1NOTES FOR BVMLINUZ/I386\s0" +.IX Subsection "NOTES FOR BVMLINUZ/I386" +Same as vmlinuz/i386. +.SS "\s-1NOTES FOR DOS/COM\s0" +.IX Subsection "NOTES FOR DOS/COM" +Obviously \fB\s-1UPX\s0\fR won't work with executables that want to read data from +themselves (like some commandline utilities that ship with Win95/98/ME). +.PP +Compressed programs only work on a 286+. +.PP +Packed programs will be byte-identical to the original after uncompression. +.PP +Maximum uncompressed size: ~65100 bytes. +.PP +Extra options available for this executable format: +.PP +.Vb 1 +\& \-\-8086 Create an executable that works on any 8086 CPU. +\& +\& \-\-all\-methods Compress the program several times, using all +\& available compression methods. This may improve +\& the compression ratio in some cases, but usually +\& the default method gives the best results anyway. +\& +\& \-\-all\-filters Compress the program several times, using all +\& available preprocessing filters. This may improve +\& the compression ratio in some cases, but usually +\& the default filter gives the best results anyway. +.Ve +.SS "\s-1NOTES FOR DOS/EXE\s0" +.IX Subsection "NOTES FOR DOS/EXE" +dos/exe stands for all \*(L"normal\*(R" 16\-bit \s-1DOS\s0 executables. +.PP +Obviously \fB\s-1UPX\s0\fR won't work with executables that want to read data from +themselves (like some command line utilities that ship with Win95/98/ME). +.PP +Compressed programs only work on a 286+. +.PP +Extra options available for this executable format: +.PP +.Vb 1 +\& \-\-8086 Create an executable that works on any 8086 CPU. +\& +\& \-\-no\-reloc Use no relocation records in the exe header. +\& +\& \-\-all\-methods Compress the program several times, using all +\& available compression methods. This may improve +\& the compression ratio in some cases, but usually +\& the default method gives the best results anyway. +.Ve +.SS "\s-1NOTES FOR DOS/SYS\s0" +.IX Subsection "NOTES FOR DOS/SYS" +Compressed programs only work on a 286+. +.PP +Packed programs will be byte-identical to the original after uncompression. +.PP +Maximum uncompressed size: ~65350 bytes. +.PP +Extra options available for this executable format: +.PP +.Vb 1 +\& \-\-8086 Create an executable that works on any 8086 CPU. +\& +\& \-\-all\-methods Compress the program several times, using all +\& available compression methods. This may improve +\& the compression ratio in some cases, but usually +\& the default method gives the best results anyway. +\& +\& \-\-all\-filters Compress the program several times, using all +\& available preprocessing filters. This may improve +\& the compression ratio in some cases, but usually +\& the default filter gives the best results anyway. +.Ve +.SS "\s-1NOTES FOR DJGPP2/COFF\s0" +.IX Subsection "NOTES FOR DJGPP2/COFF" +First of all, it is recommended to use \fB\s-1UPX\s0\fR *instead* of \fBstrip\fR. strip has +the very bad habit of replacing your stub with its own (outdated) version. +Additionally \fB\s-1UPX\s0\fR corrects a bug/feature in strip v2.8.x: it +will fix the 4 KiB alignment of the stub. +.PP +\&\fB\s-1UPX\s0\fR includes the full functionality of stubify. This means it will +automatically stubify your \s-1COFF\s0 files. Use the option \fB\-\-coff\fR to +disable this functionality (see below). +.PP +\&\fB\s-1UPX\s0\fR automatically handles Allegro packfiles. +.PP +The \s-1DLM\s0 format (a rather exotic shared library extension) is not supported. +.PP +Packed programs will be byte-identical to the original after uncompression. +All debug information and trailing garbage will be stripped, though. +.PP +Extra options available for this executable format: +.PP +.Vb 2 +\& \-\-coff Produce COFF output instead of EXE. By default +\& UPX keeps your current stub. +\& +\& \-\-all\-methods Compress the program several times, using all +\& available compression methods. This may improve +\& the compression ratio in some cases, but usually +\& the default method gives the best results anyway. +\& +\& \-\-all\-filters Compress the program several times, using all +\& available preprocessing filters. This may improve +\& the compression ratio in some cases, but usually +\& the default filter gives the best results anyway. +.Ve +.SS "\s-1NOTES FOR LINUX\s0 [general]" +.IX Subsection "NOTES FOR LINUX [general]" +Introduction +.PP +.Vb 4 +\& Linux/386 support in UPX consists of 3 different executable formats, +\& one optimized for ELF executables ("linux/elf386"), one optimized +\& for shell scripts ("linux/sh386"), and one generic format +\& ("linux/386"). +\& +\& We will start with a general discussion first, but please +\& also read the relevant docs for each of the individual formats. +\& +\& Also, there is special support for bootable kernels \- see the +\& description of the vmlinuz/386 format. +.Ve +.PP +General user's overview +.PP +.Vb 7 +\& Running a compressed executable program trades less space on a +\& \`\`permanent\*(Aq\*(Aq storage medium (such as a hard disk, floppy disk, +\& CD\-ROM, flash memory, EPROM, etc.) for more space in one or more +\& \`\`temporary\*(Aq\*(Aq storage media (such as RAM, swap space, /tmp, etc.). +\& Running a compressed executable also requires some additional CPU +\& cycles to generate the compressed executable in the first place, +\& and to decompress it at each invocation. +\& +\& How much space is traded? It depends on the executable, but many +\& programs save 30% to 50% of permanent disk space. How much CPU +\& overhead is there? Again, it depends on the executable, but +\& decompression speed generally is at least many megabytes per second, +\& and frequently is limited by the speed of the underlying disk +\& or network I/O. +\& +\& Depending on the statistics of usage and access, and the relative +\& speeds of CPU, RAM, swap space, /tmp, and file system storage, then +\& invoking and running a compressed executable can be faster than +\& directly running the corresponding uncompressed program. +\& The operating system might perform fewer expensive I/O operations +\& to invoke the compressed program. Paging to or from swap space +\& or /tmp might be faster than paging from the general file system. +\& \`\`Medium\-sized\*(Aq\*(Aq programs which access about 1/3 to 1/2 of their +\& stored program bytes can do particularly well with compression. +\& Small programs tend not to benefit as much because the absolute +\& savings is less. Big programs tend not to benefit proportionally +\& because each invocation may use only a small fraction of the program, +\& yet UPX decompresses the entire program before invoking it. +\& But in environments where disk or flash memory storage is limited, +\& then compression may win anyway. +\& +\& Currently, executables compressed by UPX do not share RAM at runtime +\& in the way that executables mapped from a file system do. As a +\& result, if the same program is run simultaneously by more than one +\& process, then using the compressed version will require more RAM and/or +\& swap space. So, shell programs (bash, csh, etc.) and \`\`make\*(Aq\*(Aq +\& might not be good candidates for compression. +\& +\& UPX recognizes three executable formats for Linux: Linux/elf386, +\& Linux/sh386, and Linux/386. Linux/386 is the most generic format; +\& it accommodates any file that can be executed. At runtime, the UPX +\& decompression stub re\-creates in /tmp a copy of the original file, +\& and then the copy is (re\-)executed with the same arguments. +\& ELF binary executables prefer the Linux/elf386 format by default, +\& because UPX decompresses them directly into RAM, uses only one +\& exec, does not use space in /tmp, and does not use /proc. +\& Shell scripts where the underlying shell accepts a \`\`\-c\*(Aq\*(Aq argument +\& can use the Linux/sh386 format. UPX decompresses the shell script +\& into low memory, then maps the shell and passes the entire text of the +\& script as an argument with a leading \`\`\-c\*(Aq\*(Aq. +.Ve +.PP +General benefits: +.PP +.Vb 4 +\& \- UPX can compress all executables, be it AOUT, ELF, libc4, libc5, +\& libc6, Shell/Perl/Python/... scripts, standalone Java .class +\& binaries, or whatever... +\& All scripts and programs will work just as before. +\& +\& \- Compressed programs are completely self\-contained. No need for +\& any external program. +\& +\& \- UPX keeps your original program untouched. This means that +\& after decompression you will have a byte\-identical version, +\& and you can use UPX as a file compressor just like gzip. +\& [ Note that UPX maintains a checksum of the file internally, +\& so it is indeed a reliable alternative. ] +\& +\& \- As the stub only uses syscalls and isn\*(Aqt linked against libc it +\& should run under any Linux configuration that can run ELF +\& binaries. +\& +\& \- For the same reason compressed executables should run under +\& FreeBSD and other systems which can run Linux binaries. +\& [ Please send feedback on this topic ] +.Ve +.PP +General drawbacks: +.PP +.Vb 4 +\& \- It is not advisable to compress programs which usually have many +\& instances running (like \`sh\*(Aq or \`make\*(Aq) because the common segments of +\& compressed programs won\*(Aqt be shared any longer between different +\& processes. +\& +\& \- \`ldd\*(Aq and \`size\*(Aq won\*(Aqt show anything useful because all they +\& see is the statically linked stub. Since version 0.82 the section +\& headers are stripped from the UPX stub and \`size\*(Aq doesn\*(Aqt even +\& recognize the file format. The file patches/patch\-elfcode.h has a +\& patch to fix this bug in \`size\*(Aq and other programs which use GNU BFD. +.Ve +.PP +General notes: +.PP +.Vb 2 +\& \- As UPX leaves your original program untouched it is advantageous +\& to strip it before compression. +\& +\& \- If you compress a script you will lose platform independence \- +\& this could be a problem if you are using NFS mounted disks. +\& +\& \- Compression of suid, guid and sticky\-bit programs is rejected +\& because of possible security implications. +\& +\& \- For the same reason there is no sense in making any compressed +\& program suid. +\& +\& \- Obviously UPX won\*(Aqt work with executables that want to read data +\& from themselves. E.g., this might be a problem for Perl scripts +\& which access their _\|_DATA_\|_ lines. +\& +\& \- In case of internal errors the stub will abort with exitcode 127. +\& Typical reasons for this to happen are that the program has somehow +\& been modified after compression. +\& Running \`strace \-o strace.log compressed_file\*(Aq will tell you more. +.Ve +.SS "\s-1NOTES FOR LINUX/ELF386\s0" +.IX Subsection "NOTES FOR LINUX/ELF386" +Please read the general Linux description first. +.PP +The linux/elf386 format decompresses directly into \s-1RAM,\s0 +uses only one exec, does not use space in /tmp, +and does not use /proc. +.PP +Linux/elf386 is automatically selected for Linux \s-1ELF\s0 executables. +.PP +Packed programs will be byte-identical to the original after uncompression. +.PP +How it works: +.PP +.Vb 9 +\& For ELF executables, UPX decompresses directly to memory, simulating +\& the mapping that the operating system kernel uses during exec(), +\& including the PT_INTERP program interpreter (if any). +\& The brk() is set by a special PT_LOAD segment in the compressed +\& executable itself. UPX then wipes the stack clean except for +\& arguments, environment variables, and Elf_auxv entries (this is +\& required by bugs in the startup code of /lib/ld\-linux.so as of +\& May 2000), and transfers control to the program interpreter or +\& the e_entry address of the original executable. +\& +\& The UPX stub is about 1700 bytes long, partly written in assembler +\& and only uses kernel syscalls. It is not linked against any libc. +.Ve +.PP +Specific drawbacks: +.PP +.Vb 9 +\& \- For linux/elf386 and linux/sh386 formats, you will be relying on +\& RAM and swap space to hold all of the decompressed program during +\& the lifetime of the process. If you already use most of your swap +\& space, then you may run out. A system that is "out of memory" +\& can become fragile. Many programs do not react gracefully when +\& malloc() returns 0. With newer Linux kernels, the kernel +\& may decide to kill some processes to regain memory, and you +\& may not like the kernel\*(Aqs choice of which to kill. Running +\& /usr/bin/top is one way to check on the usage of swap space. +.Ve +.PP +Extra options available for this executable format: +.PP +.Vb 1 +\& (none) +.Ve +.SS "\s-1NOTES FOR LINUX/SH386\s0" +.IX Subsection "NOTES FOR LINUX/SH386" +Please read the general Linux description first. +.PP +Shell scripts where the underling shell accepts a ``\-c'' argument +can use the Linux/sh386 format. \fB\s-1UPX\s0\fR decompresses the shell script +into low memory, then maps the shell and passes the entire text of the +script as an argument with a leading ``\-c''. +It does not use space in /tmp, and does not use /proc. +.PP +Linux/sh386 is automatically selected for shell scripts that +use a known shell. +.PP +Packed programs will be byte-identical to the original after uncompression. +.PP +How it works: +.PP +.Vb 8 +\& For shell script executables (files beginning with "#!/" or "#! /") +\& where the shell is known to accept "\-c ", UPX decompresses +\& the file into low memory, then maps the shell (and its PT_INTERP), +\& and passes control to the shell with the entire decompressed file +\& as the argument after "\-c". Known shells are sh, ash, bash, bsh, csh, +\& ksh, tcsh, pdksh. Restriction: UPX cannot use this method +\& for shell scripts which use the one optional string argument after +\& the shell name in the script (example: "#! /bin/sh option3\en".) +\& +\& The UPX stub is about 1700 bytes long, partly written in assembler +\& and only uses kernel syscalls. It is not linked against any libc. +.Ve +.PP +Specific drawbacks: +.PP +.Vb 9 +\& \- For linux/elf386 and linux/sh386 formats, you will be relying on +\& RAM and swap space to hold all of the decompressed program during +\& the lifetime of the process. If you already use most of your swap +\& space, then you may run out. A system that is "out of memory" +\& can become fragile. Many programs do not react gracefully when +\& malloc() returns 0. With newer Linux kernels, the kernel +\& may decide to kill some processes to regain memory, and you +\& may not like the kernel\*(Aqs choice of which to kill. Running +\& /usr/bin/top is one way to check on the usage of swap space. +.Ve +.PP +Extra options available for this executable format: +.PP +.Vb 1 +\& (none) +.Ve +.SS "\s-1NOTES FOR LINUX/386\s0" +.IX Subsection "NOTES FOR LINUX/386" +Please read the general Linux description first. +.PP +The generic linux/386 format decompresses to /tmp and needs +/proc file system support. It starts the decompressed program +via the \fBexecve()\fR syscall. +.PP +Linux/386 is only selected if the specialized linux/elf386 +and linux/sh386 won't recognize a file. +.PP +Packed programs will be byte-identical to the original after uncompression. +.PP +How it works: +.PP +.Vb 7 +\& For files which are not ELF and not a script for a known "\-c" shell, +\& UPX uses kernel execve(), which first requires decompressing to a +\& temporary file in the file system. Interestingly \- +\& because of the good memory management of the Linux kernel \- this +\& often does not introduce a noticeable delay, and in fact there +\& will be no disk access at all if you have enough free memory as +\& the entire process takes places within the file system buffers. +\& +\& A compressed executable consists of the UPX stub and an overlay +\& which contains the original program in a compressed form. +\& +\& The UPX stub is a statically linked ELF executable and does +\& the following at program startup: +\& +\& 1) decompress the overlay to a temporary location in /tmp +\& 2) open the temporary file for reading +\& 3) try to delete the temporary file and start (execve) +\& the uncompressed program in /tmp using /proc//fd/X as +\& attained by step 2) +\& 4) if that fails, fork off a subprocess to clean up and +\& start the program in /tmp in the meantime +\& +\& The UPX stub is about 1700 bytes long, partly written in assembler +\& and only uses kernel syscalls. It is not linked against any libc. +.Ve +.PP +Specific drawbacks: +.PP +.Vb 4 +\& \- You need additional free disk space for the uncompressed program +\& in your /tmp directory. This program is deleted immediately after +\& decompression, but you still need it for the full execution time +\& of the program. +\& +\& \- You must have /proc file system support as the stub wants to open +\& /proc//exe and needs /proc//fd/X. This also means that you +\& cannot compress programs that are used during the boot sequence +\& before /proc is mounted. +\& +\& \- Utilities like \`top\*(Aq will display numerical values in the process +\& name field. This is because Linux computes the process name from +\& the first argument of the last execve syscall (which is typically +\& something like /proc//fd/3). +\& +\& \- Because of temporary decompression to disk the decompression speed +\& is not as fast as with the other executable formats. Still, I can see +\& no noticeable delay when starting programs like my ~3 MiB emacs (which +\& is less than 1 MiB when compressed :\-). +.Ve +.PP +Extra options available for this executable format: +.PP +.Vb 3 +\& \-\-force\-execve Force the use of the generic linux/386 "execve" +\& format, i.e. do not try the linux/elf386 and +\& linux/sh386 formats. +.Ve +.SS "\s-1NOTES FOR PS1/EXE\s0" +.IX Subsection "NOTES FOR PS1/EXE" +This is the executable format used by the Sony PlayStation (PSone), +a \s-1MIPS R3000\s0 based gaming console which is popular since the late '90s. +Support of this format is very similar to the Atari one, because of +nostalgic feelings of one of the authors. +.PP +Packed programs will be byte-identical to the original after uncompression, +until further notice. +.PP +Maximum uncompressed size: ~1.89 / ~7.60 MiB. +.PP +Notes: +.PP +.Vb 6 +\& \- UPX creates as default a suitable executable for CD\-Mastering +\& and console transfer. For a CD\-Master main executable you could also try +\& the special option "\-\-boot\-only" as described below. +\& It has been reported that upx packed executables are fully compatible with +\& the Sony PlayStation 2 (PS2, PStwo) and Sony PlayStation Portable (PSP) in +\& Sony PlayStation (PSone) emulation mode. +\& +\& \- Normally the packed files use the same memory areas like the uncompressed +\& versions, so they will not override other memory areas while unpacking. +\& If this isn\*(Aqt possible UPX will abort showing a \*(Aqpacked data overlap\*(Aq +\& error. With the "\-\-force" option UPX will relocate the loading address +\& for the packed file, but this isn\*(Aqt a real problem if it is a single or +\& the main executable. +.Ve +.PP +Extra options available for this executable format: +.PP +.Vb 4 +\& \-\-all\-methods Compress the program several times, using all +\& available compression methods. This may improve +\& the compression ratio in some cases, but usually +\& the default method gives the best results anyway. +\& +\& \-\-8\-bit Uses 8 bit size compression [default: 32 bit] +\& +\& \-\-8mib\-ram PSone has 8 MiB ram available [default: 2 MiB] +\& +\& \-\-boot\-only This format is for main exes and CD\-Mastering only ! +\& It may slightly improve the compression ratio, +\& decompression routines are faster than default ones. +\& But it cannot be used for console transfer ! +\& +\& \-\-no\-align This option disables CD mode 2 data sector format +\& alignment. May slightly improves the compression ratio, +\& but the compressed executable will not boot from a CD. +\& Use it for console transfer only ! +.Ve +.SS "\s-1NOTES FOR RTM32/PE\s0 and \s-1ARM/PE\s0" +.IX Subsection "NOTES FOR RTM32/PE and ARM/PE" +Same as win32/pe. +.SS "\s-1NOTES FOR TMT/ADAM\s0" +.IX Subsection "NOTES FOR TMT/ADAM" +This format is used by the \s-1TMT\s0 Pascal compiler \- see http://www.tmt.com/ . +.PP +Extra options available for this executable format: +.PP +.Vb 4 +\& \-\-all\-methods Compress the program several times, using all +\& available compression methods. This may improve +\& the compression ratio in some cases, but usually +\& the default method gives the best results anyway. +\& +\& \-\-all\-filters Compress the program several times, using all +\& available preprocessing filters. This may improve +\& the compression ratio in some cases, but usually +\& the default filter gives the best results anyway. +.Ve +.SS "\s-1NOTES FOR VMLINUZ/386\s0" +.IX Subsection "NOTES FOR VMLINUZ/386" +The vmlinuz/386 and bvmlinuz/386 formats take a gzip-compressed +bootable Linux kernel image (\*(L"vmlinuz\*(R", \*(L"zImage\*(R", \*(L"bzImage\*(R"), +gzip-decompress it and re-compress it with the \fB\s-1UPX\s0\fR compression method. +.PP +vmlinuz/386 is completely unrelated to the other Linux executable +formats, and it does not share any of their drawbacks. +.PP +Notes: +.PP +.Vb 3 +\& \- Be sure that "vmlinuz/386" or "bvmlinuz/386" is displayed +\& during compression \- otherwise a wrong executable format +\& may have been used, and the kernel won\*(Aqt boot. +.Ve +.PP +Benefits: +.PP +.Vb 4 +\& \- Better compression (but note that the kernel was already compressed, +\& so the improvement is not as large as with other formats). +\& Still, the bytes saved may be essential for special needs like +\& boot disks. +\& +\& For example, this is what I get for my 2.2.16 kernel: +\& 1589708 vmlinux +\& 641073 bzImage [original] +\& 560755 bzImage.upx [compressed by "upx \-9"] +\& +\& \- Much faster decompression at kernel boot time (but kernel +\& decompression speed is not really an issue these days). +.Ve +.PP +Drawbacks: +.PP +.Vb 1 +\& (none) +.Ve +.PP +Extra options available for this executable format: +.PP +.Vb 4 +\& \-\-all\-methods Compress the program several times, using all +\& available compression methods. This may improve +\& the compression ratio in some cases, but usually +\& the default method gives the best results anyway. +\& +\& \-\-all\-filters Compress the program several times, using all +\& available preprocessing filters. This may improve +\& the compression ratio in some cases, but usually +\& the default filter gives the best results anyway. +.Ve +.SS "\s-1NOTES FOR WATCOM/LE\s0" +.IX Subsection "NOTES FOR WATCOM/LE" +\&\fB\s-1UPX\s0\fR has been successfully tested with the following extenders: + \s-1DOS4G, DOS4GW, PMODE/W,\s0 DOS32a, CauseWay. + The \s-1WDOS/X\s0 extender is partly supported (for details + see the file bugs \s-1BUGS\s0). +.PP +DLLs and the \s-1LX\s0 format are not supported. +.PP +Extra options available for this executable format: +.PP +.Vb 2 +\& \-\-le Produce an unbound LE output instead of +\& keeping the current stub. +.Ve +.SS "\s-1NOTES FOR WIN32/PE\s0" +.IX Subsection "NOTES FOR WIN32/PE" +The \s-1PE\s0 support in \fB\s-1UPX\s0\fR is quite stable now, but probably there are +still some incompatibilities with some files. +.PP +Because of the way \fB\s-1UPX\s0\fR (and other packers for this format) works, you +can see increased memory usage of your compressed files because the whole +program is loaded into memory at startup. +If you start several instances of huge compressed programs you're +wasting memory because the common segments of the program won't +get shared across the instances. +On the other hand if you're compressing only smaller programs, or +running only one instance of larger programs, then this penalty is +smaller, but it's still there. +.PP +If you're running executables from network, then compressed programs +will load faster, and require less bandwidth during execution. +.PP +DLLs are supported. But \s-1UPX\s0 compressed DLLs can not share common data and +code when they got used by multiple applications. So compressing msvcrt.dll +is a waste of memory, but compressing the dll plugins of a particular +application may be a better idea. +.PP +Screensavers are supported, with the restriction that the filename +must end with \*(L".scr\*(R" (as screensavers are handled slightly different +than normal exe files). +.PP +\&\s-1UPX\s0 compressed \s-1PE\s0 files have some minor memory overhead (usually in the +10 \- 30 KiB range) which can be seen by specifying the \*(L"\-i\*(R" command +line switch during compression. +.PP +Extra options available for this executable format: +.PP +.Vb 9 +\& \-\-compress\-exports=0 Don\*(Aqt compress the export section. +\& Use this if you plan to run the compressed +\& program under Wine. +\& \-\-compress\-exports=1 Compress the export section. [DEFAULT] +\& Compression of the export section can improve the +\& compression ratio quite a bit but may not work +\& with all programs (like winword.exe). +\& UPX never compresses the export section of a DLL +\& regardless of this option. +\& +\& \-\-compress\-icons=0 Don\*(Aqt compress any icons. +\& \-\-compress\-icons=1 Compress all but the first icon. +\& \-\-compress\-icons=2 Compress all icons which are not in the +\& first icon directory. [DEFAULT] +\& \-\-compress\-icons=3 Compress all icons. +\& +\& \-\-compress\-resources=0 Don\*(Aqt compress any resources at all. +\& +\& \-\-keep\-resource=list Don\*(Aqt compress resources specified by the list. +\& The members of the list are separated by commas. +\& A list member has the following format: I. +\& I is the type of the resource. Standard types +\& must be specified as decimal numbers, user types can be +\& specified by decimal IDs or strings. I is the +\& identifier of the resource. It can be a decimal number +\& or a string. For example: +\& +\& \-\-keep\-resource=2/MYBITMAP,5,6/12345 +\& +\& UPX won\*(Aqt compress the named bitmap resource "MYBITMAP", +\& it leaves every dialog (5) resource uncompressed, and +\& it won\*(Aqt touch the string table resource with identifier +\& 12345. +\& +\& \-\-force Force compression even when there is an +\& unexpected value in a header field. +\& Use with care. +\& +\& \-\-strip\-relocs=0 Don\*(Aqt strip relocation records. +\& \-\-strip\-relocs=1 Strip relocation records. [DEFAULT] +\& This option only works on executables with base +\& address greater or equal to 0x400000. Usually the +\& compressed files becomes smaller, but some files +\& may become larger. Note that the resulting file will +\& not work under Windows 3.x (Win32s). +\& UPX never strips relocations from a DLL +\& regardless of this option. +\& +\& \-\-all\-methods Compress the program several times, using all +\& available compression methods. This may improve +\& the compression ratio in some cases, but usually +\& the default method gives the best results anyway. +\& +\& \-\-all\-filters Compress the program several times, using all +\& available preprocessing filters. This may improve +\& the compression ratio in some cases, but usually +\& the default filter gives the best results anyway. +.Ve +.SH "DIAGNOSTICS" +.IX Header "DIAGNOSTICS" +Exit status is normally 0; if an error occurs, exit status +is 1. If a warning occurs, exit status is 2. +.PP +\&\fB\s-1UPX\s0\fR's diagnostics are intended to be self-explanatory. +.SH "BUGS" +.IX Header "BUGS" +Please report all bugs immediately to the authors. +.SH "AUTHORS" +.IX Header "AUTHORS" +.Vb 2 +\& Markus F.X.J. Oberhumer +\& http://www.oberhumer.com +\& +\& Laszlo Molnar +\& +\& John F. Reiser +\& +\& Jens Medoch +.Ve +.SH "COPYRIGHT" +.IX Header "COPYRIGHT" +Copyright (C) 1996\-2024 Markus Franz Xaver Johannes Oberhumer +.PP +Copyright (C) 1996\-2024 Laszlo Molnar +.PP +Copyright (C) 2000\-2024 John F. Reiser +.PP +Copyright (C) 2002\-2024 Jens Medoch +.PP +\&\fB\s-1UPX\s0\fR is distributed with full source code under the terms of the +\&\s-1GNU\s0 General Public License v2+; either under the pure GPLv2+ (see +the file \s-1COPYING\s0), or (at your option) under the GPLv+2 with special +exceptions and restrictions granting the free usage for all binaries +including commercial programs (see the file \s-1LICENSE\s0). +.PP +This program is distributed in the hope that it will be useful, +but \s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of +\&\s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0 +.PP +You should have received a copy of the \s-1UPX\s0 License Agreements along +with this program; see the files \s-1COPYING\s0 and \s-1LICENSE.\s0 If not, +visit the \s-1UPX\s0 home page. diff --git a/util/init.go b/util/init.go new file mode 100644 index 0000000..489c4f6 --- /dev/null +++ b/util/init.go @@ -0,0 +1,26 @@ +package util + +import ( + "os" + "path/filepath" +) + +// CreateDir 创建目录 +func CreateDir(dirPath string) bool { + err := os.Mkdir(dirPath, 0755) + return err == nil +} + +// CalcPercentage 计算percentage相对于total的百分比 +func CalcPercentage(percentage int, total int) int { + return int(float64(percentage) / float64(total) * 100) +} + +func GetFileNameWithoutExt(path string) string { + // 获取文件名(包含后缀) + filename := filepath.Base(path) + // 去除后缀 + ext := filepath.Ext(filename) + name := filename[:len(filename)-len(ext)] + return name +} diff --git a/vars/init.go b/vars/init.go new file mode 100644 index 0000000..8a80f40 --- /dev/null +++ b/vars/init.go @@ -0,0 +1,9 @@ +package vars + +var GlobalFilePathList []string // 所有文件的路径 +var GlobalFilePath2FileNameExtMap = make(map[string]string) // 文件路径和文件名称(包含后缀)的映射关系 +var GlobalFilePath2FileNameMap = make(map[string]string) // 文件路径和文件名称(不包含后缀)的映射关系 +var GlobalFilePath2FileExtMap = make(map[string]string) // 文件路径和文件扩展名的映射关系 + +var GlobalHEICFilePathNameMap = make(map[string]string) // 文件路径和HEIC文件名称的映射关系 +var GlobalMOVFilePathPathNameMap = make(map[string]string) // 文件路径和MOV文件名称的映射关系