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);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值