欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

学习xfish“美妙的PE”一文后的小作品

学习xfish“美妙的PE”一文后的小作品

感谢xfish撰写的 【Anti Virus专题】,看了之后,对于新人的我,收获颇多!
特别声明:这是看了xfish“美妙的PE”一文后的练习作品,无任何作怪目的;
xfish“美妙的PE”文章:http://www.pediy.com/kssd/pediy10/83646.html

看了xfish撰写的 【Anti Virus专题】中的“美妙的PE”一文后,为了加深理解,做了二个小程序:
1、把原病毒代码迁移到了masm平台上(病毒代码版权归xfish所有),其中为了适应win7,我对GetKrnl32函数做了些完善,具体如下:

;-----------------------------------------------
;获得Kernel32基地址
;Input  : nothing
;
;ntdll!_UNICODE_STRING
;   +0x000 Length           : Uint2B
;   +0x002 MaximumLength    : Uint2B
;   +0x004 Buffer           : Ptr32 Uint2B
;
;-----------------------------------------------
GetKrnl32:
                push    esi
                push    edi
                push    ecx
                
                call    @@GetKrnl32Str
@@Krnl32StrBeg:
                irpc    char, <kernel32.dll>
                        db      '&char&' , 0
                endm
KRNL32_STR_LEN = $ - @@Krnl32StrBeg
@@GetKrnl32Str:
                pop     esi
                cld
                
                mov     eax, fs:[30h]
                mov     eax, [eax + 0ch]
                mov     eax, [eax + 1ch]
                
@@FindKrnl32Dll:
                cmp     word ptr[eax + 1ch], KRNL32_STR_LEN     ;BaseDllName(Unicode String)
                je      @@IsKernel32Dll
@@NotKrnl32Dll:
                mov     eax, [eax]
                jmp     @@FindKrnl32Dll
@@IsKernel32Dll:
                mov     edi, [eax + 20h]
                mov     ecx, KRNL32_STR_LEN / 4
                repz    cmpsd
                
                test    ecx, ecx
                jnz     @@NotKrnl32Dll
                
                mov     eax, [eax + 08h]
                pop     ecx
                pop     edi
                pop     esi
                ret
2、写了一个专门针对此病毒的修复程序(无任何作怪目的),具体如下:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;程序用途:用于修复被 xfish"美妙的PE"一文中描述的病毒 感染后的文件
;xfish"美妙的PE"文章:http://www.pediy.com/kssd/pediy10/83646.html
;
;author lw(nopnopnop) [2012-08-15]
;仅仅是学习之后为了加深理解而做的练习,无任何作怪目的,O(∩_∩)O~
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .386
                .model flat, stdcall
                option casemap:none
                
include         windows.inc
include         kernel32.inc
includelib      kernel32.lib
include         user32.inc
includelib      user32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
VIRUS_FLAG      equ     'HSIF'          ;字符串"FISH"
VIRUS_SIZE      equ     0496h
VIRUS_JMP_SIZE  equ     03B5h
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;用于push字符串操作
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
$pushsz         macro   str
                local   @@DefStrAddrEnd
                call    @@DefStrAddrEnd
                db      str, 0
@@DefStrAddrEnd:
endm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;用于存储病毒感染后的一些特征
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
VirusMark       struc
markOffset      dd      0       ;相对于病毒代码起始的偏移
markData        dd      0       ;指定偏移地址处的特征数据
VirusMark       ends
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .const
virusMarks      VirusMark       <0000h, 00E89C60h>, <024Bh, 40004014h>, <048Ah, 14D14C51h>
szSearchPath    db              'C:\virusdemodir\', 0   ;需要修复的目录
szMsgTitle      db              '提示', 0
szMsgText       db              '修复工作已完成!', 0
;函数声明处
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
RecoverFile     proto   lpszFilePath:dword
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;代码段
                .code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;用于修复指定路径下所有被感染的文件
RecoverDisk     proc    uses ebx esi edi, _lpszSearchPath:dword, _dwSearchType:dword
                local   @szFilePath[MAX_PATH]   :byte
                local   @hFindFile              :dword
                local   @stFindData             :WIN32_FIND_DATA
                lea     ebx, @stFindData
                lea     esi, @stFindData.cFileName              
                lea     edi, @szFilePath
                
                invoke  lstrcpy, edi, _lpszSearchPath
                $pushsz '*.*'
                push    edi
                call    lstrcat
                
                invoke  FindFirstFile, edi, ebx
                cmp     eax, INVALID_HANDLE_VALUE
                je      @@FindFileFailed
                mov     @hFindFile, eax
                
@@RecoverFile:
                cmp     byte ptr[esi], '.'
                je      @@FindNextFile
                mov     eax, @stFindData.dwFileAttributes
                and     eax, FILE_ATTRIBUTE_DIRECTORY
                test    eax, eax
                jnz     @@RecoverDisk           ;递归修复
                
                invoke  lstrlen, esi
                cmp     eax, 4
                jna     @@FindNextFile
                mov     eax, [esi + eax - 4]    ;文件后缀
                cmp     eax, _dwSearchType
                jne     @@FindNextFile
                invoke  lstrcpy, edi, _lpszSearchPath
                invoke  lstrcat, edi, esi
                invoke  RecoverFile, edi
                
@@FindNextFile:
                invoke  FindNextFile, @hFindFile, ebx
                test    eax, eax
                jnz     @@RecoverFile
                jmp     @@Ret
                
