天天看點

AMF學習2遠端調用的封裝

前言的前2位元組用于說明amf的版本,目前amf有2個版本amf0和amf3.如使用amf0則是:00 00

第3和第4位元組用16位整數表示amf頭的數量。

每一個amf頭是由以下四部分組成:

utf string 表示header的名字

boolean 表示該header是否是必須的

int32表示header的長度,但是好像很多情況下該值為ff ff ff ff,似乎這個字段沒有意義。

variable變量是某種amf資料類型。

在header表示完後,接下來是一個16位的整數用來表示amf主體的數量,在這個數量之後才是amf主體。

amf主體主要由以下四部分組成:

utf string - response表示請求的類和方法或響應的結果。

utf string - target是一個辨別,其作用就是為了實作請求和響應的對應,通過target找到該響應對應的請求。一般使用自增整數。

int32- 表示主體的長度,該字段一般沒有什麼用

variable變量表示主體的資料。

主體響應是用戶端向伺服器發送一個amf請求以後伺服器做出的和請求的主體格式相同的amf響應,但是主體響應中的内容有所不同:

response: 被設定為字元串‘null’.

target: 是請求的target值再加上“/onstatus”, “onresult”, 或者 “/ondebugevents”組成. “/onstatus” 是為運作時錯誤而準備的我們一般不關心這個. “/onresult” 表示該請求被正确調用. “/ondebugevents” 是在調試時使用的,這裡也不用關心. 如果請求的target是‘/1’, 那麼被成功調用以後的主體響應應該是: ‘/1/onresult’ 。

data:就是響應後傳回的amf對象。

說了這麼多估計還是感覺比較抽象,下面給出個執行個體:

amf 16進制内容

00000000h: 00 00 00 00 00 01 00 1b 7a 68 2e 66 6c 65 65 74 ; ........zh.fleet

00000010h: 53 65 72 76 69 63 65 2e 67 65 74 46 6c 65 65 74 ; service.getfleet

00000020h: 52 6f 77 00 03 2f 37 39 00 00 00 13 0a 00 00 00 ; row../79........

00000030h: 03 02 00 01 35 02 00 03 38 34 35 02 00 01 35 ; ....5...845...5

以上是用戶端向伺服器發送的一個amf請求。我們可以按照前面說的封裝方式将該amf解析如下:

00 00(amf0版本)00 00(header個數為0)00 01(amf主體有1個)

00 1b(請求的方法的字元串長度為27個位元組)

7a ……77(這27個直接就是調用的類和方法:“zh.fleetservice.getfleetrow”)

00 03(請求的target字元串長3位元組) 2f 37 39(target的内容:“/79”)

00 00 00 13(主體的長度為19)

0a(傳入的變量是一個array)00 00 00 03(該array的長度為3)02 00 01 35(array的第一個值是字元串“5”)02 00 03 38 34 35(array的第二個值是字元串“845”)02 00 01 35(array的第三個值是字元串“5”)

現在整個amf對象都解析出來了,我們可以認為是用戶端調用了伺服器的方法:zh.fleetservice.getfleetrow("5", "845", "5")

伺服器傳回的amf檔案的内容的解析方式相同,這裡我就不再重複了。

現在我們已經對amf檔案有了一個清晰的認識了。那麼接下來就是要抓包,看某些在flex上的操作對應的發送了什麼amf檔案,伺服器傳回了什麼amf檔案。将這些amf檔案解析出來然後就可以看到調用了api了。

繼續閱讀