WinHex自定义模板

WinHex模板

(根据官方帮助文档翻译,有翻译不对的地方请指正)


与直接编辑原始十六进制数据相比,模板编辑对话框能以一种更加轻松且不易出错的方式编辑特定数据结构。当在各个编辑框中完成编辑,按下回车键或在退出时(有提示)更改就会生效。需要编辑的数据可以来自文件、磁盘扇区、或虚拟内存。特别是当编辑数据库时,你可以定义一个模板以便访问数据库记录。在对话框的系统菜单中可以找到打印该模板的命令。(译者注:对话框的系统菜单为点左上角的图标弹出)

模板定义保存在扩展名为.tpl的文本文件中。模板编辑器可以让你编写模板定义并且提供语法检查的功能。模板定义主要由变量声明构成,有点类似于编程语言的源代码。支持的数据类型包括普通的整型、浮点型和布尔型、日期类型、十六进制、二进制、字符和字符串类型。还可以使用单一变量的数组或变量组的数组(译者注:变量组的数组是指重复执行命令块,见高级命令部分)。可以在数据中自由前后移动(译者注:指move和goto命令,见高级命令部分),这使得使用模板非常灵活:
(1)同一变量可用几种不同的方式解释和处理
(2)无关的数据部分可以被跳过

模板管理器列出在WinHex目录中包含模板定义的文本文件,显示出模板标题、描述、文件名、最后修改的日期和时间。点击应用按钮就使用当前选中的模板为当前编辑窗口的当前位置数据显示一个模板编辑对话框。也可以在模板管理器中创建一个新模板,删除或编辑现有模板。

WinHex自带有几个示例模板。

模板定义:
winhex模板定义包括“模板头”和“模板主体”。

一、模板头语法

模板头格式如下:

template "标题"
[description "描述"]
[applies_to (file/disk/RAM)]
[fixed_start 偏移]
[sector-aligned]
[requires 偏移 "十六进制值"]
[big-endian]
[hexadecimal/octal]
[read-only]
[multiple [固定总字节长度]]
// 此处为模板注释(译者注:下面begin与end之间为模板主体)
begin
        变量声明
        变量声明
        ……
end

