自爆解凍プログラムの作り方

2001/01/04

始めに

  Windows Softでは時折見かける自爆解凍処理を作ってみたい。という事で考えてみた。 なお、圧縮アルゴリズムそのものについては、ここでは取り扱いしません。

● 主目的

  1. 自爆解凍機能付き圧縮プログラムのように、データファイルを抱き込んで実行形ファイルを作成する。
  2. 作成した実行形式ファイルを実行すると抱き込んでいたデータファイルを書き出す。

● 前準備

 Win32の実行ファイルというのはPEフォーマット(Portable Executable)で作成されており前段階に使われるオブジェクトファイルは COFF 形式であるということは比較的知られています。

 しかしCOFF やPE の詳細な仕様を入手しないと話は始まりません。という事で MicroSoft の技術資料を検索 します。

   ※ MS社は時々URLが変わりますので注意

     <http://www.microsoft.com/japan/developer/library/default.asp?URL=/japan/developer/library/jpspecs/platfrm/msspec.htm>

   ここで見つからなかったらlcc-win32 の付属資料も付属していたと記憶しています。

● MS-DOS の時代

 MS-DOSの時代にはEXE ファイルの最後に特定の目印を付けて物理的にファイルを連結するという方法がありました。
しかし、今は実行中のEXEファイルを書き換えるというのは許されていません。

    

● Windowsの時代の考察

 通常のデータ領域にファイルを書き込み保存するという方法は、静的にリンクが出来れば問題無いと思われるが、リロケーションヘッダを作り直ししたりする必要があるだろう。

 Windows 時代になってGUIの実行ファイルにはリソースセグメントが付くようになった。(PE的には特殊セグメント扱い)このリソースセグメントを動的に変更出来れば実行ファイルにファイルを抱かせる事が出来るのではないか? という事でAPI を調査してみた。

    ・ 解凍段階で必要と思われるAPI(リソースセグメントを読み込み)

番号

API名称

機能

FindResource()

特定名称(ID含む)のリソースを検索

LoadResource()

リソースをメモリ中に読み込み

SizeofResource()

対象リソースのサイズを取得

LockResource()

リソースにアドレス割り当て

FreeResource()

リソースの解放

    ・ 作成段階で必要と思われるAPI(リソースセグメントを書き換え)

番号

API名称

機能

BeginUpdateResource()

リソース更新の開始宣言

EndUpdateResource()

リソース更新の終了宣言

UpdateResource()

対象リソースを更新

 調査の結果、以下の方法で自爆解凍処理で行えそうです。

  1. GUIモードで作成したEXE に「ユーザー定義リソース」を抱かせる。 実行ファイルはユーザー定義リソースをファイルとして書き出す。
  2. もう一つのプログラムが「ユーザー定義リソース」を書き換える。
 イメージにすると以下のようになります。

    

● で、試作

  1. 自爆解凍側のソースと実行形式  TARGETPG.LZH
  2. 書き換え側のソースと実行形式  CHGTARGET.LZH
説明はめんどくさくなったので無しっていうかソースみて:-)

● 補足説明

  1. 「リロケーションヘッダ」とは、

    通常の実行ファイルってのは、マシンコードやデータをメモリイメージで格納 している訳ではなく再配置が可能な状況で保持しています。そのための再配置 情報を指します。(COM形式とか再配置情報が無いものも存在します)

  2. 「リソース」とは

    COFF からみれば特殊セグメントの一種ですが、Windowsではこれを拡張し、 検索して読み込みする事が可能になっています。つまり通常のデータセグメント と異なり読み込み指示を明確に与えなければメモリ中に実体化することはありま せん。

  3. なぜ「ユーザー定義リソースを書き換える」のか

    実行ファイルを作るには通常リンカが必要ですが、「リソースセグメント」は 専用APIがあるので自由に書き換え出来ます。ただし DIALOGにしても ICON に してもデータの形式はシステム上定義されていますので勝手なフォーマットに 書くわけにはいけません。

    「ユーザー定義リソース」ってのは名前の通り、システムはデータタイプ、 名称、サイズのみを管理して、内容については一切管理しないものです。 ですから、そこには tar形式だろうとRPM形式だろうと自由に書けますので それを使って自爆解凍を行うのです。