汎用SFX

仕事で自己解凍形式(SFX)のプログラムを作らなければならなくなったので、実現方法を調べてみました。わかってみれば非常に簡単なことでした。説明するよりソースファイルを見たほうが早いので紹介します。

ソースファイル

#include <stdio.h>
#include <stdlib.h>

// 自己解凍プログラムのサイズ(一度コンパイルしてから直す)
#define SIZE 3748

int main(int argc, char** argv) {
    FILE* fp;
    int file_size;
    char* file;
    
    // ファイルを開く
    fp = fopen(argv[0], "rb");
    if (fp == NULL) {
        return (-1);
    }
    
    // 全体のファイルのサイズを得る
    fseek(fp, 0, SEEK_END);
    file_size = ftell(fp);
    fseek(fp, 0, 0);
    
    // データ部分に移動して読み込む
    fseek(fp, SIZE, 0);
    file = (char*)malloc(file_size - SIZE);
    fread(file, (file_size - SIZE), 1, fp);
    fclose(fp);
    
    // TODO:解凍する
    
    // output.datにデータ部分を書き出す
    fp = fopen("./output.dat", "wb");
    if (fp == NULL) {
        free(file);
        return (-1);
    } else {
        fwrite(file, file_size - SIZE, 1, fp);
        fclose(fp);
        free(file);
    }
    
    return 0;
}

実行方法

gcc -o sfx -Wall sfx.c (1度目のコンパイル)
strip sfx (実行ファイルのコンパクト化)
ls -l sfx (ファイルサイズをチェックする)
vi sfx.c (ファイルサイズを直す)
gcc -o sfx -Wall sfx.c (2度目のコンパイル)
strip sfx(実行ファイルのコンパクト化)
cat sfx hoge.txt > fuga (自己解凍プログラム+データ)
chmod +x fuga
./fuga (試しに実行してみる)
cat hoge.txt (ちゃんと解凍できたか確認)

解凍方法は圧縮形式しだいでしょうから割愛します。特別なライブラリーを使っているわけではないのでLinuxに限らずWindowsでも何の問題もなく動くはずです。Windowsコマンドプロンプトでは以下のようにするらしいです。

copy /b sfx.exe+hoge.txt > fuga.exe