AMF 是一种脚本语言,多用在时下流行的基于 FLASH 界面的网络游戏中。如果希望写出相关的辅助工具,分析发送和影响中的数据是必不可少的一个步骤。下面对一小段 AMF 格式数据进行解析,下面是用 charles 所获取的一段发送请求的十六进制数据:
(图-1)
对上面数据构成的分析(数据字节从 1 开始算起):
第 1-2 个字节 00 00 表示的是 AMF 的版本,都是 0,则表示使用的是 AMF0 格式。
第 3-4 个字节 00 00 表示的是 Header 头部的个数,此处为 0,表示不使用头部。
第 5-6 个字节 00 01 表示的是 AMF 的主体(body) 有 1 个。
上面的说明可以从下图得到验证:
(图-2)
将上图已经解析好的各个组成部分和十六进制格式相比较,更容易理解数据的构成。
接着,看到一个目标 Target ,这是调用的类和方法,其为 UserService.getCDStatus 。此时反过来再接着看十六进制形式的数据:
第 7-8 个字节 00 17, 表示请求的方法的长度,仔细数一下 UserService.getCDStatus 刚好是 23 个字节,即十六进制的 0x17 。
第 9-31 个字节就是 UserService.getCDStatus 中各个字符的 ASCII 码。
第 32-33 个字节 00 02 表示请求 Target 后,要求服务器端相应标识的长度。
第 34-35 个字节 2f 31 所对应的 ASCII 码为 '/1' ,在 图-2 中看到被解析成 "Response"。也就是说,该请求发出后,服务器需要对此做出相应的响应,而对此的响应标识就为 '/1' 。现在观察一下服务器响应后的情况:
在上图中,被红色方框所框住部分,即是服务器发回的相应情况:Target 对应的字符串为 "/1/onResult",这里也看到了上述的标识符'/1',然后后接一个 '/onResult' ,这表明客户端发出的调用请求成功。而其下的 Response 的值为 'null' 表示不需要客户端对此响应再做出响应。
接下来到主体的”内容“(Content)部分。
由图中可见,内容部分有一个数组,数组中有一个数字类型数据,其值为 7764 ,下面分析这些信息的十六进制构成:
第 36-39个字节 00 00 00 0e 这 4 个字节表示 ”Content" 这部分内容的长度,该长度包含了 “Content" 中元素类型标识符长度以及元素自身相关的属性长度。下面将依次列出这些部分的说明。
第 40 个字节 0a ,在 AMF0 中,0a 用来标识这是一个数组。
第 41-43 个字节 00 00 00 01 ,这里用 4 个字节来表示该数组的元素个数,从图-1可知,该数组只有一个数值,因此元素个数为 1 。
第 44 个字节 00 表示该元素的类型,而 00 正是表示其类型为数值类型。
第 45-52 个字节,00 00 00 00 00 54 be 40 这 8 个字节正是用来表示数值 7754 的。注意,这里的数字存放是按照双精度浮点型来存放。这一点我们可用下面的小程序进行验证:
[C++] 纯文本查看 复制代码 #include <stdio.h>
int main()
{
double i = 7764;
unsigned char *p = (char *)&i;
int k;
for (k = 0; k < 8; k++)
printf ("0x%x ", *(p+k));
printf ("\n");
return 0;
}
运行输出:beyes:~ # ./double
0x0 0x0 0x0 0x0 0x0 0x54 0xbe 0x40
这部分请求的 AMF 数据格式已经分析完,虽然麻雀虽小,但五脏俱全。其它复杂的数据结构可以类似的分析,对照着软件的解析结果,我们可以更好的理解十六进制中的内容。如果想写出游戏辅助工具,在程序里提取相关数据是必不可少的一件工作。
关于 AMF 的相关资料,在网上还有许多,可以百度谷歌参考,下面给出几个相关的参考链接:
AMF 中的数据类型:
http://osflash.org/documentation/amf/astypes
学习 AMF 协议之数据类型:
http://wenku.baidu.com/view/e9d7b74433687e21af45a99e.html
AMF 的维基百科:
http://en.wikipedia.org/wiki/Action_Message_Format |