傳送門
winhex有很多的官方模板,可以在網(wǎng)上下載(后綴tpl)并放至它的安裝目錄,即可使用。不過要是自己能自己制作,這才好玩,不是么?!
打開模板管理器,可以選中其中一個模板,下面有應(yīng)用,有編輯,你點(diǎn)開編輯按鈕,就可以看到對應(yīng)的模板源碼。而你點(diǎn)開那個新建按鈕,就可以自己寫模板了,最后保存到安裝目錄即可。提醒一點(diǎn),我是在記事本下寫好粘貼到新建后那個面板上的,因?yàn)槲野l(fā)現(xiàn)有好些符號它不支持,比如下劃線、引號等,maybe是我自己沒設(shè)置的原因,不過,這不是重點(diǎn),略過。寫好后,那個面板下有檢查語法的按鈕,通過它可判斷你的代碼是否語法正確。
閑話不多說,下面,我來講解下模板編程的語法:
模板頭的常用關(guān)鍵字:
1.template:聲明模板的名字 eg:template "模板1"
2.description:描述參數(shù),描述這個模板的用途。(保存好后,你可以在模板管理器里看到你自定義的模板的名字,描述等信息。)eg:description "這個模板是用來。。。"
3.applies_to:參數(shù)可以是file/disk/RAM。指定該模板的適用對象時文件、磁盤還是內(nèi)存。eg:applies_to disk
4.fixed_start offset:模板的默認(rèn)起始偏移量取決于光標(biāo)停留的位置,而這個關(guān)鍵字是來指定偏移量起始位置。eg:fixed_start 0x040
5.sector-aligned:作用是指定模板從當(dāng)前扇區(qū)的偏移0位置運(yùn)行。無參數(shù)。
6.requires offset:匹配數(shù)據(jù),若發(fā)現(xiàn)指定偏移量的位置的數(shù)據(jù)不匹配,就會報(bào)錯。注意:這里的偏移量是相對于模板起始偏移量計(jì)算的。eg:requires 0x1fe "55aa"
7.big-endian/little-endian:規(guī)定讀取的字節(jié)順序,也就是平日說的小端機(jī)、大端機(jī)的區(qū)別,內(nèi)存的數(shù)據(jù)存儲方向不一樣。無參數(shù)。
8.hexadecimal:使模板中讀到的數(shù)據(jù)都以十六進(jìn)制方式顯示,octal為八進(jìn)制,decimal為十進(jìn)制。無參數(shù)。
9.read-only/read-write:規(guī)定讀取權(quán)限。無參數(shù)。
10.multiple:作用是使模板上出現(xiàn)左右鍵來讓你可以選擇讀取上一條或下一條記錄,記錄之間的跨度是該模板涉及的所有字節(jié)的長度。無參數(shù)。
11.begin與end:之間的區(qū)域用于存放程序主干。
這里作下模板頭知識總結(jié):首先,模板的命名需要關(guān)鍵字template加引號完成。description參數(shù)可以補(bǔ)充描述。applies_to(RAM、file、disk)后面可以用于指定訪問對象的類型,使模板適應(yīng)當(dāng)前工程的根本環(huán)境。fixed_start可以為模板指定起始偏移量。requires則制定更嚴(yán)格的模板運(yùn)行條件,要求模板作用范圍內(nèi)指定位置必須匹配指定數(shù)據(jù)。big-endian、hexadecimal、read-only等都是作用于顯示輸出的可選參數(shù)。頭部關(guān)鍵字沒有強(qiáng)制規(guī)定“出場順序”,對引號的要求也不嚴(yán)格。此外,模板可以用雙斜杠添加注釋,這是一個很好的編程習(xí)慣。
注意:數(shù)制屬性關(guān)鍵字(hexadecimal等)、顯示方向?qū)傩躁P(guān)鍵字(big-endian等)、讀寫屬性關(guān)鍵字(read-only等)都可以插入begin與end之間,用于臨時改變數(shù)據(jù)的屬性,注意這種改變僅僅作用于緊隨它們的數(shù)據(jù)類型聲明語句,而并非全局。
下面說下程序主干里的常用關(guān)鍵字:
1.int8:帶符號的8位整型,占用一字節(jié),范圍-128~127。eg:int8 "身高"
2.uint8:無符號的8為整型,占用一字節(jié),范圍0~255。同byte類型。
3.int16:帶符號的16位整型,占用2字節(jié)。
不贅述了,與前面這些類似的還有:uint16, int32, uint32, int64, int24, uint24。
4.unit_flex:類似于c語言里位域的概念。其語法是:unit_flex "要解釋的位" "title"
例如:unit_flex "8,7,6,5,4,3,2,1,0" "permissions",表示讀取一個32位無符號整數(shù)并解釋其低9位。
注意,盡管unit_flex所表示的數(shù)據(jù)長度可能小于4個字節(jié),但每次讀取仍然按照4個字節(jié)來計(jì)算,故而要特別注意位域的實(shí)際長度。比如,我們要解釋一個16位整型數(shù)值的前4位和后12位,應(yīng)當(dāng)首先解釋前4位,這時光標(biāo)移動4字節(jié)。unit_flex "3,2,1,0" "flexlow" 因?yàn)檫€有數(shù)據(jù)要從該16位整型數(shù)值中提取,故回退4個字節(jié)。move -4 。 解釋后12位。unit_flex "15,14,13,12,11,10,9,8,7,6,5,4" "flexhigh" 由于16位整型數(shù)值只占用兩個字節(jié),而實(shí)際光標(biāo)移動4字節(jié),故需要回退2字節(jié):move -2, 否則會占用下一個數(shù)據(jù)的空間。
5.binary:每次讀取一個字節(jié),并解釋為二進(jìn)制樣式。
6.char:讀取一個字節(jié),ascii碼顯示。也可以用char[len]讀取字符數(shù)組(字符串),len表示長度。
7.char16:讀取兩個字節(jié),Unicode字符顯示。
8.string:ascii字符串。語法為string len "title"
9.string16:unicode字符串。
10.zstring:表示不管長度讀取一個ascii字符串,遇到"NULL"時結(jié)束。zstring16為其Unicode版本。
11.hex:表示直接讀取字節(jié)而且并不將其解釋為任何數(shù)據(jù)類型,直接顯示。
12.float:占用4字節(jié),浮點(diǎn)數(shù),同c語言。
13.real:占用6字節(jié),浮點(diǎn)數(shù)。
14.double:占用8字節(jié),浮點(diǎn)數(shù)。
15.longdouble:占用10字節(jié),浮點(diǎn)數(shù)。
16.Loop:實(shí)現(xiàn)簡單的循環(huán)。中括號中可以存放常量表示循環(huán)次數(shù),也可以直接引用前面數(shù)據(jù)類型的title。
17.IfEqual:簡單的if語句,判斷是否相等。比較的對象可以是常量,也可以是前面數(shù)據(jù)類型的title。
eg:
byte "學(xué)號"
IfEqual "學(xué)號" 09
uint "成績"
Else
uint "績點(diǎn)”
EndIf
18.~:占位符。一般用于循環(huán)內(nèi)部數(shù)據(jù)類型的標(biāo)題中,以形成數(shù)字遞增的效果。常常與numbering配合使用。numbering可以用來指定占位符的初始值。
eg:

uint32 "文件數(shù)目"
numbering 1
{
string16 255 "~號文件"
}["文件數(shù)目"]
//占位符從1開始,循環(huán)代入string16 255 "~號文件"中。
下面是隨手寫的一個例子,很湊合的說~
源碼:

template "the dbr of ntfs of jiu"
description "......"
applies_to disk
sector-aligned
requires 0x03 "4e54465320"
requires 0x1f0 "55aa"
little-endian
read-write
multiple
begin
hex 3 "jmp"
char[8] "OEM"
uint16 "bytes per sector"
uint8 "sectors per cluster"
uint16 "unused"
hex 3 "zero"
hex 10 "unused"
int64 "total sectors"
int64 "mft"
int64 "mftmirr"
byte "file record"
hex 100 "......"
end
自定義模板的應(yīng)用: