1 协议分析的基本原则和方法
1.1 TLV方法:type、length、value类型、长度、数值
由于具体数值的不确定、长度可变,因此绝大部分协议,都会将长度放在前面,后面再跟具体的数据。oracle的dmp文件的数据解析没有type字段,数据类型是集中说明。
原则:先是长度值,然后是具体数据。
1.2 字节序问题
X86架构都是小端优先。 读到长度 10 00,其实就是 0010, 16字节长。 字、双字有此类问题,字符串无此类问题。
1.3 分析方法、工具
linux下用hexdump -C aa.dmp 可以得到二进制及其字符, windows下可以用支持二进制的编辑器,比如ultraedit。
000d9890 54 41 54 52 45 43 3b 20 42 45 47 49 4e 20 53 52 |TATREC; BEGIN SR|
000d98a0 45 43 2e 4d 49 4e 56 41 4c 20 3a 3d 20 4e 55 4c |EC.MINVAL := NUL|
000d98b0 4c 3b 20 53 52 45 43 2e 4d 41 58 56 41 4c 20 3a |L; SREC.MAXVAL :|
000d98c0 3d 20 4e 55 4c 4c 3b 20 53 52 45 43 2e 45 41 56 |= NULL; SREC.EAV|
最左边是序号,16字节一行。最右边对应的是ASCII码。
1.4 字符集、编码
可以看到在计算机里存储的都是二进制或者说十六进制,具体这个数值代表什么意思,需要由编码来确定。仅就字符集来说,有下列几种。
ASCII, 一个字节代表一个字符,共256, 可见字符也就常见的数字、字母、标点符号,0a 换行符\n, 0d 回车 \r, 20 空格,数字30-39,大写字母41-5a,小写61-7a
unicode 两字节代表一字符,原来的英文,需要高字节填0。
UTF-8: UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0x00-0x7F之间的字符,UTF-8编码与ASCII编码完全相同。 汉字是3个字节
GBK:两字节表示1汉字,按照拼音排序编码
2 dmp文件的基本流程
非数据部分就是字符(包括汉字),以换行符隔开。所以全部解析对了,就不会出现不可见字符,blob的内容不可打印。
大的流程:建表语句create table, 插入数据 insert,后面还有主外键的添加,视图、函数等。
重点、难点就是插入数据
1) INSERT INTO "BONUS" ("ENAME", "JOB", "SAL", "COMM") VALUES (:1, :2, :3, :4)
2) 数据类型 , 先是字段数,然后是每个字段的数据类型,
000024e0 28 22 45 4e 41 4d 45 22 2c 20 22 4a 4f 42 22 2c |("ENAME", "JOB",|
000024f0 20 22 53 41 4c 22 2c 20 22 43 4f 4d 4d 22 29 20 | "SAL", "COMM") |
00002500 56 41 4c 55 45 53 20 28 3a 31 2c 20 3a 32 2c 20 |VALUES (:1, :2, |
00002510 3a 33 2c 20 3a 34 29 0a 04 00 01 00 0a 00 54 03 |:3, :4).......T.|
00002520 01 00 01 00 09 00 54 03 01 00 02 00 16 00 02 00 |......T.........|
00002530 16 00 00 00 00 00 ff ff 0a 41 4e 41 4c 53 54 41 |.........ANALSTA|
0400, 说明是四个字段,01 00 0a 00 54 03 01 00, 说明是varchar2,长度为 10(0a 00),02001600是number数值类型
主要的数据类型: 01 00 xx 00 54 03 01 00 varchar2 02 00 16 00 number
0c 00 07 00 date
71 00 20 00 blob
70 00 20 00 54 03 01 00 clob
与建表语句符合。 CREATE TABLE "BONUS" ("ENAME" VARCHAR2(10), "JOB" VARCHAR2(9), "SAL" NUMBER, "COMM" NUMBER)
后面 00000000,四个00代表类型说明完毕。再后面的ffff,说明insert 语句完毕。
3) 具体数值
先看没有blob、clob字段的。在类型说明完毕后,就是每条记录的内容。
00033830 54 20 49 4e 54 4f 20 22 53 41 4c 47 52 41 44 45 |T INTO "SALGRADE|
00033840 22 20 28 22 47 52 41 44 45 22 2c 20 22 4c 4f 53 |" ("GRADE", "LOS|
00033850 41 4c 22 2c 20 22 48 49 53 41 4c 22 29 20 56 41 |AL", "HISAL") VA|
00033860 4c 55 45 53 20 28 3a 31 2c 20 3a 32 2c 20 3a 33 |LUES (:1, :2, :3|
00033870 29 0a 03 00 02 00 16 00 02 00 16 00 02 00 16 00 |)...............|
00033880 00 00 00 00 02 00 c1 02 02 00 c2 08 02 00 c2 0d |................|
00033890 00 00 02 00 c1 03 03 00 c2 0d 02 02 00 c2 0f 00 |................|
000338a0 00 02 00 c1 04 03 00 c2 0f 02 02 00 c2 15 00 00 |................|
000338b0 02 00 c1 05 03 00 c2 15 02 02 00 c2 1f 00 00 02 |................|
000338c0 00 c1 06 03 00 c2 1f 02 03 00 c2 64 64 00 00 ff |...........dd...|
000338d0 ff 0a 41 4e 41 4c 53 54 41 54 53 20 54 52 20 22 |..ANALSTATS TR "|
00 00 00 00 后开始具体的每条记录, 0200, 2个字节, c102,就是1。 数字的简单,每个字节的结果减去1,然后每个字节按位置*100,减1的原因是防止出现00,否则会跟结束符混淆。每条记录以0000结束。 ffff则当前表的insert结束。