Oracle TNS 314 協議分析:四、SQL執行流程與包分析

SQL 命令典型執行過程(以Select爲例)

Client

 

 

 

Server

1

-------

Data Piggyback(11) Cursor Close All(69)

注意此處也有可能是 116b,035e,0303

----->

具體語句

2

<-----

Data DescribeInfo(10)  17

-------

返回列

3

-------

Data UOCIFun(03) FetchARow(05)

----->

獲取其他值

4

<-----

Data RowTransferHeader(06)  01

-------

返回值

11g,12c有三種sql命令執行的模式:

  1. 第一種是前序一個piggyback(1169)包,然後緊接execute buddle command(035e)
  2. 第二種是前序一個session switch piggy back(116b)包,然後緊接execute buddle command(035e)
  3. 第三種是直接發送execute buddle command(035e),前者可以看做只是在後者前面加了一個頭

參考網上其他文章Oracle 9.2還有可能使用0303來發命令,而對其的返回(上述流程中2處)可能使用data 1019的包

使用0x1169執行SQL命令的情況

包格式

 

32bit

64bit

 

序列號

1

1

 

Piggyback cusor close all (1169) command

9 or 13

16 or 20

 

Buddle execute (035e)command

變長

變長

 

參考網上一些文章,Oracle9,10  Piggy Command長度爲12

1169 command

這個部分是變長的,下面是幾種變化,都以feMagic(定義參見本系列第二篇 《Oracle TNS 314 協議分析---基礎包結構》)數組開頭,有的長16個字節,有的20個字節

語句

Plsql

Sqlplus

Navicat

Select

fe ff ff ff ff ff ff ff

01 00 00 00

04 00 00 00

fe ff ff ff ff ff ff ff

01 00 00 00 00 00 00 00

05 00 00 00

當沒有輸入;05會變03

fe ff ff ff ff ff ff ff

01 00 00 00

05 00 00 00

Update

fe ff ff ff ff ff ff ff

01 00 00 00

02 00 00 00

fe ff ff ff ff ff ff ff

01 00 00 00 00 00 00 00 06 00 00 00

 

Delete

fe ff ff ff ff ff ff ff

01 00 00 00

02 00 00 00

fe ff ff ff ff ff ff ff

01 00 00 00 00 00 00 00 03 00 00 00

 

Insert

 

fe ff ff ff ff ff ff ff

01 00 00 00 00 00 00 00 05 00 00 00

有時是0b 有時是09

 

CreateTable

 

fe ff ff ff ff ff ff ff

01 00 00 00 00 00 00 00 07 00 00 00

 

使用0x116b執行SQL命令的情況

包格式

 

32bit

64bit

 

序列號

1

1

 

Piggy command

12

12

 

Buddle execute command 035e

變長

變長

 

Oracle9 10  Piggy Command長度也爲12

Buddle execute Command  035e

 

32bit

64bit

ThinClient

 

序列號

1

1

1

 

命令相關

8

8

5

 

feMagic

1

8

1

 

語句長度相關字段

2

2

1

 

未知 2 2 1  

固定字節

54

152

41

所有命令都相同

SQL命令

變長

變長

變長

 

尾部字節

52

52

17

01開頭

根據其他文章來看Oracle9、10(TNS312,313)下這個包有一定區別(主要是從序列號到SQL的字節數分別爲80,92,而11,12爲172)下面是根據其他文章分析的包結構

序列號

1

 

固定長度頭部

80 or 92

 

SQL命令

變長

SQL查詢語句

尾部字節

48

 

ThinClient發出的包與此相差較大,將另文描述

命令相關

各個平臺各種語句調用如下

語句

PlSQL

SQLplus

Navicat

Thin Client

Select

61 80 00 00 00 00 00 00

61 80 00 00 00 00 00 00

61 81 00 00 00 00 00 00

02 80 21 00 01

Update

21 80 00 00 00 00 00 00

21 80 00 00 00 00 00 00

21 81 00 00 00 00 00 00

 

Delete

21 80 00 00 00 00 00 00

21 80 00 00 00 00 00 00

21 81 00 00 00 00 00 00

 

Insert

21 80 00 00 00 00 00 00

21 80 00 00 00 00 00 00

21 81 00 00 00 00 00 00

 

CreateTable

21 80 00 00 00 00 00 00

21 80 00 00 00 00 00 00

21 81 00 00 00 00 00 00

 

AlterTable

21 80 00 00 00 00 00 00

21 80 00 00 00 00 00 00

21 81 00 00 00 00 00 00

 

