TNSAnalysis

參考文檔: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 "";
		}
		
		//035E
		if(0x03==data[10] && 0x5E==data[11]){
//			System.out.println("035E");
						
			//+82
			c = 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];
				}
			}	
		}
		
		//1169
		if(0x11==data[10] && 0x69==data[11]){
//			System.out.println("1169");
			
			//+14
			c = 11+14;
			if(0x03==data[c] && 0x5E==data[++c]){
//				System.out.println("035E");
			}
			
			//+82
			c += 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);
	}
}


發佈了65 篇原創文章 · 獲贊 18 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章