Billy Belceb病毒編寫教程(DOS篇)有用的結構體
【有用的結構體】
~~~~~~~~~~~~~~
現在介紹我們已經討論了很多的PSP。
%PSP(Program Segment Prefix)%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PSP結構如下:
___________________________________
| INT 20h(CD 20) |<------+0000h
|___________________________________| Size:1 WORD
| Pointer to the next segment |<------+0002h
|___________________________________| Size:1 WORD
| Reserved |<------+0004h
|___________________________________| Size:1 BYTE
| Far call to INT 21h |<------+0005h
|___________________________________| Size:5 BYTES
| Saved INT 22h vector |<------+000Ah
|___________________________________| Size:1 DWORD
| Saved INT 23h vector |<------+000Eh
|___________________________________| Size:1 DWORD
| Saved INT 24h vector |<------+0012h
|___________________________________| Size:1 DWORD
| Reserved |<------+0016h
|___________________________________| Size:22 BYTES
| Offset to Environment Segment |<------+002Ch
|___________________________________| Size:1 WORD
| Reserved |<------+002Eh
|___________________________________| Size:46 BYTES
| First default FCB |<------+005Ch
|___________________________________| Size:16 BYTES
| Second default FCB |<------+006Ch
|___________________________________| Size:16 BYTES
| Command Tail and default DTA |<------+0080h
|___________________________________| Size:180 BYTES
Total Size:256 BYTES
因為這個結構非常重要,讓我一步一步地解釋吧。
offset 0000h:
INT 20h是終止程式的過時的方法,現在我們使用INT 21h的4CH號函式。
offset 0002h:
這是pointer to the next segment,這個指標指向我們程式的下一段。我們利用它可以知道DOS 能給我們多少記憶體(它指向的偏移地址減去PSP的偏移地址0000)。它將以段返回給我們記憶體,所以我們必須把它乘以16來得到位元組數。
offset 0005h:
這是呼叫INT 21h的一種奇特方式。而且,當然,我們可以利用它來達到我們的目的。這個函式用到CL而不是AH,而且我們只能在低於24h時呼叫這個函式。我將在TUNNELING這一章裡介紹更多。
offset 000Ah:
這裡儲存的是原先的INT 22h中斷向量。INT 22h當程式使用如下方法終止執行時接受控制:
- INT 20h
- INT 27h
- INT 21h(00h,21h,4Ch函式)
offset 000Eh:`
這裡儲存另一箇中斷的向量,INT 23h。這個中斷處理CTRL+C按鍵組合。
offset 0012h:
儲存在這裡的另外一箇中斷,INT 24h。這個中斷處理嚴重錯誤。這種型別錯誤的例子:當你的軟碟機裡面沒有軟盤,或者軟盤被防寫了。
offset 002Ch:
這裡是環境塊偏移地址的開始。
offset 005Ch:
這裡儲存第一個預設FCB(File Control Block檔案控制塊)。這種訪問檔案的方式通常情況下不會被程式使用(在這裡是為了和低版本的DOS相容),但是病毒作者為了使病毒更隱蔽,經常使用它。你可以在FCB結構裡看到更多的資訊。
offset 006Ch:
同上,這是第二個預設FCB。
Offset 0080h:
這一段有兩個功能:
----儲存命令尾(command tail)
---儲存D他的預設檔案緩衝區
這兩個功能不能同時使用,所以我們開始一個程式要考慮的第一件事就是命令尾(command tail)。如果我們需要它,我建議你把它儲存到一個安全的地方(我們程式碼中的一個變數中)。命令尾的第一個位元組(80h)約束了它的長度,而且這裡,它儲存了真正的引數。D他的結構將會在這一章中介紹。
%FCB(File Control Block 檔案控制模組)%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
現在有兩種型別的FCB:普通和擴充套件型別。下面給出普通FCB:
________________________________
| Drive Letter(0=actual,1=A...) |<----+0000h
|________________________________| Size:1 BYTE
| Blank padded file name |<----+0001h
|________________________________| Size:8 BYTES
| Blank padded file extension |<----+0009h
|________________________________| Size:3 BYTES
| Current block number |<----+000Ch
|________________________________| Size:1 WORD
| Logical record size |<----+000Eh
|________________________________| Size:1 WORD
| File size |<----+0010h
|________________________________| Size:1 DWORD
| File date |<----+0014h
|________________________________| Size:1 WORD
| File time |<----+0016h
|________________________________| Size:1 WORD
| Reserved |<----+0018h
|________________________________| Size:8 BYTES
| Record within current block |<----+0020h
|________________________________| Size:1 BYTE
| Record access record number |<----+0021h
|________________________________| Size:1 DWORD
Total Size:37 BYTES
而在一個擴充套件FCB中,上面所有的偏移地址會向後移7個位元組,而開始的7個位元組如下:
_____________________________________
| FF(Signature for extended FCB) |<---- -0007h
|_____________________________________| Size:1 BYTE
| Reserved |<---- -0006h
|_____________________________________| Size:5 BYTES
| File attribute |<---- -0001h
|_____________________________________| Size:1 BYTE
Total Size:44 BYTES
檢測FCB是普通的還是擴充套件的方法是看FCB 的第一個位元組是否為FFh。如果是,那麼就為擴充套件FCB,否則就為普通FCB。
有一種隱蔽病毒(STEALTH)方法就是改變FCB的某些值,我們將會在STEALTH一章裡具體討論。
%MCB(Memory Control Block 記憶體控制模組)%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我們將在駐留記憶體病毒這一章介紹它(下一章)。下面給出MCB:
___________________________________
| ID(Z=last,M=there're more) |<----+0000h
|___________________________________| Size:1 BYTE
| Address of associated PSP |<----+0001h
|___________________________________| Size:1 WORD
| Number of paras in allocated mem |<----+0003h
|___________________________________| Size:1 BYTE
| Unused |<----+0005h
|___________________________________| Size:11 BYTES
| Block Name |<----+0008h
|___________________________________| Size:8 BYTES
| Zone of allocated memory |<----+0010h
|___________________________________| Size:?? PARAS
Total Size: VARIABLE
%DTA(Disk Transfer Area 磁碟交換區)%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在病毒寫作中這個結構非常重要。讓我們看:
___________________________________
| Drive Letter(equal than above) |<----+0000h
|___________________________________| Size: 1 BYTE
| Search Template |<----+0001h
|___________________________________| Size: 11 BYTES
| Reserved |<----+000Ch
|___________________________________| Size: 9 BYTES
| File attribute |<----+0015h
|___________________________________| Size: 1 BYTE
| File time |<----+0016h
|___________________________________| Size: 1 WORD
| File date |<----+0018h
|___________________________________| Size: 1 WORD
| File size |<----+001Ah
|___________________________________| Size: 1 DWORD
| ASCIIZ Filename+extention |<----+001Eh
|___________________________________| Size: 13 BYTES
Total Size: 43 BYTES
原始DTA儲存在PSP的偏移地址80h處。我們可以利用INT 21h的1Ah功能儲存它。
%IVT(Interrupt Vector Table中斷向量表)%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
這個並不是“真正的”結構體。恩...讓我解釋一下吧...IVT是儲存所有中斷向量的地方(哇,天才啊!)。所有的中斷向量的位置為number_of_interrupt*4(中斷號*4)。假如我們想把INT 21h中斷向量賦給DS:DX...則:
xor ax,ax
mov ds,ax
lds dx,ds:[21h*4]
為什麼我們清除DS?因為IVT是從地址0000:0000開始到高地址記憶體的。這種操作(不透過使用DOS)是獲得/賦給一箇中斷的向量的直接方法。有關更多的介紹將在駐留記憶體病毒(RESIDENT VIRUSES)一章中介紹。嗨...我忘記了示意圖了:)
__________________________________
| INT 00h vector |<-----+0000h
|__________________________________| Size:1 DWORD
| INT 01h vector |<-----+0004h
|__________________________________| Size:1 DWORD
|
//////////////////
|__________________________________
| INT FEh vector |<-----+03FCh
|__________________________________| Size:1 DWORD
| INT FFh vector |<-----+0400h
|__________________________________| Size:1 DWROD
Total Size:1024 BYTES
你能想象得到“斷”行表示有256箇中斷,我不得不最佳化這篇教程(我可不想花5頁來表示它!)
%SFT(System File Table 系統檔案表)%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
這個結構真得很酷。它能幫助你使你的程式碼更健壯,更最佳化。它類似於FCB,但是,正如你看到的,它更強大。利用這個表,我們可以使病毒更隱蔽,改變檔案指標的開啟模式,屬性...這裡你看到的使DOS 4以上版本的結構(我相信在這個世界上已經沒有人用DOS 3或更低了吧)。好了,如果你想為DOS 3編寫程式碼,可以參考Ralph Brown的中斷列表。但是DOS 3的SFT是和下面的非常類似的。重要的值在相同的地方:)
===================================== <----+0000h
‖ Pointer to next file table ‖ Size:1 DWORD
‖===================================‖<----+0004h
‖ Number of files in this table ‖-----------Size:1 WORD----------
‖===================================‖<----+0000h [3Bh bytes per file]
| Number of file handles of file | Size:1 WORD
|___________________________________|
| File open mode(AH=3Dh) |<-----+0002h
|___________________________________| Size:1 WORD
| File attribute |<-----+0004h
|___________________________________| Size:1 BYTE
| Device info block(AX=4400h) |<-----+0005h
|___________________________________| Size:1 WORD
| If char device points next dev h. |<-----+0007h
| else point to DOS DPB | Size:1 DWORD
|___________________________________|
| Starting cluster of file |<-----+000Bh
|___________________________________| Size:1 WORD
| File time |<-----+000Dh
|___________________________________| Size:1 WORD
| File date |<-----+000Fh
|___________________________________| Size:1 WORD
| File size |<-----+0011h
|___________________________________| Size:1 DWORD
| Current offset in file |<-----+0015h
|___________________________________| Size:1 DWORD
| Relative cluster within file of |<-----+000-}---------[If Local File]
| last cluster accessed | Size:1 WORD
|___________________________________|
| Number of sector with dir entry |<-----+001Bh
|___________________________________| Size:1 DWORD
| Number of dir entry within sector |<-----+001Fh
|___________________________________| Size:1 BYTE
| Pointer to REDIRIFS records |<-----+000-}---[Network redirector]
|___________________________________| Size:1 DWORD
| ??? |<-----+001Dh
|___________________________________|--------Size:3 BYTES--------
| Filename in FCB format |<-----+0020h
|___________________________________| Size:11 BYTES
| Pointer to prev SFT sharing file* |<-----+002Bh
|___________________________________| Size:1 DWORD
| Network machine num opened file* |<-----+002Fh
|___________________________________| Size:1 WORD
| PSP segment of file owner |<-----+0031h
|___________________________________| Size:1 WORD
| Offset to code segment of rec* |<-----+0033h
|___________________________________| Size:1 WORD
| Absolute clust num of last access |<-----+0035h
|___________________________________| Size:1 WORD
| Pointer to IFS driver for file |<-----+0037h
|___________________________________| Size:1 DWORD
Total Size:61 BYTES
Uhm...我忘記訪問SFT的方法了...下面給出的程式把SFT賦給ES:DI,把檔案控制程式碼儲存到BX中。
GetSFT:
mov ax,1220h
int 2Fh
jc BadSFT
xor bx,bx
mov ax,1216h
mov bl,byte ptr es:[di]
int 2Fh
BadSFT:
ret
我強烈地建議你把返回值儲存到AX/BX中(BX非常重要:這裡我們用來儲存檔案控制程式碼)。
標誌(*)的域將會被SHARE.EXE使用
%DIB(DOS Info Block DOS資訊模組)%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
利用DIB,我們能夠訪問那些重要的不能利用其它方法訪問結構。這個結構並不是固定的在記憶體中的,我們必須利用INT 21h的52h功能。在DOS文件裡沒有這個函式的介紹。當我們呼叫這個函式的時候,我們將會在ES:BX裡得到DIB的地址。你將會得到:
___________________________________
| Pointer to first MCB |<---- -0004h
|___________________________________| Size:1 DWORD
| Pointer to first DPB |<-----+0000h
|___________________________________| Size:1 DWORD
| Pointer to DOS last buffer |<-----+0004h
|___________________________________| Size:1 DWORD
| Pointer to $CLOCK |<-----+0008h
|___________________________________| Size:1 DWORD
| Pointer to CON |<-----+000Ch
|___________________________________| Size:1 DWORD
| Maximum sector length |<-----+0010h
|___________________________________| Size:1 WORD
| Pointer to DOS first buffer |<-----+0012h
|___________________________________| Size:1 DWORD
| Pointer to array of cur dir struc |<-----+0016h
|___________________________________| Size:1 DWORD
| Pointer to SFT |<-----+001Ah
|___________________________________| Size:1 DWORD
Total Size:34 BYTES
%DPB(Drive Parameter Block 驅動器引數模組)%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
這個結構為我們提供了達到我們的目的的非常有用的資訊。透過使用DIB(看上文)裡的第二個指標,我們能夠知道它的位置。下面給出:
___________________________________
| Drive Letter(0=A,1=B...) |<----+0000h
|___________________________________| Size:1 BYTE
| Unit number within device driver |<----+0001h
|___________________________________| Size:1 BYTE
| Bytes per sector |<----+0002h
|___________________________________| Size:1 WORD
| Highest sect num within a cluster |<----+0004h
|___________________________________| Size:1 BYTE
| Shift count for clust to sectors |<----+0005h
|___________________________________| Size:1 BYTE
| Number of reserved clusters |<----+0006h
|___________________________________| Size:1 WORD
| Number of FATS |<----+0008h
|___________________________________| Size:1 BYTE
| Number of root directory entries |<----+0009h
|___________________________________| Size:1 WORD
| Number of first sector with data |<----+000Bh
|___________________________________| Size:1 WORD
| Number of last sector with data |<----+000Dh
|___________________________________| Size:1 WORD
| Number of sector per FAT |<----+000Fh
|___________________________________| Size:1 BYTE
| Sector number of first dir sector |<----+0010h
|___________________________________| Size:1 WORD
| Address of device driver header |<----+0012h
|___________________________________| Size:1 DWORD
| Media ID byte |<----+0016h
|___________________________________| Size:1 BYTE
| 00h if disk accessed,else FFh |<----+0017h
|___________________________________| Size:1 BYTE
| Pointer to next DPB |<----+0018h
|___________________________________| Size:1 DWORD
Total Size:28 BYTES
%分割槽表%
~~~~~~~~
所有編寫啟動病毒的人都知道這個結構,它是硬碟上的第一塊。它總是在第一塊的,無論在軟盤還是在硬碟上。如果是硬碟,我們就叫它MBR(Master Boot Record 主啟動記錄),如果是軟盤,就叫它啟動扇區。
分割槽表是一個有著四個入口的陣列,在偏移地址01BEh處。下面給出每個入口的格式:
___________________________________
| Boot indicator(Bootable=80h, |<----+0000h
| Non bootable 00h) | Size:1 BYTE
|___________________________________|
| Head where the partition begins |<----+0001h
|___________________________________| Size:1 BYTE
| Sector where the partition begins |<----+0002h
|___________________________________| Size:1 BYTE
| Cylinder where the part.begins |<----+0003h
|___________________________________| Size:1 BYTE
| System indicator*(What OS?) |<----+0004h
|___________________________________| Size:1 BYTE
| Head where partition ends |<----+0005h
|___________________________________| Size:1 BYTE
| Sector where the partition ends |<----+0006h
|___________________________________| Size:1 BYTE
| Cylinder where the partition ends |<----+0007h
|___________________________________| Size:1 BYTE
| Total blocks preceding partition |<----+0008h
|___________________________________| Size:1 DWORD
| Total blocks in the partition |<----+000Ch
|___________________________________| Size:1 DWORD
Total Size:16 BYTES
(*) 01=12-bit FAT
04=16-bit FAT
%BPB(Bios Parameter Block Bios 引數模組)%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在以DOS為基礎的系統中,啟動記錄以一個跳轉(jump)作為開始,後面跟這一個結構體――BPB。
_________________________________
| OEM name and version(ASCII) |<----+0000h
|_________________________________| Size:8 BYTES
| Bytes per sector |<----+0008h
|_________________________________| Size:1 WORD
| Sectors per cluster |<----+000Dh
|_________________________________| Size:1 BYTE
| Reserved sector(starting at 0) |<----+000Eh
|_________________________________| Size:1 WORD
| Number of FATs |<----+0010h
|_________________________________| Size:1 BYTE
| Total sectors in partition |<----+0011h
|_________________________________| Size:1 WORD
| Media descriptor |<----+0013h
|_________________________________| Size:1 WORD
| Sectors per FAT |<----+0015h
|_________________________________| Size:1 BYTE
| Sectors per track |<----+0017h
|_________________________________| Size:1 WORD
| Number of heads |<----+0019h
|_________________________________| Size:1 WORD
| Number of hidden sectors |<----+001Dh
|_________________________________| Size:1 WORD
Total Size:29 BYTES
相關文章
- Billy Belceb病毒編寫教程DOS篇---宣告2015-11-15
- Billy Belceb病毒編寫教程(DOS篇)---加密2015-11-15加密
- Billy Belceb病毒編寫教程(DOS篇)---病毒編寫所需的軟體2015-11-15
- Billy Belceb病毒編寫教程(DOS篇)---附錄2015-11-15
- Billy Belceb病毒編寫教程(DOS篇)---駐留記憶體病毒2015-11-15記憶體
- Billy Belceb病毒編寫教程(DOS篇)---隱蔽(Stealth)2015-11-15
- Billy Belceb病毒編寫教程(DOS篇)---優化(Optimization)2015-11-15優化
- Billy Belceb病毒編寫教程(DOS篇)---Tunneling2015-11-15
- Billy Belceb病毒編寫教程(DOS篇)---多型(polymorphism)2015-11-15多型
- Billy Belceb病毒編寫教程(DOS篇)反探索(Anti-Heuristics)2015-11-15
- Billy Belceb病毒編寫教程(DOS篇)---保護你的程式碼2015-11-15
- Billy Belceb病毒編寫教程(DOS篇)---Anti-tunneling2015-11-15
- Billy Belceb病毒編寫教程(DOS篇)一些重要的理論2015-11-15
- [翻譯]Billy Belceb 病毒編寫教程for Win32 ----病毒編寫中的有用的東西2004-05-28Win32
- Billy Belceb 病毒編寫教程for Win32 ----附錄2004-05-28Win32
- [翻譯]Billy
Belceb 病毒編寫教程for Win32----- 宣告2004-05-28Win32
- Billy Belceb 病毒編寫教程for Win32 ----PE檔案頭2015-11-15Win32
- Billy Belceb 病毒編寫教程for Win32 ----簡單介紹2015-11-15Win32
- Billy Belceb 病毒編寫教程for Win32 ----Per-Process?residency2004-05-28Win32IDE
- Billy Belceb 病毒編寫教程for Win32 ----Win32優化2004-05-28Win32優化
- Billy Belceb 病毒編寫教程for Win32 ----Win32多型2004-05-28Win32多型
- Billy Belceb 病毒編寫教程for Win32 ----Win32 反除錯2004-05-28Win32除錯
- Billy Belceb 病毒編寫教程for Win32 ----高階Win32技術2004-05-28Win32
- Billy Belceb 病毒編寫教程for Win32 ----Ring-0,系統級編碼2004-05-28Win32
- Billy Belceb 病毒編寫教程for Win32 ----Ring-3,使用者級編碼2015-11-15Win32
- 用匯編編寫DOS下的記憶體駐留程式(5) (轉)2007-12-05記憶體
- 用匯編編寫DOS下的記憶體駐留程式(3) (轉)2007-08-15記憶體
- 用匯編編寫DOS下的記憶體駐留程式(4) (轉)2007-08-15記憶體
- html常用編寫軟體以及基本結構2020-11-22HTML
- Qealler - 一個用Java編寫的惡意病毒軟體2019-02-08Java
- 技能篇:shell教程及指令碼編寫2021-06-16指令碼
- Oracle體系結構理論篇2015-12-16Oracle
- 有用教程收藏2017-07-14
- 【redis】-- 資料結構及底層編碼篇2021-01-05Redis資料結構
- Oracle記憶體結構研究-PGA篇2009-10-22Oracle記憶體
- Oracle記憶體結構研究-SGA篇2009-10-24Oracle記憶體
- 金山毒霸:DOS病毒復活 穿越者輕鬆突破主流防毒軟體2016-07-06防毒
- 使用Rust編寫嵌入式韌體入門教程2021-12-20Rust