紅色部分見過這些取值

61 80 plsql select

61 81 navicat select

01 80 02 plsql select another

29 04 04 plsql declare function

29 05 04 navicat declare function

21 80 plsql 除select 外

21 81 navicat 除select 外

21 01 04 navicat call function

而在ThinClient中,返現Endian會發生變化,且前序一個長度字節的情況,且此字段長度也不相同

於是21 80會變成 02 80 21

語句長度字段

此字節與sql長度有關,OCI Client 下爲sql長度字段大小*3,如果sql較長,則會產生進位,注意進位後是little endian的形式,02 01 表示102,ThinClient下直接就是語句長度,ThinClient下語句前不會再附加長度,此處是獲取長度的最佳地點。

39 00 00 00 表示 0x39

21 01 00 00 表示 0x121

在命令超長的情況下,這個長度字段非常有用,因爲一個command會在多個TNSData包中出現,必須用這個長度字段和TNS Command Header的長度字段,才能正確組合超長命令。

上圖中可以看出,一個超長命令可能跨越多個TNS包,如果一個TNS包中的Command長度不足,說明還沒有收取完畢,需要繼續從buffer中讀取數據,直到命令長度滿足要求。另外處理程序如果工作在應用層,那麼處理程序從buffer中取出的數據可能橫跨多個TNS包,由於每個TNS包都有自己的頭部,就會在解析的命令中引入這些額外的頭部。爲了跳過這些頭部,必須利用第一個TNS 的package Length作爲指針,逐個找到每個頭部,從而處理這些額外的10字節頭。

固定字節

64bit OCI Client(SQLPLUS,PLSQL,Navicat)

後續19*8=152個固定字節,使用navicat和plsql無論什麼命令都相同:

0000 fe ff ff ff ff ff ff ff 0d 00 00 00 fe ff ff ff ........ ........

0010 ff ff ff ff fe ff ff ff ff ff ff ff 00 00 00 00 ........ ........

0020 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........

0030 00 00 00 00 00 00 00 00 00 00 00 00 fe ff ff ff ........ ........

0040 ff ff ff ff 00 00 00 00 00 00 00 00 fe ff ff ff ........ ........

0050 ff ff ff ff fe ff ff ff ff ff ff ff fe ff ff ff ........ ........

0060 ff ff ff ff 00 00 00 00 00 00 00 00 fe ff ff ff ........ ........

0070 ff ff ff ff fe ff ff ff ff ff ff ff 00 00 00 00 ........ ........

0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........

0090 00 00 00 00 00 00 00 00   ........

32bit OCI Client(SQLPLUS,PLSQL,Navicat)

後續54個固定字節

0000  01 0d 00 00 00 01 01 00  00 00 00 01 00 00 00 00   ........ ........

0010  00 00 00 00 00 00 00 00  00 01 00 01 01 01 00 00   ........ ........

0020  00 00 00 00 00 00 01 01  00 00 00 00 00 00 00 00   ........ ........

0030  00 00 00 00 00 00

Thin Client(JAVA)

後續41個固定字節

0000  01 0d 00 00 04 ff ff ff  ff 01 0a 04 7f ff ff ff ........ ........

0010  00 00 00 00 00 00 00 00  00 00 00 01 00 00 00 00 ........ ........

0020  00 00 00 00 00 00 00 00  00

Sql命令

後續立刻接sql,sql遵循變長字符串或數組形式,即len+值定義,第一個字節爲長度,或fe表示數組,數組中元素也是變長字符串,當爲數組時數組由00結尾,所有sql都後續01。如果輸入時忘記輸入;語句後會多個0a,所以結尾看起來是0a01或0a0001(變長)。

定長命令

00A0                                          13 53 45   ........ ......SE

00B0  4c 45 43 54 20 2a 20 46  52 4f 4d 20 44 45 50 54   LECT * F ROM DEPT

00C0  0a 01 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........

00D0  00 00 00 00 00 00 00 00  00 00 00 00 00 01 00 00   ........ ........

00E0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........

00F0  00 00 00 00 00     

變長命令

ThinClient 無長度前序命令

ThinClient下發現此包無前序長度,長度由前面長度相關字段確定

​​​​​​​包示例(Navicat 15 premium 64bit to Oracle 12)

​​​​​​​ 0303 QUERY

根據其他文章在Oracle9.2下有可能使用這種包發送命令(本文11,12 64bit下未測得),其格式如下

Request id

1

 

Magic

12

 

Data Format

可變

查詢語句

​​​​​​通過​Transfer header 獲取返回值

包示例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章