Win32下病毒設(shè)計(jì)入門(mén)
更新時(shí)間:2006年10月03日 00:00:00 作者:
Win32下病毒設(shè)計(jì)入門(mén)
本文假定你對(duì)dos下的病毒和386PM有一定的了解。
1、感染任何一個(gè)病毒都需要有寄主,把病毒代碼加入寄主程序中
(伴侶病毒除外)。
以下說(shuō)明如何將病毒代碼嵌入PE文件中,有關(guān)PE文件的結(jié)構(gòu)請(qǐng)看以前的文章。 PE文件的典型結(jié)構(gòu): MZ Header DOS STUB CODE PE HEADER OPTIONAL HEADER SECTION TABLE SECTION 1 SECTION 2 ... IMPORT TABLE EXPORT TABLE 和DOS的可執(zhí)行文件類(lèi)似,PE的代碼映象分為幾個(gè)SECTION,在文件中會(huì)對(duì)齊
頁(yè)邊界(4K)。一般來(lái)說(shuō),文件會(huì)加載在400000h開(kāi)始的空間,而第一個(gè)SECTION在401000h處,同時(shí)入口地址也是401000h。由高級(jí)語(yǔ)言編寫(xiě)的程序,每個(gè)SECTIO-N的長(zhǎng)度不可能剛好是4K的倍數(shù),因此在SECTION的末尾將會(huì)存在一段未用的空間 , 大小可由Section的PHYSICAL SIZE-VIRTUALSIZE得到,在文件中起始位置可由 PHYSICAL OFFSET得到,這段空間可以用來(lái)存放病毒代碼。此外一般來(lái)說(shuō), MZ Header+DOS STUD+PE
HEADER+OPTIONAL HEADER+SECTION TABLE不過(guò)1K左右, 而SECTION 1由4K開(kāi)始,空出來(lái)的地方足夠存放一個(gè)設(shè)計(jì)精良的病毒。CIH就是將 代碼存放在這些空閑空間里。
2、分配駐留所需內(nèi)存
對(duì)于駐留形的病毒,分配駐留所需內(nèi)存是必需的。在DOS下使用由于所有的 應(yīng)用程序都映射在相同的線(xiàn)性地址空間里,使用一般的內(nèi)存分配調(diào)用就足夠了。而在WIN32下,每個(gè)應(yīng)用程序都有自己的線(xiàn)性地址空間,必須使用特殊的函數(shù)分配2GB以上的系統(tǒng)地址。典型的如:VXD服務(wù)_PageAllocate,和kernel32的 VxDCALL
_PageReserve。_PageAllocate請(qǐng)參看win98ddk中的說(shuō)明,VxDCall _PageReserve 請(qǐng)參看HPS源碼中的注釋。
3、截留FILE I/O操作 駐留型的病毒通過(guò)截留FILE I/O來(lái)激活,可以通過(guò)使用VXD服務(wù)
IFSMgr_Install-FileSystemAPIHook(如CIH)或截留VxDCall中的DOS Services callback(如HPS)。
在Win32下編寫(xiě)病毒不是一件困難的事。值得注意的有幾件事:
一、Win32下的系統(tǒng)功能調(diào)用不是通過(guò)中斷實(shí)現(xiàn),而是由DLL中導(dǎo)出。
(直接使用VxD服務(wù)除外)。直接在病毒中得到API入口不是一件容易的事,可以通過(guò)以下這個(gè)變通的方法。
在同一個(gè)版本的Windows下,同一個(gè)核心函數(shù)的入口總是固定的
(指由Kernel32,gdi32,user32導(dǎo)出的函數(shù))。因此可以用以下的方法得到函數(shù)入口:
.386p
.model flat,stdcall
extrn GetModuleHandleA:proc
extrn GetProcAddress:proc
extrn ExitProcess:proc
.data
szKernel db 'KERNEL32.DLL',0
szFindFirst db 'FindFirstFileA',0
szFindNext db 'FindNextFileA',0
szFindClose db 'FindClose',0
szGetCurrentDir db 'GetCurrentDirectoryA',0
szGetWinDir db 'GetWindowsDirectoryA',0
szGetSysDir db 'GetSystemDirectoryA',0
szGetFileAttrib db 'GetFileAttributesA',0
szSetFileAttrib db 'SetFileAttributesA',0
szlopen db '_lopen',0
szlread db '_lread',0
szlwrite db '_lwrite',0
szlclose db '_lclose',0
szllseek db '_llseek',0
hKernel dd 0
.code
;Initialize code
start:
push szKernel
call GetModuleHandleA
mov hKernel,eax
push szFindFirst
push hKernel
call GetProcAddress
mov FindFirstFile,eax
....
jmp VirusStart
InitExit:
push 0
call ExitProcess
VirusStart:
jmp Entry
HostEntry dd InitExit
FindFirstFile dd 0
FindNextFile dd 0
...
Entry:
...
end start
在Intialize Code得到要用的函數(shù)入口并將它填入病毒中,在病毒運(yùn)行時(shí)可以直接使用了。
二:主要是要截留文件I/O操作。
Windows下截留文件I/O操作有幾種方法,在病毒中使用的主要有兩種。
1、使用VxDCallIFSMgr_InstallFileSystemHook
2、截留Kernel32.dll中導(dǎo)出的第一個(gè)函數(shù)VxDCall對(duì)DOS
INT 21的呼叫(EAX=2A0010)。
VxDCall的代碼如下:
mov eax,dword ptr [esp+04]
pop dword ptr [esp]
call fword ptr cs:[xxxxxxxx]
^^^^^^^^只要將這個(gè)地址指向的地址改為自己的過(guò)程入口,就捕獲了所有的VxDCall。
進(jìn)入這個(gè)過(guò)程時(shí):
eax=service number,如果是DOS INT 21將是2A0010
esp[2c]調(diào)用Int 21時(shí)eax的值
~~~~ 算漏了個(gè)pushad,應(yīng)該是10h
esp[30] 調(diào)用int 21時(shí)ecx的值
~~~~14h
其他寄存器為調(diào)用時(shí)所需的值。(段寄存器無(wú)用)
以后的就和在DOS下寫(xiě)病毒沒(méi)什么差別了。
在WINDOWS下寫(xiě)病毒,如何得到API的入口是一件麻煩的事. 可以直接使用的API都在DLL中,而VXDCALL要在RING0時(shí)才能使 用,DOS的INT 21服務(wù)也不能直接調(diào)用. 得到DLL中的API入口有兩種方法:
1.加載時(shí)得到,建立一個(gè) IMPORT TABLE,在加載時(shí)WINDOWS會(huì)根據(jù)IMPORT TABLE定位API的 入口地址.這是一般應(yīng)用程序的使用的方法,但不大適合病毒.
2.運(yùn)行時(shí)得到,使用GetModuleHandle和GetProcAddress得到API的入口,但前提時(shí)要知道GetModuleHandle和GetProcAddress的 入口地址.:< 這是明顯也是不可能的.除了將GetModuleHandle和GetProcAddress的代碼復(fù)制到我們的病毒中,只有使用暴力在 2GB的空間內(nèi)找出API的入口了.
首先說(shuō)明一下WINDOWS的內(nèi)存映射,由00000000開(kāi)始有一段是 無(wú)效地址(我忘了到底到多少了),用來(lái)捕獲應(yīng)用程序錯(cuò)誤的指針.
跟著一直到0x7FFFFFFF為應(yīng)用程序的空間.0X80000000以后為系統(tǒng) 的空間,DLL和VXD都映射在這里.我們要作的就是從這2GB的空間內(nèi)找到Krnl32.dll. 一般來(lái)說(shuō),Windows下的程序都是對(duì)齊在64k的邊界.首先是MZ 文件頭,跟著是由MZ HEADER中的信息可以得到PE HEADER的入口. 由這個(gè)標(biāo)記就可以找出所有的DLL.由PE HEADER可以得到DLL的 EXPORT TABLE的入口,其中而NAME PTR TABLE的第一項(xiàng)為DLL的名 稱(chēng),由此可以找出Krnl32.dll,并從ADDRESS TABLE中得到任何一個(gè) API的入口.
值得注意的是,在這2GB中并不是所有而地址都是有效的,在 一般的程序中可以通過(guò)IsXXXXXPtr來(lái)判斷地址是否有效,但在病毒 中不行.只能Hook Exception,忽略訪(fǎng)問(wèn)無(wú)效的地址導(dǎo)致的Exception. Windows中的Exception Chain的結(jié)構(gòu)如下: fs:[0] dword exception發(fā)生時(shí)esp的新值,該值指向一個(gè)如下 的結(jié)構(gòu) [esp] dword fs:[0]的新值 [esp+4] dword exception handler的入口 [esp+8] dword exception handler使用的數(shù)據(jù)首地址 [esp+12] dword -1詳細(xì)的匯編代碼可以用C寫(xiě)一段__try...__except的代碼,然后 轉(zhuǎn)譯成匯編. 只要我們的exception handler直接跳轉(zhuǎn)到病毒中尋找Krnl32.dll 的代碼,就可以不引起GP Error而訪(fǎng)問(wèn)任何的地址了. 范例可以參看HPS的源碼,PE HEADER,EXPORT TABLE請(qǐng)參看PE FORMAT.
1、在Windows下載入的DLL在不同的process中映射到同一個(gè)地址。
2、在DLL中導(dǎo)出的函數(shù)在export table中記錄相對(duì)DLL Image Base 的偏移,改變這個(gè)偏移使用GetProcAddress得到的地址就會(huì)改變。 (想象一下,把CreateProcess地址指向自己的DLL中的函數(shù),或者截獲GetDlgItemText來(lái)記錄Password)
3、在Kernel32.DLL中Section Table在0x300以前就結(jié)束了,而真正的代碼由0x1000處開(kāi)始,其間有3K的未用空間,可以用來(lái)存放我們的代碼。 Kernel32.DLL的Image Base可以由GetModuleHandleA得到。
4、在任何版本的Windows中,3個(gè)基本的DLL總是被加載(Kernel32.DLL,User32.DLL,GDI32.DLL),而且對(duì)于同一個(gè)版本的Windows,它們的Image Base,和導(dǎo)出函數(shù)的地址總是固定的??梢詫⒌玫降牡刂分苯佑糜诓《臼褂谩?nbsp;( 在NT也可以寫(xiě)病毒了,又要換系統(tǒng)了8< )
本文假定你對(duì)dos下的病毒和386PM有一定的了解。
1、感染任何一個(gè)病毒都需要有寄主,把病毒代碼加入寄主程序中
(伴侶病毒除外)。
以下說(shuō)明如何將病毒代碼嵌入PE文件中,有關(guān)PE文件的結(jié)構(gòu)請(qǐng)看以前的文章。 PE文件的典型結(jié)構(gòu): MZ Header DOS STUB CODE PE HEADER OPTIONAL HEADER SECTION TABLE SECTION 1 SECTION 2 ... IMPORT TABLE EXPORT TABLE 和DOS的可執(zhí)行文件類(lèi)似,PE的代碼映象分為幾個(gè)SECTION,在文件中會(huì)對(duì)齊
頁(yè)邊界(4K)。一般來(lái)說(shuō),文件會(huì)加載在400000h開(kāi)始的空間,而第一個(gè)SECTION在401000h處,同時(shí)入口地址也是401000h。由高級(jí)語(yǔ)言編寫(xiě)的程序,每個(gè)SECTIO-N的長(zhǎng)度不可能剛好是4K的倍數(shù),因此在SECTION的末尾將會(huì)存在一段未用的空間 , 大小可由Section的PHYSICAL SIZE-VIRTUALSIZE得到,在文件中起始位置可由 PHYSICAL OFFSET得到,這段空間可以用來(lái)存放病毒代碼。此外一般來(lái)說(shuō), MZ Header+DOS STUD+PE
HEADER+OPTIONAL HEADER+SECTION TABLE不過(guò)1K左右, 而SECTION 1由4K開(kāi)始,空出來(lái)的地方足夠存放一個(gè)設(shè)計(jì)精良的病毒。CIH就是將 代碼存放在這些空閑空間里。
2、分配駐留所需內(nèi)存
對(duì)于駐留形的病毒,分配駐留所需內(nèi)存是必需的。在DOS下使用由于所有的 應(yīng)用程序都映射在相同的線(xiàn)性地址空間里,使用一般的內(nèi)存分配調(diào)用就足夠了。而在WIN32下,每個(gè)應(yīng)用程序都有自己的線(xiàn)性地址空間,必須使用特殊的函數(shù)分配2GB以上的系統(tǒng)地址。典型的如:VXD服務(wù)_PageAllocate,和kernel32的 VxDCALL
_PageReserve。_PageAllocate請(qǐng)參看win98ddk中的說(shuō)明,VxDCall _PageReserve 請(qǐng)參看HPS源碼中的注釋。
3、截留FILE I/O操作 駐留型的病毒通過(guò)截留FILE I/O來(lái)激活,可以通過(guò)使用VXD服務(wù)
IFSMgr_Install-FileSystemAPIHook(如CIH)或截留VxDCall中的DOS Services callback(如HPS)。
在Win32下編寫(xiě)病毒不是一件困難的事。值得注意的有幾件事:
一、Win32下的系統(tǒng)功能調(diào)用不是通過(guò)中斷實(shí)現(xiàn),而是由DLL中導(dǎo)出。
(直接使用VxD服務(wù)除外)。直接在病毒中得到API入口不是一件容易的事,可以通過(guò)以下這個(gè)變通的方法。
在同一個(gè)版本的Windows下,同一個(gè)核心函數(shù)的入口總是固定的
(指由Kernel32,gdi32,user32導(dǎo)出的函數(shù))。因此可以用以下的方法得到函數(shù)入口:
.386p
.model flat,stdcall
extrn GetModuleHandleA:proc
extrn GetProcAddress:proc
extrn ExitProcess:proc
.data
szKernel db 'KERNEL32.DLL',0
szFindFirst db 'FindFirstFileA',0
szFindNext db 'FindNextFileA',0
szFindClose db 'FindClose',0
szGetCurrentDir db 'GetCurrentDirectoryA',0
szGetWinDir db 'GetWindowsDirectoryA',0
szGetSysDir db 'GetSystemDirectoryA',0
szGetFileAttrib db 'GetFileAttributesA',0
szSetFileAttrib db 'SetFileAttributesA',0
szlopen db '_lopen',0
szlread db '_lread',0
szlwrite db '_lwrite',0
szlclose db '_lclose',0
szllseek db '_llseek',0
hKernel dd 0
.code
;Initialize code
start:
push szKernel
call GetModuleHandleA
mov hKernel,eax
push szFindFirst
push hKernel
call GetProcAddress
mov FindFirstFile,eax
....
jmp VirusStart
InitExit:
push 0
call ExitProcess
VirusStart:
jmp Entry
HostEntry dd InitExit
FindFirstFile dd 0
FindNextFile dd 0
...
Entry:
...
end start
在Intialize Code得到要用的函數(shù)入口并將它填入病毒中,在病毒運(yùn)行時(shí)可以直接使用了。
二:主要是要截留文件I/O操作。
Windows下截留文件I/O操作有幾種方法,在病毒中使用的主要有兩種。
1、使用VxDCallIFSMgr_InstallFileSystemHook
2、截留Kernel32.dll中導(dǎo)出的第一個(gè)函數(shù)VxDCall對(duì)DOS
INT 21的呼叫(EAX=2A0010)。
VxDCall的代碼如下:
mov eax,dword ptr [esp+04]
pop dword ptr [esp]
call fword ptr cs:[xxxxxxxx]
^^^^^^^^只要將這個(gè)地址指向的地址改為自己的過(guò)程入口,就捕獲了所有的VxDCall。
進(jìn)入這個(gè)過(guò)程時(shí):
eax=service number,如果是DOS INT 21將是2A0010
esp[2c]調(diào)用Int 21時(shí)eax的值
~~~~ 算漏了個(gè)pushad,應(yīng)該是10h
esp[30] 調(diào)用int 21時(shí)ecx的值
~~~~14h
其他寄存器為調(diào)用時(shí)所需的值。(段寄存器無(wú)用)
以后的就和在DOS下寫(xiě)病毒沒(méi)什么差別了。
在WINDOWS下寫(xiě)病毒,如何得到API的入口是一件麻煩的事. 可以直接使用的API都在DLL中,而VXDCALL要在RING0時(shí)才能使 用,DOS的INT 21服務(wù)也不能直接調(diào)用. 得到DLL中的API入口有兩種方法:
1.加載時(shí)得到,建立一個(gè) IMPORT TABLE,在加載時(shí)WINDOWS會(huì)根據(jù)IMPORT TABLE定位API的 入口地址.這是一般應(yīng)用程序的使用的方法,但不大適合病毒.
2.運(yùn)行時(shí)得到,使用GetModuleHandle和GetProcAddress得到API的入口,但前提時(shí)要知道GetModuleHandle和GetProcAddress的 入口地址.:< 這是明顯也是不可能的.除了將GetModuleHandle和GetProcAddress的代碼復(fù)制到我們的病毒中,只有使用暴力在 2GB的空間內(nèi)找出API的入口了.
首先說(shuō)明一下WINDOWS的內(nèi)存映射,由00000000開(kāi)始有一段是 無(wú)效地址(我忘了到底到多少了),用來(lái)捕獲應(yīng)用程序錯(cuò)誤的指針.
跟著一直到0x7FFFFFFF為應(yīng)用程序的空間.0X80000000以后為系統(tǒng) 的空間,DLL和VXD都映射在這里.我們要作的就是從這2GB的空間內(nèi)找到Krnl32.dll. 一般來(lái)說(shuō),Windows下的程序都是對(duì)齊在64k的邊界.首先是MZ 文件頭,跟著是由MZ HEADER中的信息可以得到PE HEADER的入口. 由這個(gè)標(biāo)記就可以找出所有的DLL.由PE HEADER可以得到DLL的 EXPORT TABLE的入口,其中而NAME PTR TABLE的第一項(xiàng)為DLL的名 稱(chēng),由此可以找出Krnl32.dll,并從ADDRESS TABLE中得到任何一個(gè) API的入口.
值得注意的是,在這2GB中并不是所有而地址都是有效的,在 一般的程序中可以通過(guò)IsXXXXXPtr來(lái)判斷地址是否有效,但在病毒 中不行.只能Hook Exception,忽略訪(fǎng)問(wèn)無(wú)效的地址導(dǎo)致的Exception. Windows中的Exception Chain的結(jié)構(gòu)如下: fs:[0] dword exception發(fā)生時(shí)esp的新值,該值指向一個(gè)如下 的結(jié)構(gòu) [esp] dword fs:[0]的新值 [esp+4] dword exception handler的入口 [esp+8] dword exception handler使用的數(shù)據(jù)首地址 [esp+12] dword -1詳細(xì)的匯編代碼可以用C寫(xiě)一段__try...__except的代碼,然后 轉(zhuǎn)譯成匯編. 只要我們的exception handler直接跳轉(zhuǎn)到病毒中尋找Krnl32.dll 的代碼,就可以不引起GP Error而訪(fǎng)問(wèn)任何的地址了. 范例可以參看HPS的源碼,PE HEADER,EXPORT TABLE請(qǐng)參看PE FORMAT.
1、在Windows下載入的DLL在不同的process中映射到同一個(gè)地址。
2、在DLL中導(dǎo)出的函數(shù)在export table中記錄相對(duì)DLL Image Base 的偏移,改變這個(gè)偏移使用GetProcAddress得到的地址就會(huì)改變。 (想象一下,把CreateProcess地址指向自己的DLL中的函數(shù),或者截獲GetDlgItemText來(lái)記錄Password)
3、在Kernel32.DLL中Section Table在0x300以前就結(jié)束了,而真正的代碼由0x1000處開(kāi)始,其間有3K的未用空間,可以用來(lái)存放我們的代碼。 Kernel32.DLL的Image Base可以由GetModuleHandleA得到。
4、在任何版本的Windows中,3個(gè)基本的DLL總是被加載(Kernel32.DLL,User32.DLL,GDI32.DLL),而且對(duì)于同一個(gè)版本的Windows,它們的Image Base,和導(dǎo)出函數(shù)的地址總是固定的??梢詫⒌玫降牡刂分苯佑糜诓《臼褂谩?nbsp;( 在NT也可以寫(xiě)病毒了,又要換系統(tǒng)了8< )
相關(guān)文章
SA 沙盤(pán)模式下不用恢復(fù)xp_cmdshell和xplog70.dll也執(zhí)行命令
sa下刪除xp_cmdshell和xplog70.dll時(shí)候的一種辦法,不算新的了, 也被一些人不斷的再次提出來(lái),為了方便自己記憶再寫(xiě)出來(lái), 在這種情況下,要執(zhí)行命令,條件是要有xp_regwrite。2011-01-01Iptables防火墻tcp-flags模塊擴(kuò)展匹配規(guī)則詳解
這篇文章主要為大家介紹了Iptables防火墻tcp-flags模塊擴(kuò)展匹配規(guī)則詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08最詳細(xì)的SQL注入相關(guān)的命令整理 (轉(zhuǎn))
這篇文章主要為打擊分享下一些常用SQL注入相關(guān)的命令,今天幫客戶(hù)做安裝的時(shí)候發(fā)現(xiàn)他的網(wǎng)站有很多漏洞,導(dǎo)致注入數(shù)據(jù)庫(kù)也被清空了,希望大家多關(guān)于安全2006-12-12Portia開(kāi)源可視化爬蟲(chóng)工具的使用學(xué)習(xí)
這篇文章主要為大家介紹了Portia開(kāi)源可視化爬蟲(chóng)工具的使用學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04