今天我們來學習一款給應用加殼的軟件,叫做upx(the Ultimate Packer for eXecutables)
首先我們先看下它**百科的釋義:
UPX (the Ultimate Packer for eXecutables)是一款先進的可執行程序文件壓縮器,壓縮過的可執行文件體積縮小50%-70% ,這樣減少了磁盤占用空間、網絡上傳下載的時間和其它分布以及存儲費用。 通過 UPX 壓縮過的程序和程序庫完全沒有功能損失和壓縮之前一樣可正常地運行,對于支持的大多數格式沒有運行時間或內存的不利后果。 UPX 支持許多不同的可執行文件格式 包含 Windows 95/98/ME/NT/2000/XP/CE 程序和動態鏈接庫、DOS 程序、 Linux 可執行文件和核心。
那么百科的釋義呢很簡單,主要有兩點,一個是加殼,一個是壓縮。
小試牛刀
先準備好材料
//hello.cpp
#include <iostream>
using namespace std;
int main() {
int i = 10;
for(;i > 0;i--) {
cout<<"hello,i = "<<(10 - i)<<endl;
}
return 0;
}
還是熟悉的配方。好,那么我們upx一下
$ g++ hello.cpp -o hello.out
$ upx hello.out -o hello.upx.out
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2017
UPX 3.94 Markus Oberhumer, Laszlo Molnar & John Reiser May 12th 2017
File size Ratio Format Name
-------------------- ------ ----------- -----------
upx: hello.strip.out: NotCompressibleException
Packed 1 file: 0 ok, 1 error.
$
那么是什么問題呢,我上網找了一下。原來是upx不支持太小的文件。小于40kb的文件就不支持了。
好,那么本文就到此結束啦,謝謝大家的觀看。
再次嘗試
等等,我輩豈是如此輕言放棄之人。
//hello.go
package main
import "fmt"
func main() {
i := 10
for ; i > 0; i-- {
fmt.Printf("hello,i = %d\n",(10 - i))
}
}
然后編譯
$ go build hello.go
$ ls -l
total 2040
-rwxr-xr-x 1 root root 2080925 Jul 13 03:12 hello
-rw-r--r-- 1 root root 141 Jul 13 03:00 hello.go
$
那么我們得到了一個20M的可執行文件,讓我們來upx一下它
$ upx hello -o hello.upx.out
$ ls -l
total 4592
-rwxr-xr-x 1 root root 2080925 Jul 13 03:12 hello
-rw-r--r-- 1 root root 141 Jul 13 03:00 hello.go
-rwxr-xr-x 1 root root 1143336 Jul 13 03:23 hello.upx.out
$
嗯,確實小了不少,upx處理后,變成了11M;看小減少了百分之多少。
(2080925-1143336)/2080925≈45.07%
嗯,比strip多一點。
那么看看,能不能再strip
$ strip hello.upx.out -o hello.upxs.out
strip: error: the input file 'hello.upx.out' has no sections
$
那么我們分析一下應該不難得知,upx把殼給加上了,導致strip找不到那些標記
反向操作
那么呢,我們是不能把這個過程給反一下。是不是就可以了呢
好,那么說干就干
$ strip hello -p -o hello.s.out
$ ls -l
total 4592
-rwxr-xr-x 1 root root 2080925 Jul 13 03:12 hello
-rw-r--r-- 1 root root 141 Jul 13 03:00 hello.go
-rwxr-xr-x 1 root root 1463768 Jul 13 03:23 hello.s.out
-rwxr-xr-x 1 root root 1143336 Jul 13 03:23 hello.upx.out
$ upx hello.s.out -o hello.su.out
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2017
UPX 3.94 Markus Oberhumer, Laszlo Molnar & John Reiser May 12th 2017
File size Ratio Format Name
-------------------- ------ ----------- -----------
1463768 -> 574340 39.24% linux/amd64 hello.su.out
Packed 1 file.
$ ls -l
total 5156
-rwxr-xr-x 1 root root 2080925 Jul 13 03:12 hello
-rw-r--r-- 1 root root 141 Jul 13 03:00 hello.go
-rwxr-xr-x 1 root root 1463768 Jul 13 03:23 hello.s.out
-rwxr-xr-x 1 root root 574340 Jul 13 03:23 hello.su.out
-rwxr-xr-x 1 root root 1143336 Jul 13 03:23 hello.upx.out
$
嗯,很好。套娃成功
看下減少了多少,1-574340/2080925≈72.40%
那么這個減少的量是比較多的,讓我們來看看可以運行嗎
$ ./hello.su.out
hello,i = 0
hello,i = 1
hello,i = 2
hello,i = 3
hello,i = 4
hello,i = 5
hello,i = 6
hello,i = 7
hello,i = 8
hello,i = 9
$
那么我們可以看到,這個是可以正常運行的。
繼續研究
那么我們來看看upx可以帶哪些選項吧,
$ upx
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2017
UPX 3.94 Markus Oberhumer, Laszlo Molnar & John Reiser May 12th 2017
Usage: upx [-123456789dlthVL] [-qvfk] [-o file] file..
Commands:
-1 compress faster -9 compress better
-d decompress -l list compressed file
-t test compressed file -V display version number
-h give more help -L display software license
Options:
-q be quiet -v be verbose
-oFILE write output to 'FILE'
-f force compression of suspicious files
-k keep backup files
file.. executables to (de)compress
Type 'upx --help' for more detailed help.
UPX comes with ABSOLUTELY NO WARRANTY; for details visit https://upx.github.io
$
命令:
有1到9的壓縮等級;
-d 不壓縮;
-l 列出壓縮的文件;
-t 測試壓縮文件;
-h 顯示幫助文檔
-V 顯示版本號
-L 顯示軟件許可證
選項:
-q 安靜模式
-v 詳細模式
-o 大家都懂,輸出到文件
-f 強制壓縮可以的文件
-k 保持備份文件
嗯, 好像沒有什么值得深究的功能, 這個壓縮等級大家可以按照自己的需要去調整。
好,就這樣。
總結
最后我們來總結一下
首先這個upx之后的東西,嗯,它的時間戳還是保留之前的
然后呢,upx操作之后呢,這個sections會變得面目全非。所以再去strip呢,就不行了
所以我們需要采取反向操作先strip然后再upx
然后呢就是壓縮的等級,-1是優先速度,-9是優先質量。那么中間的按照這個去推斷。
好了,本文到這里就結束啦,如果喜歡這篇文章,記得點贊。謝謝