摘要
Action Message Format (AMF)
是一種簡潔的二進(jìn)制格式轧邪,通常用于序列化ActionScript
object graphs(對象圖刽脖?不會翻譯)。一旦序列化忌愚,AMF
編碼的對象圖可用于會話之間持久化以及檢索應(yīng)用程序的公共狀態(tài)曲管,或者允許兩個端通過強(qiáng)類型數(shù)據(jù)的交換進(jìn)行通信。
AMF 0 Data Types
下方是AMF0
的16種類型的marker
硕糊。marker
位占用一個字節(jié)長度院水,用于描述AMF
中某種數(shù)據(jù)類型。
marker | value | remark | |
---|---|---|---|
number-marker | 0x00 | ||
boolean-marker | 0x01 | ||
string-marker | 0x02 | ||
object-marker | 0x03 | ||
movieclip-marker | 0x04 | reserved, not supported | |
null-marker | 0x05 | ||
undefined-marker | 0x06 | ||
reference-marker | 0x07 | ||
ecma-array-marker | 0x08 | ||
object-end-marker | 0x09 | ||
strict-array-marker | 0x0A | ||
date-marker | 0x0B | ||
long-string-marker | 0x0C | ||
unsupported-marker | 0x0D | ||
recordset-marker | 0x0E | reserved, not supported | |
xml-document-marker | 0x0F | ||
typed-object-marker | 0x10 |
抓包分析
因?yàn)?code>AMF0采用的是 big endian (network) byte order
癌幕,所以先簡單看看什么是big endian
衙耕。
int val = 0x1234;
big endian:
低地址 0------->1------->2 高地址
+--------+--------+
| 0x12 | 0x34 |
+--------+--------+
little endian:
+--------+--------+
| 0x34 | 0x12 |
+--------+--------+
- Number
number-type = number-marker DOUBLE
Number
Number
的marker
為0x00
勺远,紫框是Number
的數(shù)值,為40 08 00 00 00 00 00 00
时鸵,我的電腦是little endian
的所以我在內(nèi)存里面看到的相應(yīng)的數(shù)值是00 00 00 00 00 00 08 40
胶逢。我們可以看一下rtmpdump的實(shí)現(xiàn)
char *AMF_EncodeNumber(char *output, char *outend, double dVal)
{
unsigned char *ci, *co;
ci = (unsigned char *)&dVal;
co = (unsigned char *)output;
co[0] = ci[7];
co[1] = ci[6];
co[2] = ci[5];
co[3] = ci[4];
co[4] = ci[3];
co[5] = ci[2];
co[6] = ci[1];
co[7] = ci[0];
}
- Boolean
boolean-type = boolean-marker U8 ; 0 is false, <> 0 is true
Boolean
Boolean
的marker
為0x01
,紫框是Boolean
的數(shù)值初坠,為0x01
和簸,理論上只要非零就是true
rtmpdump的實(shí)現(xiàn)
char * AMF_EncodeBoolean(char *output, char *outend, int bVal)
{
*output++ = AMF_BOOLEAN;
*output++ = bVal ? 0x01 : 0x00;
return output;
}
- String
string-type = string-marker UTF-8
String
String
的marker
為0x02
碟刺,綠框是字符串的長度锁保,值為0x0008
,紫框是String
的值半沽,為onStatus
的ASCII
碼爽柒。rtmpdump的實(shí)現(xiàn)
char *AMF_EncodeString(char *output, char *outend, const AVal *bv)
{
*output++ = AMF_STRING;
output = AMF_EncodeInt16(output, outend, bv->av_len);
memcpy(output, bv->av_val, bv->av_len);
output += bv->av_len;
return output;
}
- Object
object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
anonymous-object-type = object-marker *(object-property)
Object
類型除了可以包含其他類型之外,也可以包含Object
類型者填。
image.png
Object
是以Object-End
結(jié)束的浩村,值為0x000009
。
Thanks
- rtmpdump占哟,簡直是入門引路者
最終目標(biāo)是實(shí)現(xiàn)RTMP協(xié)議心墅。還好前方有大量牛人實(shí)現(xiàn)過,感覺造輪子的時候榨乎,可以抄一下=怎燥。=
簡單地實(shí)現(xiàn)了一下,代碼地址->amf0