TNSAnalysis

来源:互联网 发布:完美主义 知乎 编辑:程序博客网 时间:2024/05/29 03:28

参考文档:ORACLE_TNS协议.doc


用于分析截获的TNS数据(只处理了连接请求和sql语句)


/** * 用于分析TNS协议数据 * @author shanl * */public class TNSAnalysis {//private DecimalFormat df = new DecimalFormat("###.#%");private static final int HEADER_LENGTH = 8;private byte[] data = null;private int dataLen = 0;/** * 设置tns请求数据 * @param tnsData * @param tnsDataLen */public void setData(byte[] tnsData, int tnsDataLen){this.data = tnsData;this.dataLen = tnsDataLen;}/** * 返回请求类型 * @return 1:连接,6:数据 */public int getType(){return 0x00ff & (data[4]);}/** * 返回连接请求数据 * @return */public String getConnectData(){int offset = HEADER_LENGTH;int dataLen = (0xff00&(data[offset+16]<<2)) | (0x00ff&data[offset+17]);int dataOffset = (0xff00&(data[offset+18]<<2)) | (0x00ff&data[offset+19]); if(dataLen<0){return "";}return new String(data, dataOffset, dataLen);}/** * 解析oracle sql语句<br/> * 只解析符合sql命令的数据 * @return 如果返回"",表示返回的不是sql命令。否则返回sql数据。 */public String getSqlData(){String sql = "";byte[] buffer = new byte[1024*1024*2];int position = 0;int c = 0;int len = 0;if(dataLen <= 142){//System.out.println("非sql命令.");return "";}//035Eif(0x03==data[10] && 0x5E==data[11]){//System.out.println("035E");//+82c = 11 + 82;//0xFE 大数量标志,下面从0xFE下一个字节开始//1+n(字节)  1表示长度,n为数据; 1字节为0表示数量结束.if((byte)0xFE == data[c]){do{len = data[++c];for(int i=c+1,end=i+len; i<end; i++){//System.out.print((char)bys[i]);//sql += (char)bys[i];if(0x00 != data[i]){buffer[position++] = data[i];}}c += len;}while(len!=0);}else{//非大数量len = data[c];for(int i=c+1,end=i+len; i<end; i++){//System.out.print((char)bys[i]);//sql += (char)bys[i];buffer[position++] = data[i];}}}//1169if(0x11==data[10] && 0x69==data[11]){//System.out.println("1169");//+14c = 11+14;if(0x03==data[c] && 0x5E==data[++c]){//System.out.println("035E");}//+82c += 82;//0xFE 大数量标志,下面从0xFE下一个字节开始//1+n(字节)  1表示长度,n为数据; 1字节为0表示数量结束.if((byte)0xFE == data[c]){while(0!=(len = data[++c])){for(int i=c+1,end=i+len; i<end; i++){//System.out.print((char)bys[i]);//sql += (char)bys[i];if(0x00 != data[i]){buffer[position++] = data[i];}}c += len;}}else{//非大数量len = data[c];for(int i=c+1,end=i+len; i<end; i++){//System.out.print((char)bys[i]);//sql += (char)bys[i];if(0x00 != data[i]){buffer[position++] = data[i];}}}}sql = new String(buffer, 0, position);return sql;//return doFilter(sql);}}


测试类:

public class Test3 {public static void main(String[] args){t1();}static void t1(){String hexStr = "012B00000600000000001169"+"08E03868030100000001000"+"000035E0961800000000000"+"00204D68032802000088EA6"+"7030C00000000000000B8EA"+"67030000000000000000000"+"00000000000000000000000"+"00000000000000000000000"+"0000000BAEA6703F4386803"+"00000000FE4073656C65637"+"4206772616E7465652C206E"+"616D652066726F6D0A73797"+"32E706C73716C6465765F61"+"7574686F72697A6174696F6"+"E0A7768657265206772616E"+"7440656520696E202875736"+"5722C20275055424C494327"+"290A6F72206772616E74656"+"520696E202873656C656374"+"20726F6C652066726F6D207"+"379732E73657373690A6F6E"+"5F726F6C6573290A0001000"+"00000000000000000000000"+"00000000000000000000000"+"00000010000000000000000"+"0000000000000000000000";//String hexStr = "00F00000010000000138012C000008007FFF860E0000010000B6"//+"003A000002006161000000000000000000000E38000000140000000000000"//+"000284445534352495054494F4E3D28414444524553533D2850524F544F43"//+"4F4C3D5443502928484F53543D3139322E3136382E322E32332928504F525"//+"43D31353231292928434F4E4E4543545F444154413D28534552564943455F"//+"4E414D453D697032356F72636C29284349443D2850524F4752414D3D443A5"//+"C746F6F6C735C504C53514C20446576656C6F7065725C504C53514C446576"//+"2E6578652928484F53543D504336372928555345523D7368616E6C29292929";byte[] bys = new byte[hexStr.length()/2];int hex = 0;int c = 0;int len = 0;for(int i=0,j=0,endi=hexStr.length()-2; i<endi; j++){hex = Integer.valueOf(hexStr.substring(i, i+=2), 16);bys[j] = (byte)hex;//System.out.print(c+":"+h+" ");}TNSAnalysis tnsAnaly = new TNSAnalysis();tnsAnaly.setData(bys, bys.length);int type = tnsAnaly.getType();System.out.println("tns type:"+type);String tmp = null;switch(type){case 1: //连接请求tmp = tnsAnaly.getConnectData();break;case 6: //sql语句tmp = tnsAnaly.getSqlData();break;default:}System.out.println(tmp);}}