@@RecoverDisk:
                invoke  lstrcpy, edi, _lpszSearchPath
                invoke  lstrcat, edi, esi
                $pushsz '\'     ;目录设定是假设以“\”结尾
                push    edi
                call    lstrcat
                invoke  RecoverDisk, edi, _dwSearchType
                jmp     @@FindNextFile
                
@@Ret:
                invoke  CloseHandle, @hFindFile
@@FindFileFailed:
                ret
RecoverDisk     endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;用于修复被感染的程序(1、修正入口点;2、清空病毒代码;3、清除感染标记)
RecoverFile     proc    uses ebx esi edi, _lpszFilePath:dword
                local   @hOpenedFile    :dword
                local   @hFileMapping   :dword
                local   @hMappedView    :dword
                
                invoke  CreateFile, _lpszFilePath, FILE_READ_DATA or FILE_WRITE_DATA, \
                        FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
                cmp     eax, INVALID_HANDLE_VALUE
                je      @@OpenFileFailed
                mov     @hOpenedFile, eax
                
                invoke  CreateFileMapping, eax, NULL, PAGE_READWRITE, 0, 0, NULL
                test    eax, eax
                jz      @@FileMappingFailed
                mov     @hFileMapping, eax
                
                invoke  MapViewOfFile, eax, FILE_MAP_WRITE, 0, 0, 0
                test    eax, eax
                jz      @@MapViewFailed
                mov     @hMappedView, eax
                mov     edi, eax
                
                ;首先判断是不是可执行文件
                cmp     word ptr[edi], 'ZM'
                jne     @@Ret
                
                ;检测有没有病毒感染的标记
                cmp     dword ptr[edi + 2], VIRUS_FLAG
                jne     @@Ret
                
                ;esi, ebx 均指向IMAGE_NT_HEADERS
                mov     ebx, [edi + 3ch]
                add     ebx, edi
                mov     esi, ebx
                
                ;再次判断是不是可执行文件
                cmp     word ptr[esi], 'EP'
                jne     @@Ret
                
                ;edx = AddressOfEntryPoint
                mov     edx, [esi + 28h]
                
                ;ebx指向末尾段
                xor     eax, eax
                mov     ax, [esi + 06h]                 ;NumberOfSections
                dec     ax
                imul    ax, 28h
                add     bx, [esi + 14h]                 ;SizeOfOptionalHeader
                lea     ebx, [ebx + eax + 18h]
                
                ;被病毒感染后的VirtualSize == SizeOfRawData
                mov     eax, [ebx + 08h]                ;VirtualSize
                cmp     eax, [ebx + 10h]                ;SizeOfRawData
                jne     @@Ret
                
                ;检测当前入口地址在不在最后一段的虚拟地址内
                mov     eax, [ebx + 0ch]                ;VirtualAddress
                sub     edx, eax
                jna     @@Ret
                
                ;检测最后一段的大小是否能完整包含病毒代码,否则表示没感染
                mov     eax, [ebx + 10h]                ;SizeOfRawData
                sub     eax, edx
                jna     @@Ret
                sub     eax, VIRUS_SIZE
                jb      @@Ret
                
                ;edx指向病毒代码的开始地址
                mov     eax, [ebx + 14h]                ;PointerToRawData
                add     eax, edi
                add     edx, eax
                
                ;判断需不需要进行特征码检测
                mov     ecx, lengthof virusMarks
                test    ecx, ecx
                jz      @@DoRecover
                
                ;根据制定的特征数据再次判断程序是否被病毒感染
                lea     eax, virusMarks
@@CompareMarks:
                mov     edi, edx
                add     edi, [eax + VirusMark.markOffset]
                mov     edi, [edi]
                cmp     edi, [eax + VirusMark.markData]
                jne     @@Ret
                add     eax, sizeof VirusMark
                dec     ecx
                jnz     @@CompareMarks
                ;开始修复被感染后的程序文件
@@DoRecover:
                ;还原真正的入口点
                mov     eax, edx
                add     eax, VIRUS_JMP_SIZE
                mov     eax, [eax - 4]
                mov     ecx, [esi + 28h]                ;AddressOfEntryPoint
                add     ecx, VIRUS_JMP_SIZE
                add     eax, ecx
                mov     [esi + 28h], eax
                
                ;清除病毒代码
                xor     eax, eax
                mov     edi, edx
                mov     ecx, VIRUS_SIZE
                rep stosb
                
                ;清除感染标记
                mov     edi, @hMappedView
                add     edi, 2
                stosd
                
@@Ret:
                invoke  UnmapViewOfFile, @hMappedView
@@MapViewFailed:
                invoke  CloseHandle, @hFileMapping
@@FileMappingFailed:
                invoke  CloseHandle, @hOpenedFile
@@OpenFileFailed:
                ret
RecoverFile     endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;程序入口点
AntiVirusEntry:
                invoke  RecoverDisk, addr szSearchPath, 'exe.'  ;'.exe'
                invoke  MessageBox, NULL, addr szMsgText, addr szMsgTitle, MB_OK
                invoke  ExitProcess, 0
                end     AntiVirusEntry
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
附件内容罗列:
bin文件夹中的virusdemo.exe是病毒文件,具体可以看xfish“美妙的PE”
bin文件夹中的antivirus.exe文件用于修复被virusdemo.exe感染后的程序
src文件夹中的virusdemo.Asm是masm版本的病毒实现代码
src文件夹中的antivirus.Asm是antivirus.exe的实现代码
src文件夹中的calchash.cpp用于计算virusdemo.Asm文件中需要用到的函数名hash值

上传的附件 VirusPratice_SRC.zip
VirusPratice_BIN.zip

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功