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
© Copyright 2024 Paperzz