ア | イ | ウ | エ | オ |
カ | キ | ク | ケ | コ |
サ | シ | ス | セ | ソ |
タ | チ | ツ | テ | ト |
ナ | ニ | ヌ | ネ | ノ |
ハ | ヒ | フ | ヘ | ホ |
マ | ミ | ム | メ | モ |
ヤ | ユ | ヨ | ||
ラ | リ | ル | レ | ロ |
ワ | ヰ | ヴ | ヱ | ヲ |
ン |
A | B | C | D | E |
F | G | H | I | J |
K | L | M | N | O |
P | Q | R | S | T |
U | V | W | X | Y |
Z | 数字 | 記号 |
ファイルアーカイバ、LHAで使われているファイルフォーマット(コンテナーフォーマット)の俗称。
LHAが使うコンテナーフォーマットは、LArcのものの拡張である。
基本的には各ファイルごとに、次の構造になる。
[ヘッダー1][データ1][ヘッダー2][データ2]…[ヘッダーn][データn][00h]
ヘッダーは格納ファイルに常にあるが、データは無いことがある。LHA v2.14以降で対応した-lhd-(ディレクトリ名の格納)は、データサイズ0でありデータがない。
ヘッダーの最初の1バイトは基本ヘッダーそのものの長さとなっている。ここが00hとなると、それがファイル末端であることを表わす。
ヘッダーは、次のような構造をしている。
[基本ヘッダー][拡張ヘッダー1][拡張ヘッダー2]…[拡張ヘッダーn][0000h]
LHAのヘッダー形式はLEVEL 0/1/2の三種類がある。略してH0/H1/H2のように呼ばれる。LArcおよびLHarc(LHA 1.xx)はLHAでいうLEVEL 0に対応し、LEVEL 1/2はLEVEL 0の拡張である。
拡張ヘッダーはLEVEL 1/2で対応し、LEVEL 0には存在しない。
拡張ヘッダーの最初の2バイトは拡張ヘッダーそのものの長さとなっている。ここが0000hとなると、それが拡張ヘッダー末端であることを表わし、この後に(あれば)データが続く。
「基本ヘッダー」は、ファイルの基本的な情報を記録する領域である。タイムスタンプ、CRCなどはここにある。
「拡張ヘッダー」は、付加的な情報を格納するために使われる。この数も任意で、複数のヘッダーを持つことも可能。
なお、WORD以上の長さを持つパラメーターは、リトルエンディアンで値が格納される。
最も古い形式の基本ヘッダーで、LArc用に作られ使われた。LHarcもこの形式で、LHAであってもDOS版の自己解凍書庫はこのヘッダー形式である。
1バイト目が基本ヘッダーの長さで、最大255なので、実際の基本ヘッダー長の最大長は257バイトということになる。
位置 | サイズ | 内容 |
---|---|---|
00h | BYTE | 基本ヘッダー長(これ自身と拡張データ長を除く) |
01h | BYTE | ヘッダーのチェックサム(02hから基本ヘッダー長分の単純和 下位8ビット) |
02h | 5BYTE | 圧縮方法 ("-lh5-"などの文字列) |
07h | DWORD | 圧縮後のデータ長 |
0Bh | DWORD | 元のファイルサイズ |
0Fh | WORD | ファイルの更新時刻 (MS-DOS形式) |
11h | WORD | ファイルの更新日付 (MS-DOS形式) |
13h | BYTE | ファイル属性 (MS-DOS形式) |
14h | BYTE | 00h=ヘッダーのレベル |
15h | BYTE | ファイル名の長さ (最大233バイト) |
16h | nBYTE | ファイル名 (最大233バイト、パスも含む) |
WORD | 格納ファイル(圧縮前)のCRC | |
nBYTE | 拡張データ(無い場合もある) |
ファイル名はパスも含む。パスのデリミター文字は、'\'か'/'である。ASCIIZではないので、末端にNULは無い。
ヘッダー全体の長さが最大257バイトであるため、逆算してファイル名・パス名の最大長は233バイトになる。
拡張データは通常使われないが、UNIX版LHaでは、ファイル属性、ファイル更新日時、UID/GID属性などOSに必要な情報を格納しているとされる。UNIX関係の情報は、LEVEL 1では正規の方法で格納可能になった。
LHA 2.1x〜2.5xで標準となっているもの。拡張ヘッダーが追加され、付加的な情報はそちらに回されている。
基本ヘッダーの構造は次の通りである。
位置 | サイズ | 内容 |
---|---|---|
00h | BYTE | 基本ヘッダー長 |
01h | BYTE | ヘッダーのチェックサム(02hから基本ヘッダー長分の単純和 下位8ビット) |
02h | 5BYTE | 圧縮方法 ("-lh5-"などの文字列) |
07h | DWORD | 圧縮後のデータ長+拡張ヘッダー長の合計 |
0Bh | DWORD | 元のファイルサイズ |
0Fh | WORD | ファイルの更新時刻 (MS-DOS形式) |
11h | WORD | ファイルの更新日付 (MS-DOS形式) |
13h | BYTE | 20h ダミーのファイル属性 (互換用) |
14h | BYTE | 01h=ヘッダーのレベル |
15h | BYTE | ファイル名の長さ (最大230バイト、0の場合は拡張ヘッダーに格納) |
16h | nBYTE | ファイル名 (最大230バイト、パスは含まない) |
WORD | 格納ファイル(圧縮前)のCRC | |
BYTE | OS識別子 (詳細後述) | |
nBYTE | 拡張データ(無い場合もある) |
基本ヘッダー長は、LEVEL 0の時と異なり、拡張ヘッダーの終端を表わすWORDの2バイト分が含まれる。
チェックサムのロジックはLEVEL 0と同じだが、02hから基本ヘッダー長分までなので、最初の拡張ヘッダーの拡張ヘッダー長2バイトまでが計算の対象となる。
LEVEL 1/2共通の拡張ヘッダーの基本構造は次の通り。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | この拡張ヘッダー長 |
02h | BYTE | この拡張ヘッダーの種類 |
03h | nBYTE | この拡張ヘッダーのデータ |
拡張ヘッダーの種類は、OSに非依存(00h〜3fh)か依存(40h〜7fh)かで分類されており、様々なものがある。実装は、未対応のものは読み飛ばす。
これ以外に、実装独自拡張の拡張ヘッダーもあるらしい。
ファイル名の長さ=0の場合、次の拡張ヘッダーにファイル名を格納する。これにより、非常に長いファイル名も格納可能になった。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 拡張ヘッダー長 (ファイル名の長さ+3) |
02h | BYTE | 01h ファイル名ヘッダー |
03h | nBYTE | ファイル名 (シフトJIS) |
ディレクトリ指定がある時のみ、次の拡張ヘッダーがある。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 拡張ヘッダー長 (ディレクトリ名の長さ+3) |
02h | BYTE | 02h ディレクトリ名ヘッダー |
03h | nBYTE | ディレクトリ名 (シフトJIS、パスのデリミターはFFh) |
MS-DOSのファイル属性が20h以外の時のみ、次の拡張ヘッダーがある。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 拡張ヘッダー長 (ディレクトリ名の長さ+3) |
02h | BYTE | 40h MS-DOSファイル属性ヘッダー |
03h | WORD | MS-DOSファイル属性 |
拡張ヘッダーがある場合は、拡張ヘッダーのCRCを格納する次の拡張ヘッダーがある。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 拡張ヘッダー長 (0005h または 0006h) |
02h | BYTE | 00h 共通ヘッダー |
03h | WORD | ヘッダーのCRC (基本ヘッダー/拡張ヘッダー全体の) |
05h | BYTE | 付加情報 (無い場合もある) |
ヘッダーのCRCは、まずCRC領域を0000hとして、基本ヘッダーの先頭から拡張ヘッダー終端を表わすWORDの0000hまでを計算する。実際に照合する場合も、ここを0000hと想定し、最後にこの領域と比較することになる。ヘッダー最後の付加情報は仕様が未確定である。
拡張ヘッダー列の終端には、次のヘッダーがある。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 0000h |
LHA 2.6x以降、UNLHA32.DLLで標準となっている形式。
タイムスタンプの格納形式が変更された他、基本ヘッダーの構造が整理されている。
ファイル名については、常に拡張ヘッダーに格納されるようになった。
基本ヘッダーの構造は次の通りである。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | ヘッダー長 (この領域からデータ部直前までの長さ) |
02h | 5BYTE | 圧縮方法 ("-lh5-"などの文字列) |
07h | DWORD | 圧縮後のデータ長 |
0Bh | DWORD | 元のファイルサイズ |
0Fh | DWORD | ファイルの更新時刻 (time_t形式) |
13h | BYTE | 20h ダミーのファイル属性 (互換用) |
14h | BYTE | 02h=ヘッダーのレベル |
15h | WORD | 格納ファイル(圧縮前)のCRC |
17h | BYTE | OS識別子 (詳細後述) |
基本的にLEVEL 1と同じ。以下の4つは、同じなので再度の説明を略す。
拡張ヘッダー列の終端には、同様に次のヘッダーがあるが、若干仕様が違う。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 0000h |
02h | BYTE | ダミー |
基本ヘッダー先頭から、終端ヘッダー末の0000hまでの長さが256の倍数の時、ダミーの1バイトを追加し、ヘッダーサイズを1バイト増やす。
これは、ヘッダー長が256の倍数になると下位1バイトが00hとなってしまい、ファイル終端と区別が付かなくなるためで、これを回避する目的がある。
UNLHA32.DLLにはLEVEL 3のヘッダーがあることが知られているが、使われていない。
基本ヘッダーの仕様が若干異なるほか、拡張ヘッダーの仕様も変更されており、拡張ヘッダー長領域がDWORDに拡張されている。
LEVEL 3では、LEVEL 2に加え、次の拡張ヘッダーが利用できる。
UNLHA32.DLL ver 2.39a以降で、Unicodeファイル名にも対応した。
ファイル名とディレクトリ名について、それぞれ拡張ヘッダーが用意されている。
Unicodeファイル名は、次のヘッダーに格納する。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 拡張ヘッダー長 (ファイル名の長さ+3) |
02h | BYTE | 44h ファイル名ヘッダー (UTF-16LE) |
03h | nWORD | ファイル名 (UTF-16LE) |
Unicodeディレクトリ名は、次のヘッダーに格納する。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 拡張ヘッダー長 (ディレクトリ名の長さ+3) |
02h | BYTE | 45h ディレクトリ名ヘッダー (UTF-16LE) |
03h | nWORD | ファイル名 (UTF-16LE) |
シフトJISで扱えない文字を含む場合はUnicodeファイル名として保存される。
この場合、従来のファイル名ヘッダー(01h)、ディレクトリ名ヘッダー(02h)は使用されないため、未対応のソフトウェアでは正しく扱えないアーカイブができてしまうことになる。
UNIXでは、UNIXのファイル属性等を保存する必要があり、そのための拡張ヘッダーが用意されている。
UNIX用の実装LHaで使われているが、下記のうち、グループ名ヘッダーとユーザー名ヘッダーは実際には使われていない。
パーミッション情報は、次のヘッダーに格納する。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 拡張ヘッダー長 (0005h) |
02h | BYTE | 50h UNIX パーミッションヘッダー |
03h | WORD | パーミッション情報 |
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 拡張ヘッダー長 (0007h) |
02h | BYTE | 51h UNIX UID/GIDヘッダー |
03h | WORD | GID |
05h | WORD | UID |
グループ名は、次のヘッダーに格納できるが、使われていない。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 拡張ヘッダー長 (グループ名の長さ+3) |
02h | BYTE | 52h UNIX グループ名ヘッダー |
03h | nBYTE | グループ名 |
ユーザー名は、次のヘッダーに格納できるが、使われていない。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 拡張ヘッダー長 (ユーザー名の長さ+3) |
02h | BYTE | 53h UNIX ユーザー名ヘッダー |
03h | nBYTE | ユーザー名 |
最終更新日時は、次のヘッダーに格納する。
位置 | サイズ | 内容 |
---|---|---|
00h | WORD | 拡張ヘッダー長 (0007h) |
02h | BYTE | 54h UNIX 最終更新日時ヘッダー |
03h | DWORD | 最終更新日時 (time_t形式) |
UNIXのシンボリックリンクは、ディレクトリ名と同様、-lhd-形式で格納される。
ディレクトリ名の格納と殆ど同じだが、ディレクトリ名を格納する所に「シンボリックリンクファイル名|リンク先」という形式で文字列が格納される。
計算に使われるCRCは、一般的な16ビットのCRC-16、多項式11000000000000101(x16+x15+x2+x0)である。
LEVEL 1以降の基本ヘッダーにある1バイトの領域に、OSの情報を書き込むことができる。公式なものと非公式なものがあるとされる。
Windowsでも、OS識別子はMS-DOSの'M'がそのまま使われている。
LHAに限ったことではないが、LHAの実装の多くにはセキュリティ面での脆弱性があり、特にバッファーオーバーフロー脆弱性を持つものが多い。
例えば、拡張ヘッダーID 0x01(ファイル名)や0x02(パス名)に長い名前が格納された場合、バッファーオーバーフローが発生する実装がある。
それだけではなく、ヘッダー処理自体でバッファーオーバーフローを発生させる恐れもある。
LHAの基本ヘッダーは最大でも257バイトであり、これ以上に伸びることはない。一方で拡張ヘッダーは理論上64Kiバイト程度まで存在できる(H2の場合)ものの、多くの実装(純正版LHA含む)では4Kiバイト程度しかバッファを確保していない。
通常の用途で拡張ヘッダーが4Kiバイトを超えることは無いが、悪意を持ってヘッダーを細工し、巨大な拡張ヘッダーを作ることは可能で、このためバッファーオーバーフローを誘発させることが可能となる。
こういった悪意あるLZHファイルは、殆どのウイルス対策ソフトでは検疫できない。LHAフォーマットに充分に対応していないからである。
UNLHA32.DLLの作者Miccoによると、脆弱性情報の公開については、ZIP、CAB、7-Zipでは進んでいるが、LHAでは後れをとっており更に今後も望むことができない、とする。このため、安全のためにLZH書庫は(特に企業では)利用を自粛し、ゲートウェイ形式で検疫をしている場合はLZH書庫自体の拒絶をするべきとした注意喚起を2010(平成22)年6月5日に発表した。
また、UNLHA32.DLLは、UNARJ32.DLL、LHMeltと共に開発を中止するとしている。
コメントなどを投稿するフォームは、日本語対応時のみ表示されます