ファイル構造の概要

ファイルの種類の紹介

ファイル形式 (またはファイルの種類) は、コンピューターが情報を格納するために使用する特別なエンコード方法を指し、内部に格納されたデータを識別するために使用されます。たとえば、写真を保存するもの、プログラムを保存するもの、テキスト情報を保存するものがあります。各タイプの情報は、1 つまたは複数のファイル形式でコンピューター ストレージに保存できます。通常、各ファイル形式には、識別に使用できる 1 つ以上の拡張子がありますが、拡張子がない場合もあります。拡張子は、アプリケーションがファイル形式を認識するのに役立ちます。

ハード ドライブまたは任意のコンピューター ストレージの場合、有効な情報は 0 と 1 のみです。したがって、コンピューターは、情報からビットへの変換に対応する方法で設計する必要があります。さまざまな情報に対してさまざまなストレージ形式があります。

一部のファイル形式は、特別なデータを保存するように設計されています. たとえば、画像ファイルの JPEG ファイル形式は静止画像の保存にのみ使用されますが、GIF は静的画像と単純なアニメーションの両方を保存できます. Quicktime 形式は複数の異なるメディアタイプを保存できます. テキスト ファイルには、通常、単純でフォーマットされていない ASCII または Unicode テキストのみを格納する txt ファイル、フォーマットされたテキストを格納できる HTML ファイル、リッチ コンテンツおよび豊富な画像とテキストを含むテキストを格納できる PDF フォーマットがあります。

異なるプログラムで処理された同じファイル形式でも、まったく異なる結果が生成される場合があります。たとえば、Microsoft Word で Word ファイルを表示すると、テキストの内容が表示されますが、フォーマットされていない状態で音楽プレーヤー ソフトウェアで再生すると、ノイズが発生します。一部のソフトウェアにとって意味のある結果を生成するファイル形式は、他のソフトウェアにとっては役に立たないデジタルゴミのように見える場合があります。

拡張子を持つファイル形式を識別する方法は、Digital Equipment Corporation の CP/M オペレーティング システムで最初に採用されました。その後、DOS および Windows オペレーティング システムで採用されました。拡張子は、ファイル名の最後のドット (.) の後の一連の文字です。たとえば、HTML ファイルは .htm または .html 拡張子で識別され、GIF グラフィック ファイルは .gif 拡張子で識別されます。

また、さまざまなファイル形式がマシンによってどのように認識されるのでしょうか? 結局、デスクトップの接尾辞を (.txt) から (.jpg) に変更しました. ドキュメントを画像に変更しましたが、この時点でダブルクリックして開いても画像が表示されないことは誰もが知っています. . では、コンピュータはどのようにしてこのファイルが何であるかを判断するのでしょうか? 実際、さまざまなファイル形式には独自のファイル形式フラグがあります。ファイルの先頭には、ファイルに対応する記号があり、ファイルの種類を特定します。ファイルのタイプを判別した後、対応するタイプのファイル形式に従って次のコンテンツが解析されます。16 進エディタを使用すると、これらすべてを確認できます。

一般的なファイル形式フラグ:

PE(exe,dll)文件头:4D5A

JPEG (jpg),文件头:FFD8FF

PNG (png),文件头:89504E47

GIF (gif),文件头:47494638

TIFF (tif),文件头:49492A00

Windows Bitmap (bmp),文件头:424D

CAD (dwg),文件头:41433130

Adobe Photoshop (psd),文件头:38425053

Rich Text Format (rtf),文件头:7B5C727466

XML (xml),文件头:3C3F786D6C

HTML (html),文件头:68746D6C3E

Email [thorough only] (eml),文件头:44656C69766572792D646174653A

Outlook Express (dbx),文件头:CFAD12FEC5FD746F

Outlook (pst),文件头:2142444E

MS Word/Excel (xls.or.doc),文件头:D0CF11E0

MS Access (mdb),文件头:5374616E64617264204A

WordPerfect (wpd),文件头:FF575043

Postscript (eps.or.ps),文件头:252150532D41646F6265

Adobe Acrobat (pdf),文件头:255044462D312E

Quicken (qdf),文件头:AC9EBD8F

Windows Password (pwl),文件头:E3828596

ZIP Archive (zip),文件头:504B0304

RAR Archive (rar),文件头:52617221

