首页
社区
课程
招聘
[旧帖] [原创]学习xfish“美妙的PE”一文后的小作品 0.00雪花
2012-8-20 23:03 2518

[旧帖] [原创]学习xfish“美妙的PE”一文后的小作品 0.00雪花

2012-8-20 23:03
2518
感谢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值

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
点赞3
打赏
分享
最新回复 (3)
雪    币: 138
活跃值: (460)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
Nermor 1 2012-8-21 01:37
2
0
沙发

PE里思想有多远就能走多远~ 有多龌蹉就有多yindang~
雪    币: 21
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
aiying 2012-9-4 23:35
3
0
感觉最早接触的就是masm 看到很亲切
xfish好久都没更新过那个帖子了
一直在跟
雪    币: 77
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cqzj70 2014-3-8 11:02
4
0
MARK
游客
登录 | 注册 方可回帖
返回