上面括号中的标记表示可选。各个标记的先后顺序没有规定。如果表达式中有空格需要用引号包围起来。注释可以出现在模板定义中的任何地方。双斜框(//)后的字符会被解析器忽略。

applies_to关键字后面必须是file,disk或RAM中的一个且只能有一个,如果将模板应用于与此处定义不同的数据来源时winhex会发出警告。

应用模板时,默认从当前光标位置开始解释数据,而选项fixed_start使得从指定的绝对偏移开始解释数据。

如果模板应用到disk,关键字sector-aligned使得从当前扇区的开始位置解释数据,忽略当前光标的准确位置。

类似于applies_to,requires能预防将模板错误地应用于不匹配的数据。指定一个偏移和一串任意长度的十六进制值,用于识别该模板适用的正确数据。例如,一个有效的主引导记录(MBR)其0x1FE偏移处的值应为55AA,一个执行文件其偏移0x0处的值应为4D5A(对应的ASCII码为"MZ")。在模板头中可以有多个applies_to声明,它们都会被用于匹配。

关键字big-endian使得模板定义中所有的多字节整型和布尔型变量以"大端"的顺序进行读写(即:高位字节排在前面,低位字节排在后面)。

关键字hexadecimal使得模板定义中所有的整型变量都以十六进方式显示。

关键字read-only使得模板仅能用于查看数据,而不能修改。此时模板(对话框)中的编辑框显示为灰色。

如果在模板头中指定了multiple,WinHex允许在模板对话框中浏览相邻的数据记录,这就需要知道记录的长度。如果没有给multiple指定长度参数,WinHex就假定模板结构(=记录)的总长度为模板解释结束位置减去基础编辑位置。如果这是一个变化的长度,比如数组长度或move的参数是由变量的值动态决定的,WinHex将不能浏览到先前的数据记录。

二、模板主体中的变量声明

模板定义的主体部分主要由变量声明组成,类似于编程语言中的变量声明。变量声明的基本形式:

type "标题"

这里type可以是下列之一:
(1)int8, uint8(=byte), int16, uint16, int24, uint24, int32, uint32, uint48, int64
(2)uint_flex
(3)binary
(4)float(=single), real, double, longdouble(=extended)
(5)char, char16, string, string16
(6)zstring, zstring16
(7)boole8(=boolean), boole16, boole32
(8)hex
(9)DOSDateTime, FileTime, OLEDateTime, SQLDateTime, UNIXDateTime(=time_t), JavaDateTime
(10)GUID

type前可以被下列至多一个修饰词所修饰:
big-endian,little-endian                
hexadecimal,decimal,octal
read-only,read-write
local

这些修饰词仅影响紧随其后的变量。模板头中已经出现的修饰词在这里是多余的。local将(除了DOSDateTime之外的)时间戳从UTC转换为WinHex常规选项中指定的时区。

type名字的最后一个数字代表变量(string类型是指其每一字符)的二进制位数。

对于char16和sting16,WinHex支持Unicode字符和字符串。但是Unicode字符中除了和ANSI前256个等价的字符外是不被支持的。模板可以编辑的最大字符串长度是8192字节。

string,string16和hex类型需要一个附加的参数指明元素的个数。这个参数可以是一个常量或前面定义的变量或数学表达式(见后)。如果是一个常量,可以用十六进格式指定,它以数值前面的0x识别。

声明变量数组的方法是在type或标题后面的方括号中指定一个数组长度。下面两行声明了一个动态长度的ASCII字符串,它的长度决定于前面的变量:

uint8 "len"
char[len] "字符串"

下面两行声明达到的效果相同:

byte "len"
string len "字符串"

字符~(波浪号)可以当作占位符,以后可用数组的实际元素序号替代(见下面高级命令部分)。注意这种用法不适用于字符变量的数组,因为它们是自动转换为字符串的。

string,string16和hex变量,以及数组长度表达式的数字参数可以用数学符号指定。它们被内部的公式解析器处理。这样的表达式需要用圆括号包围。它们必须不包含空格字符。它们可以使用前面声明过的整型变量,整型变量的名字也不能包含空格字符。支持的操作符有加(+)、减(-)、乘(*)、整除(/)、取余(%)、按位与(&)、按位或(|),和按位异或(^)。有效的数学表达式如(5*2+1)或(len1/(len2+4))。结果总是一个整数且必须是一个正数。

zstring和zstring16是以null结束的字符串,它们的长度在运行时动态决定。

三、模板主体中的高级命令

将几个变量声明包括在括号中,就构成了一个"块",块可以做为一个整体重复使用。但是,请注意块一定不要嵌入到当前的执行当中(译者注:意思可能是块不能嵌套)。可以在变量名中使用~(波浪号)作为占位符,以后可用实际的重复次数替代。可选的numbering定义从哪里开始计数(默认为0)。

numbering 1
{ byte "len"
string len "String No. ~"
}[10]

在这个例子中,模板中实际的变量名字将是"String No. 1","String No. 2",...,"String No. 10"。如果不使用常量数值做为重复次数(如本例中的10),也可以指定一个"unlimited"(译者注:unlimited无限的意思)。如果那样的话,WinHex将重复执行块直到遇到文件结束。可以使用"ExitLoop"来在任何时候跳出循环。"Exit"则会完全终止模板执行。

IfEqual用于比较两个表达式。比较对象要么是两个数值(如十进制的常量值、整型变量或公式),要么是两个以文本或十六进制值表示的字节序列(逐字节进行比较)。ASCII字符串表达必须用引号包围,十六进制序列必须以0x的标识符开始。公式要包括在括号中。

{ byte Value
IfEqual Value 1
ExitLoop
EndIf
}[10]

IfEqual命令块以一个"Endif"结束。如果被比较的表达式相等,则从IfEqual后面继续进行模板解析。可选的,IfEqual可以跟一个Else,如果两个表达式不等,就转入Else块进行模板解析。IfEqual命令一定不能嵌套。IfGreater类似于IfEqual,如果第一个表达式大于第二个表达式则条件为真。String值和hex值按字典顺序序进行比较。

为了帮助阅读和浏览模板,可以在对话框中定义若干组以"空行"分隔的变量组:
(译者注:section相当于分节,每节有个标题,节前后有空行,便于阅读)

section "section标题"
变量声明
变量声明
……
endsection

section、endsection和numbering语句都不会对当前位置的数据进行解释。

有三个命令不用来声明变量,它们是用来显式地改变当前位置的。比如跳过无关的数据(向前移动),或做为不同的类型多次访问某些变量(向后移动)。使用move来从当前位置跳过n字节,这里n可以是负数。"goto n"从模板解释的开始位置定位到指定的绝对位置(必须是正数)。"gotoex n"基于数据窗口(如file或disk)的开始跳到指定的绝对位置。

下面的例子演示了如何做为不同的类型访问一个变量(既当作一个32位整型,也当作一个四段的十六进制值):

int32 "磁盘序列号(十进制)"
move -4
hex 4 "磁盘序列号(十六进制)"


(完)

猜你喜欢

转载自blog.csdn.net/ikaoni/article/details/78492312