Wave (wav),文件头:57415645

AVI (avi),文件头:41564920

Real Audio (ram),文件头:2E7261FD

Real Media (rm),文件头:2E524D46

MPEG (mpg),文件头:000001BA

MPEG (mpg),文件头:000001B3

Quicktime (mov),文件头:6D6F6F76

Windows Media (asf),文件头:3026B2758E66CF11

MIDI (mid),文件头:4D546864

PE ファイル構造

PE (Portable Execute) ファイルは、Windows で実行可能なファイルの総称で、DLL、EXE、OCX、SYS などが一般的です。 DOS ヘッダー、NT ヘッダー、セクション テーブル、および特定のセクションです。

1.DOSヘッダー

DOS ヘッダーの役割は、MS-DOS オペレーティング システムの実行可能ファイルと互換性を持たせることです.32 ビット PE ファイルの場合、DOS の役割は、テキスト行を表示して、ユーザーにプロンプ​​トを表示することです: I need to run on 32 -ビット ウィンドウ。無効になっているようには見えないので、それは良い冗談だと思います.DOSでユーザーが期待することを実行しないだけです.まあ、それがポイントではないことを認めます. しかし、少なくとも、このヘッダーがどのように定義されているかを見てみましょう。

注目する必要があるのは、次の 2 つのドメインだけです。

e_magic: WORD タイプ、値は定数 0x4D5A です。テキスト エディタを使用して「MZ」の値を表示します。実行可能ファイルはすべて「MZ」で始まる必要があります。

e_lfanew: 32 ビット実行可能ファイル用に拡張されたフィールドで、ファイル開始アドレスに対する DOS ヘッダーの後の NT ヘッダーのオフセットを示すために使用されます。

二、NTヘッド

DOS ヘッダーの e_lfanew に続いて、次のように定義された 32 ビット PE ファイルで最も有用なヘッダーである NT ヘッダーを簡単に見つけることができます。


次の図は、実際の PE ファイルのヘッダー構造と各フィールドの値です。


署名: DOS ヘッダーの e_magic と同様に、上位 16 ビットは 0、下位 16 ビットは 0x4550、文字表現は「PE」です。

IMAGE_FILE_HEADER は PE ファイルのヘッダーで、c 言語の定義は次のとおりです。

各フィールドの具体的な意味は次のとおりです。

マシン: ファイルのオペレーティング プラットフォーム (x86、x64、I64 など) は、次のいずれかの値になります。


NumberOfSections: PE ファイルにあるセクションの数、つまり、セクション テーブル内のアイテムの数。

TimeDateStamp: PE ファイルの作成時刻。通常はコネクタによって入力されます。

PointerToSymbolTable: ファイル内の COFF ファイル シンボル テーブル オフセット。

NumberOfSymbols: シンボル テーブルの数。

SizeOfOptionalHeader: 後続のオプション ヘッダーのサイズ。

特性: 実行可能ファイルのプロパティ。次の値のフェーズごとの OR にすることができます。


PE ファイル ヘッダーは、PE ファイルのいくつかの基本的な情報と属性を定義することがわかります. これらの属性は、PE ローダーが読み込まれるときに使用されます. ローダーが、PE ファイル ヘッダーで定義されたいくつかの属性が現在の動作を満たしていないことを検出した場合環境では、PE のロードが停止します。

もう 1 つの重要なヘッダーは、PE オプション ヘッダーです。その名前をオプション ヘッダーと見なさないでください。実際、欠落しているわけではありません。ただし、異なるプラットフォームでは異なります。たとえば、32 ビットでは IMAGE_OPTIONAL_HEADER32 です。ですが、64ビットでは IMAGE_OPTIONAL_HEADER32 です。下は IMAGE_OPTIONAL_HEADER64 です。簡単にするために、32 ビットのみを見ていきます。

Magic: オプションのヘッダーの種類を示します。 

MajorLinkerVersion および MinorLinkerVersion: リンカーのバージョン番号。

SizeOfCode: コード セグメントの長さ。複数のコード セグメントがある場合は、コード セグメントの長さの合計です。

SizeOfInitializedData: 初期化されたデータの長さ。

SizeOfUninitializedData: 初期化されていないデータの長さ。

