[原创]宇宙最强 010 Editor 模板开发教程(附带示例)
发表于:
2020-2-23 14:41
17823
[原创]宇宙最强 010 Editor 模板开发教程(附带示例)
众所周知,010 Editor 是二进制分析中十分强力的工具,能够解析多种文件格式并以友好的界面呈现。其强大的内部引擎使得任何人都可以定制所需的解析脚本或解析模板。在 010 的官网上已经有仓库存放了大量的 脚本 和 模板 库供大伙使用。但问题一定是解决不完的,当遇到冷门文件而官方仓库没有模板咋办?办法只有一个:自己写 。
本文将手把手教你如何写一个简单而不失优雅的模板。首先我会讲解下 010 模板开发的基本语法和规则,然后会提到常用的一些 Api,最后会以微软的.lib
静态库为例演示实际操作过程。
010 模板(010 Editor Templates)的基本语法和 C 语言类似,毫不夸张的说你要是会 C 的话,你已经学会了一半。剩下一半你就记住这句话:将整个文件的二进制数据当作输入,将其强制转换为一个结构体就行了 。不过当你动手开始实践的时候,你会发现事情果然没有那么简单的,要将整个文件的数据转换成一个结构体,其内部需要更细粒度的结构体来支撑。
前面说了一堆废话,还是要讲讲基本语法的,毕竟这是一篇从入门到踩坑 系列教程。
C 语言中基本变量类型都是支持,包括 int、char、short、long、float 等,结构体 struct,枚举 enum,位域 bitfield 以及联合体 union 也是没问题的 。C 中常用的关键字 define、const 和 unsigned 等也是可以用在 010 模板中的。除此之外,Windows 中定义的变量类型也是受支持的,诸如 WORD、DWORD、UINT32、UINT64、LONG。
C 中的各种加减乘除,大于小于,与或非等表达式也是可以用在模板中的,具体的如下:
数值运算:+ - * / ~ ^ & | % ++ -- ?: << >> ()
逻辑运算:&& || !
比较操作:< ? <= >= == != !
赋值操作:= += -= *= /= &= ^= %= |= <<= >>=
C 语言本身的语法并不复杂,在 010 模板中你更不必了解某些生僻的语法,只需要知道 if...else、while、for、switch 以及数组和函数即可。C 语言强大而复杂的指针在 010 中完全用不着,是不是贼开心,可以不用顶着多级指针去操作数据了。
需要注意的是在 010 模板中不能使用二维数组以及 goto 语句 。
在官网的文档中,给出了 010 模板中具有的特殊属性:
1
2
3
4
5
6
7
8
9
10
<
format
=
hex
|decimal|octal|binary, fgcolor
=
"<color"
>,
bgcolor
=
<color>,
comment
=
"<string>"
|<function_name>,
name
=
"<string>"
|<function_name>,
open
=
true|false|suppress,
hidden
=
true|false,
read
=
<function_name>,
write
=
<function_name>,
size
=
<number>|<function_name>>
<
/
function_name><
/
number><
/
function_name><
/
function_name><
/
function_name><
/
string><
/
function_name><
/
string><
/
color><
/
format
=
hex
|decimal|octal|binary,>
下面将简单介绍下这些属性
format: 以某种进制格式显示,默认为十进制,显示在 Vlaue 栏
fgcolor: 设置字体色
bgcolor: 设置背景色
comment: 添加注释,显示在 Comment 栏
name: 替换显示的字符,默认为结构体中的变量名,显示在 Name 栏
open: 设置树形图是否展开,默认不展开
hidden: 设置是否隐藏,默认为不隐藏
read: 读回调,返回字符串并显示在 Vlaue 栏
write: 写回调,将读回调返回的字符写入结构体某个字段中
size: 按需执行,可节约系统内存
把这些特殊属性归个类,不常用的属性有 open 、write 和 size ,某些比较特殊情况下会用到的属性 name 和 hidden ,花里胡哨时才会用到 fgcolor 和 bgcolor ,快速开发模板你只需要记住 read 、format 和 comment 。
上边提到特殊情况我展开说明下,name 属性我没怎么用到过,感觉是给强迫症用的,hidden 这个属性在某些情况下有奇效,比如定义的局部变量可能显示在结果中,这时候就可以利用
来隐藏冗余的输出。
下面我放两张图,帮助大伙更好的理解以上这几个特殊的属性,图 1 中的 1 处是 name 属性显示的字符,如果不指定 name 属性默认就是结构体中的变量名。2 处是 format 属性,默认是十进制,这里指定为 16 进制。3 处是背景颜色和字体颜色缩影,这里没设置颜色所以显示为空。4 处就是 comment 属性显示的位置。
背景颜色 bgcolor 和字体颜色 fgcolor 明眼人一看就明白了。
010 模板的 Api 比较多,我将一些使用频率比较高的 Api 罗列出来,如果你想要完整的 Api 列表,请看官网的函数接口 。不过个人认为下面的 Api 已经足够使用了,除非你要写非常复杂的解析模板:
void BigEndian()
void LittleEndian()
char ReadByte(int64 pos=FTell())
uchar ReadUByte(int64 pos=FTell())
short ReadShort(int64 pos=FTell())
ushort ReadUShort(int64 pos=FTell())
int ReadInt(int64 pos=FTell())
uint ReadUInt(int64 pos=FTell())
int64 ReadInt64(int64 pos=FTell())
uint64 ReadUInt64(int64 pos=FTell())
void ReadBytes(uchar buffer[], int64 pos, int n)
char[] ReadString(int64 pos, int maxLen=-1)
int ReadStringLength(int64 pos, int maxLen=-1)
wstring ReadWString(int64 pos, int maxLen=-1)
int ReadWStringLength(int64 pos, int maxLen=-1)
void WriteByte(int64 pos, char value)
int FSeek(int64 pos)
int FSkip(int64 offset)
int64 FTell()
int FEof()
void Strcpy(char dest[], const char src[])
void Strcat(char dest[], const char src[])
int Strchr(const char s[], char c)
int Strcmp(const char s1[], const char s2[])
int Printf(const char format[] [, argument, ... ])
int SScanf(char str[], char format[], ...)
int SPrintf(char buffer[], const char format[] [, argument, ... ])
这些 Api 大部分都能猜出来是干嘛的,比如 ReadByte 是指定位置读取一个字节,WriteByte 是指定位置写入一个字节,Strcmp 是字符串比较,Printf 打印字符,SScanf 将字符数组 buffer 格式化为多种数据格式,SPrintf 将各种数据格式化后置于字符数组 buffer。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课