WildPackets解码器语言参考 中文版,第二部分
对本地变量和全局变量的赋值或数学计算,可以使用下面的语法:
g[1] = 1; l[1] = 2; g[4] = l[4]; l[3] = g[6];
g[1] += 1; l[1] += 2; g[4] += l[4]; g[7] += g[6]; l[3] += g[6]; l[3] += l[6];
g[1] *= 0; l[2] /= 2; g[3] %= 1; g[4] &= l[4]; g[5] |= 5
|
对本地变量和全局变量的测试可以使用下面的语法:
if g[2] == 1 { LABL 0 0 90 c2 "g[2] == 0"; }
if g[2] == l[2] { LABL 0 0 90 c2 "g[2] == l[2]"; }
if l[1] == g[1] { LABL 0 0 90 c2 "l[1] == g[1]"; }
|
测试可以嵌套:
if g[1] <= l[2] { LABL 0 0 90 c2 "g[1] <= l[2]";
if g[2] <= l[1] { LABL 0 0 90 c2 "g[2] <= l[1]"; } }
|
包数据可以使用下面的方法访问:
g[1] = pb[1]; * means GBYT 1 1; g[1] = pb[0]; * means GBYT 0 1; g[1] = pw[0]; * means GWRD 0 1; g[1] = pl[0]; * means GLNG 0 1; l[1] = pl[0]; * means GLNG 0 41;
|
以上例子中,’p’ 表示包数据,’b’ 表示字节,’w’表示字 ,‘l’表示长字
While 循环
下面是While 循环的一个例子:
void main() { g[1] = 0; while (g[1] < 5) { g[1] += 1; DGLB( 0, g[1], 0x90, 0xc2, "g[1]:"); }
g[1] = 5; while (g[1] > 0) { g[1] -= 1; DGLB( 0, g[1], 0x90, 0xc2, "g[1]:"); } }
|
会话型解码
数据包通常包含需要被解码成协议组件的信息。然而,一些协议栈使用事务处理式请求和响应的形式,而且响
应包并不包含它响应的请求类型信息。例如,在AFP协议中,一个获取文件信息的请求被发出,响应中会包含
回应信息,但响应包并不标识它自身是作为文件信息请求的应答。由于在响应包中信息的缺乏,它可能容易被
解析为对获取卷参数请求的一个响应。对这种问题的解决方法,解码器语言包含WHOA指令。这种指令将索引
化字串的名字作为它的字串参数。每个在字串数组中的名字是如何解码下部分数据包的一种选择,并且这个名
字也是被调用的解码器的名字。 这些选择以对话框呈现给用户,值域包含一个默认选择的索引号,并被高亮显
示在一个列表中。
有了这个基础,就明确了,对那些无法标识他们响应的协议,用户需要手动选择一个解码器。在实现
的细节上,程序试图记住最后的选择并对后续的包再次使用。但是这样的推导常常不适用。
要扩展解码器的能力,添加了另外一个机制,那就是会话型解码。 首先, 增加了MARK指令,以便在遇到请
求包时,用相关信息对数据包打了“标记”;这样这种类型的回应后续的处理中会被特别期望(等待)。然后,
当在以后处理数据包时,遇到WHOA指令,WHOA指令会检查看看是否有被标记的包告诉它如何处理当前的数
据包。如果有,用户将不被提示要求输入选择,而是默认使用前面标记指令所指示的解码方法进行解码。
为了澄清和描述这种机制,考虑下面的例子。 一种特定的协议建立了一个端口到端口的连接。请求发出,并且
提供无请求识别的响应。这种协议的实现,响应发送到请求端唯一的端口上。 要针对这种情况写一个解码器程
序,在解码请求时,使用了MARK指令。在MARK指令的字串域,包含了字串数组的名字,数组包含了所有响
应类型的名字。 值域说明哪个选项对这个请求是正确的。原端口号保存在全局变量中且此全局变量传递给
MARK指令。 在MARK指令处理中,字串数组的名字、在数组中的使用的那个选项、包的号码和在全局变量
中端口号,都一起存储在LIFO内存中,也叫作缓存。
在为一个响应编写解码程序时,在一个适合的点上,可能适用不同类型的响应,WHOA指令被调用。WHOA指
令的字串域含有包含所有可能的响应类型名字的字串数组的名字。值参数说明其中的哪个选项是默认项。响应
包的目标端口保存在全局变量中。 在处理WHOA指令中,会根据端口号和字串数组名字查询缓存。如果发现
匹配,则保存在MARK指令的中的选择,用于解码下一部分的数据包。还有,如果WHOA指令在值参数的高
8bit中包含全局变量的号码,全局变量会获得包含请求包的号码。 如果在缓存中有一个匹配,解码进程将进一步执行指定的解码器。如果没有匹配,用户作出了一个选择,解码进程继续执行所选的解码器。在所有其他情况下,包括当用户选择了取消,解码进程将根据WHOA指令继续执行。请看下面的例子:
MARK 和WHOA代码例子:
1)打开decodes.dcd
2)搜索子函数 SNMP
void SNMP; ASN1_Init; MOVE 0 11; *enum testing is off LABL 0 0 0 b1 SNMP - Simple Network Management Protocol; WHOA 0 1 0 0 SNMP Exp Opt; WHOA 0 2 0 0 SNMP Exp Opt; SEQU a1 1; SKIP 5 0; SEQU a2 1; SKIP 3 0; MARK 2 2 0 0 SNMP Exp Opt; WHOA 0 2 0 0 SNMP Exp Opt; TNXT -Summary SNMP Fields; MARK 2 1 0 0 SNMP Exp Opt; WHOA 0 1 0 0 SNMP Exp Opt; TNXT -Summary SNMP Fields;
|
3)注意在11行的MARK 。它解释为,标记这个包为后面包的解码提供可能的帮助,使用字串数组SNMP Exp
Out查出下一个可能的解码器。值域说明基于全局值域的那个字串,在这里是2;以后如果在全局中这个值匹配
的话,那么它将使用在字串数组中第二个位置上指明的解码器。然后它将这些数据存储到缓存中。
4)注意12行的WHOA。它解释为,根据以前数据包的信息进行解码。检查全局变量位置2看那里是什么值。如
果值指向一个在SNMP Exp Out字串数组中的字串,那么调用那个解码器执行解码。
另一个 MARK 和WHOA代码的例子:
1) 打开decode.dcd
2) 搜索 void TCP::Ports
void TCP::Ports() { MOVE 0 9; WHOA 0 2 0 0 Alternate Decoders; WHOA 0 2 0 0 H323_Decoders; WHOA 0 2 0 0 MegacoText::Str; WHOA 0 2 0 0 SIP::MW_List; MOVE 1 9; TSB# 0 2 -TCP::Ports_Str; SKIP 1; MOVE 2 9; // g[9]==2 means we did not find a match }
|
1) 注意 第三个WHOA. 它引用MegacoText::Str。如果你搜索,会发现在列表中只有一个项。这是因为在开始的
Megaco请求中,它标记这个端口为合法Megaco端口。这样做是因为Megaco协议能根据你观察的那个会话变
换端口。所以,当有一个标记指令时,全局变量就包含一个当前Megaco协议运行的端口。这样,当有一个
WHOA指令,它能对那个MARK指令检查,看看是否Megaco是一个合法的项。如果有一个有效的项,它会利用
MARK的值域来决定跳转哪个解码器函数。(在这里,指明的是MegacoText)。
最后一个在Novell解码时,有关MARK和WHOA的例子:
1) 打开decode.dcd
2) 搜索函数 void NCP Reply
void NCP Request; GWRD 0 b; DBYT 0 14 90 c2 Sequence number:; ...
void NCP Reply; GWRD 0 b; DBYT 0 14 90 c2 Sequence number:; ... WHOA 0 14 0 0 NCP::Type_17::MW_List; WHOA 0 14 0 0 NCP::Type_21::MW_List; WHOA 0 14 0 0 NCP::Type_22::MW_List; WHOA 0 14 0 0 NCP::Type_23::MW_List; WHOA 0 14 0 0 NCP::Type_32::MW_List; WHOA 0 14 0 0 NCP::Type_34::MW_List; WHOA 0 14 0 0 NCP::Type_35::MW_List; WHOA 0 14 0 0 NCP::Type_36::MW_List; WHOA 0 14 0 0 NCP::Type_86::MW_List; WHOA 0 14 0 0 NCP::Type_87::MW_List; WHOA 0 14 0 0 NCP::Type_90::MW_List; WHOA 0 14 0 0 NCP::Type_104::MW_List; WHOA 0 14 0 0 NCP::Type_111::MW_List; WHOA 0 14 0 0 NCP::Type_114::MW_List; WHOA 0 14 0 0 NCP::Type_123::MW_List; WHOA 0 14 0 0 NCP::Type_131::MW_List; WHOA 0 14 0 0 NCP::Type_Loners::MW_List; WHOA 0 b 0 c2 Adv NW Rep Opt; TNXT -NW Reply Any Left;
|
3) 开始的几行被省略了, 但注意到一个长的WHOA指令列表。 NCP 这样工作: 要正确解析数据包,请求
包指明了响应的内容并且它还能包含需要响应的信息。
a)也注意到第二行, 在NCPRequest和NCPReply,都有一行"DBYT 0 14 90 c2 Sequence Number." 那是在MARK和WHOA指令中使用的值。所以根据序列号,MARK和WHOA指令将检查在全局变量14中的值来确认它是否有效。
b) 下一步是标记所有有响应的请求包。搜索void NCP::Type_22::52. 在函数开始部分,你会发现:
void NCP::Type_22::52; MARK 34 14 0 0 NCP::Type_22::MW_List; ...
str# NCP::Type_22::MW_List; 1 | NCP::Type_22::01R; 2 | NCP::Type_22::02R; 5 | NCP::Type_22::05R; 6 | NCP::Type_22::06R; 12 | NCP::Type_22::12R; ... 51 | NCP::Type_22::51R; 52 | NCP::Type_22::52R;
|
它标记要利用在列表中的第52号。
c)总结一下,MARK将保存全局变量14用于WHOA指令中检查,还有,值域的[0x34]被用于响应解码器的索引。当WHOA被调用是,如果全局变量14匹配,那么它将使用标记值域所对应的解码器分支进行正确解码。
Zenith
2007/6/6
阅读(1669) | 评论(0) | 转发(0) |