AddressOfEntryPoint: プログラム エントリの RVA、exe のアドレスについては、WinMain の RVA として理解できます。DLL の場合、このアドレスは DllMain の RVA として理解でき、ドライバーの場合は DriverEntry の RVA として理解できます。もちろん、実際のエントリ ポイントは WinMain、DllMain、および DriverEntry ではありません。これらの関数の前に一連の初期化を完了する必要があります。もちろん、これらはこの記事の焦点では​​ありません。

BaseOfCode: コード セグメントの開始アドレスの RVA。

BaseOfData: データ セグメントの開始アドレスの RVA。

ImageBase: イメージのベース アドレス (メモリにロードされた PE ファイル). このベース アドレスは提案です. DLL の場合、このアドレスにロードできない場合、システムは自動的にそのアドレスを選択します.

SectionAlignment: セクションの配置. PE のセクションがメモリにロードされると、このフィールドで指定された値に従って配置されます. たとえば、この値が 0x1000 の場合、各セクションの開始アドレスの下位 12 ビットは0.

FileAlignment: セクションはファイル内でこの値によって整列され、SectionAlignment は FileAlignment 以上である必要があります。

MajorOperatingSystemVersion, MinorOperatingSystemVersion: 必要なオペレーティング システムのバージョン番号オペレーティング システムのバージョンが増えるにつれて、これはそれほど重要ではないようです。

MajorImageVersion、MinorImageVersion: 開発者によって指定され、リンカーによって埋められるイメージのバージョン番号。

MajorSubsystemVersion、MinorSubsystemVersion: 必要なサブシステムのバージョン番号。

Win32VersionValue: 予約済み、0 でなければなりません。

SizeOfImage: イメージのサイズ。メモリ空間にロードされる PE ファイルは連続的です。この値は、占有される仮想空間のサイズを指定します。

SizeOfHeaders: すべてのファイル ヘッダー (セクション テーブルを含む) のサイズ。この値は FileAlignment に合わせて調整されます。

CheckSum: イメージ ファイルのチェックサム。

サブシステム: PE ファイルを実行するために必要なサブシステムは、次のいずれかの定義になります。

SizeOfStackReserve: 実行時に各スレッド スタックに予約されるメモリのサイズ。
SizeOfStackCommit: 実行時の各スレッド スタックの初期メモリ サイズ。

SizeOfHeapReserve: ランタイムは、プロセス ヒープのメモリ サイズを予約します。

SizeOfHeapCommit: 実行時のプロセス ヒープの初期メモリ サイズ。

LoaderFlags: 予約済み、0 でなければなりません。

NumberOfRvaAndSizes: データ ディレクトリ内のアイテムの数、つまり、次の配列内のアイテムの数。

DataDirectory: 配列であるデータ ディレクトリであり、配列の項目は次のように定義されます。


VirtualAddress: は RVA です。
サイズ:サイズです。

この 2 つの数値は何に使用されますか? 1 つはアドレス、もう 1 つはサイズで、このデータ ディレクトリ エントリが領域を定義していることがわかります。それで、彼はどの領域を定義しますか?前述のように、DataDirectory は配列であり、配列内の各項目は、インポート テーブル、エクスポート テーブルなどを含む特定のデータ構造に対応しています。さまざまなインデックスに従ってさまざまな構造が抽出され、各項目はヘッダー ファイルで定義されています。以下のコードに示すように、どの構造を表しますか。

ELF ファイル構造

ELF ファイルは、ELF ヘッダー (ELF ヘッダー)、プログラム ヘッダー テーブル (プログラム ヘッダー テーブル)、セクション (セクション)、セクション ヘッダー テーブル (セクション ヘッダー テーブル) の 4 つの部分で構成されます。実際には、ファイルには必ずしもすべてのコンテンツが含まれているとは限らず、それらの位置が図のように配置されていない場合があります。ELF ヘッダーの位置のみが固定されており、他の部分の位置、サイズ、およびその他の情報は値によって決定されます。 ELF ヘッダーで決定します。

ヒント: 16 進エディタを使用して表示できます

シェルの紹介

シェルは、一部のコンピューター ソフトウェアのプログラムであり、ソフトウェアが不正に変更または逆コンパイルされないように保護する特別な役割を果たします。

彼らは通常、プログラムに先んじて実行し、制御を獲得し、ソフトウェアを保護するタスクを完了します。

