Executable Packerの構造と解釈

Executable Packerの構造と解釈
Structure and Interpretation of Executable Packers
301
Tokyo Demo Fest 2011
目次
•
•
•
•
•
•
DropperとPacker
Windows PE Loader
圧縮されたPE
より小さくするために
悩ましい問題
参考資料
DropperとPacker (1/2)
Dropperとは、
• テンポラリファイルに出力したEXEをディスクから起動
– Self-Extracting Zip File
– 20to4
• 起動にかかるコードが小さく実装も容易
• 大会規約によってはHDDへの書き込みは禁止
– かつてのAssembly、近年のFunctionなど
DropperとPacker (2/2)
Packerとは、
• 圧縮展開から起動までを全てオンメモリで行う
– kkrunchy
– Crinkler
• OSに対する理解力が要求され実装は面倒
• ストレージを汚さない
– デモシーンでの主流はこちら
Windows PE Loader (1/2)
EXEファイル(Portable Executable)の情報を基に、
1.
2.
3.
メモリを確保
コードやデータを実効アドレス上にコピー
インポート関数群を解決
push GL_TRIANGLE_STRIP
call [glBegin]
…
glBegin dd ????????
4.
GetProcAddress(hOpenGL32, “glBegin”);
エントリポイントにジャンプ
Windows PE Loader (2/2)
Portable Executable (PE)
Process Memory
0x401000
NT Headers
Imports = 0x402000
Entry = 0x401200
Section Header #1
Dest = 0x401000 to 0x402000
Src = Your Code
Your Code
0x402000
Your Data
Section Header #2
Dest = 0x402000 to 0x404000
Src = Your Data
Your Code
Your Uninitialized Data
Your Data
0x404000
圧縮されたPE (1/4)
メモリのどこかに何かを書き込んだあと、
ちょっとごそごそしてからそこにジャンプするアプリケーション
• Your CodeやYour Dataがあるべき場所に
• 圧縮しておいたYour CodeやYour Dataを伸長しつつ書き込んで
• 自力でインポート関数群を解決し
– 伸長コードに制御が移った時点でPE Loaderの仕事は済んでいる
• 元のエントリポイントのアドレスにジャンプ
圧縮されたPE (2/4)
typedef void YourCode();
const uint8_t compressedYourCode[] = {...};
const uint8_t compressedYourData[] = {...};
void decompress(uintptr_t dest, const void *src);
void fixupImports(uintptr_t imports);
void entryPoint()
{
decompress(0x401000, compressedYourCode);
decompress(0x402000, compressedYourData);
fixupImports(0x402000);
((YourCode *)0x401020)();
}
圧縮されたPE (3/4)
Compressed PE
Process Memory
0x301000
NT Headers
Imports = Don’t Care
Entry = 0x301000
Decruncher
Section Header #1
Dest = 0x301000 to 0x404000
Src = Decruncher
Decruncher
0x404000
圧縮されたPE (4/4)
Process Memory
0x301000
Entry Point
Decruncher
1.
2.
3.
4.
Extract ‘Your Code’
Extract ‘Your Data’
Fix up Imports
Jump into ‘Your Code’
0x401000
Your Code
0x402000
Your Data
Your Uninitialized Data
0x404000
より小さくするために (1/2)
• 伸長後処理はユーザーコードに混ぜて一緒に圧縮
– インポート解決など
• 圧縮率と伸長コードサイズの見極め
– Cabinet API(20to4)
– D3DXCreateTextureFromFileInMemoryEx(1kpack)
– aPLib(MEW, NPX)
– PAQ variants(kkrunchy, Crinkler)
• マシンコードを圧縮されやすい状態に加工
– コールの相対アドレスを絶対アドレスへ変換
– disfilter(ryg/farbrausch)
より小さくするために (2/2)
やりすぎた人たち
• もっと気に入るEXEを生成するためにリンカから作る
– Crinkler
• もっと気に入るコードを生成するためにコンパイラから作る
– IL4 Lisp-ahtava
http://xmunkki.org/wiki/doku.php?id=projects:il4
悩ましい問題
• OSバージョン毎の動作互換性
– 非公開機能への依存
– ファイルヘッダの過度な加工
• セキュリティソフトウェアの過保護
– ウィルスと似た構造
– 暗号性によるマルウェア配布への利用
– Packer.Krunchy.A
– packers/compressors & security & malware & webhosting
http://www.pouet.net/topic.php?which=7399
参考資料
•
•
•
•
•
•
•
Executable Packing
http://gem.intro.hu/executable_packing.htm
Portable Executable Loaders and Wrappers
http://www.cultdeadcow.com/tools/pewrap.html
Linkers and Loaders
http://linker.iecc.com/
Inside Microsoft® Windows® 2000, Third Edition
http://www.microsoft.com/mspress/books/4354.aspx
Data Compression Programs
http://cs.fit.edu/~mmahoney/compression/
ryg's Homepage
http://www.farb-rausch.de/~fg/
Crinkler secrets, 4k intro executable compressor at its best
http://code4k.blogspot.com/2010/12/crinkler-secrets-4k-intro-executable.html
質問?
http://twitter.com/301z