通常、シェルは 2 つのカテゴリに分類されます。1 つは圧縮されたシェルで、もう 1 つは暗号化されたシェルです。

圧縮シェル: 

圧縮シェルは DOS 時代に登場しましたが、当時は計算能力が限られており、圧縮解除のオーバーヘッドが大きかったため、広く使用されていませんでした。

圧縮されたシェルを使用すると、PE ファイルのサイズを縮小し、PE ファイルの内部コードとリソースを隠し、ネットワーク転送と保存を容易にすることができます。

一般に、圧縮シェルには 2 種類あります。1 つは一般的な PE ファイルを圧縮するために使用されるもので、もう 1 つはソース ファイルを大幅に変形させ、PE ファイルのヘッダーに深刻な損傷を与え、悪意のあるプログラムを圧縮するためによく使用されます。

一般的な圧縮シェル: Upx、ASpack、PECompat

暗号化シェル:

暗号化シェル、または保護シェルは、コードの逆解析を防ぐためにさまざまな技術が適用されており、その主な機能は、コードの逆解析から PE を保護することです。

暗号化シェルの主な目的はファイル リソースを圧縮することではなくなったため、通常、暗号化シェルによって保護される PE プログラムは元のファイルよりもはるかに大きくなります。

現在、暗号化されたシェルは、セキュリティ要件が高く、クラッキングに敏感なアプリケーションで広く使用されています. 同時に、悪意のあるプログラムを使用して、ウイルス対策ソフトウェアの検出と強制終了を回避 (削減) しています.

一般的な暗号化シェルは、ASProtector、Armadillo、EXECryptor、Themida、VMProtect です。

シェルのローディング プロセス:

1. 入力パラメータを保存する 

①パッカーの初期化時に各レジスタの値を保存する

②シェル実行終了後、各レジスタの値を復元

③最後に元のプログラム実行へジャンプ

通常、pushad / popad、pushfd / popfd 命令ペアを使用して、シーン環境を保存および復元します。

2. 必要な関数 API を取得する

①一般的なシェルの入力テーブルにはAPI関数 GetProcAddress、GetModuleHandle、LoadLibraryしかない

②他の API 関数が必要な場合は、LoadLibraryA(W) または LoadLibraryExA(W) を使用して、DLL ファイルを呼び出しプロセスのアドレス空間にマップします。

③DLLファイルが呼び出しプロセスのアドレス空間にマッピングされている場合、GetModuleHandleA(W)関数を呼び出してDLLモジュールハンドルを取得できます

④DLLモジュールがロードされたら、GetProcAddress関数を呼び出して入力関数のアドレスを取得できます

3. 各ブロックのデータを復号化する 

①ソースプログラムコードとデータを保護する目的で、ソースプログラムファイルの各ブロックは一般的に暗号化されています。プログラムが実行されると、シェルはこれらのブロック データを復号化して、プログラムを正常に実行できるようにします。

②シェルは通常、ブロックごとに暗号化され、ブロックごとに復号化され、復号化されたデータは適切なメモリ位置に戻されます

4. 元のプログラム エントリ ポイントに戻る 

①エントリ ポイントに戻る前に、通常、元の PE ファイル入力テーブル (IAT) が復元され、再配置アイテム (主に DLL ファイル) が処理されます。

②パッキング時にシェルが自ら入力テーブルを構築するため、各DLLが導入する全ての関数のアドレスを再取得し、IATテーブルに記入する必要がある

③上記作業終了後、元のプログラムに制御を移し実行を継続

共通ツール

1.行動分析ツール

Tinder Sword(Sangfor EDRと同一環境では使用不可)、procexp、processminerなど

2. シェルチェックツール

ExefoPE、 DetectItEasy

3. 動的解析ツール

Ollydbg (32 ビット プログラムのみを解析可能)、X64dbg、Windbg、gdb (Linux)

4. 静的解析ツール

アイダプロ

5. 補助ツール

HashMyFiles (ファイルのハッシュ値を計算します)

010Editor (16進数の状態を確認して修正)

開梱ツール(シェルの種類に応じた専用の開梱ツールをダウンロード)

Pwndbg (gdb プラグイン)

おすすめ

転載: blog.csdn.net/jd_cx/article/details/126494746