JAVA软件逆向之hxtt的Access_JDBC30.jar

前言:本文仅供学习交流,禁止用于非法用途

Access_JDBC30.jar为国人参与制作的jdbc的access驱动,但是免费版存在三个限制

1.查询50次限制

2.查询结果1000条限制

3.插入500次限制

下载地址:http://www.hxtt.com/access.zip

本文用到的工具:IDEA,Eclipse,JBE

一、使用超过限制代码查看异常栈

超过50行查询的代码如下:

package com.jdbc.test1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class hxtt50thselectlimit {
	public static Connection getConnection() {
		Connection conn = null;
		try {
			Class.forName("com.hxtt.sql.access.AccessDriver");
			conn = (Connection) DriverManager.getConnection("jdbc:Access:///D:/Database1.mdb", "", ""); // 连接数据库
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}

	public static void select() {
		Connection conn = getConnection();
		String sql = "select *from usertable";
		try {
			Statement st = conn.createStatement();
			ResultSet rs = st.executeQuery(sql); // 执行SQL语句
			while (rs.next()) {
				System.out.print(rs.getString("id") + " ");
				System.out.print(rs.getString("username") + " ");
				System.out.println(rs.getInt("age") + " ");
			}
			rs.close();
			st.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		for(int i=0;i<=60;i++) {
			System.out.println("第"+i+"次查询");
			select();
		}
	}
	
	/*
	上限1:50次查询上限
	若有限制,报错如下
	第51次查询
	java.sql.SQLException: HXTT Access Version 6.0 For Evaluation Purpose allows executing not more than 50 queries once. You can order commercial version from http://www.hxtt.com .
		at com.hxtt.b.am.a(Unknown Source)
		at com.hxtt.b.am.if(Unknown Source)
		at com.hxtt.sql.b0.a(Unknown Source)
		at com.hxtt.sql.b0.if(Unknown Source)
		at com.hxtt.sql.b0.a(Unknown Source)
		at com.hxtt.sql.an.a(Unknown Source)
		at com.hxtt.sql.an.a(Unknown Source)
		at com.hxtt.sql.an.if(Unknown Source)
		at com.hxtt.sql.an.executeQuery(Unknown Source)
		at com.jdbc.test.hxtt50limit.select(hxtt50limit.java:26)
		at com.jdbc.test.hxtt50limit.main(hxtt50limit.java:43)*/	

}

原版jar在执行到第50次查询时会报异常


这时,我们需要根据其中的异常栈推出其中的报错信息。

二、反编译找调用栈

在Eclipse下可以搜索下载Eclipse Decompiler 插件,里面集成了好几个插件,但是由于这个jar经过了混淆,部分类反编译失败,但是IDEA果然是神器,Procyon反编译不出来的IDEA自带的却能反编译出来。以下教程的行数均以IDEA反编译的行数为准

首先,根据调用栈建立空表如下,每分析一个调用,填充完一行内容

方法
调用行
实际方法定义
参数个数
at com.hxtt.b.am.a(Unknown Source)



at com.hxtt.b.am.if(Unknown Source)



at com.hxtt.sql.b0.a(Unknown Source)



at com.hxtt.sql.b0.if(Unknown Source)



at com.hxtt.sql.b0.a(Unknown Source)



at com.hxtt.sql.an.a(Unknown Source)



at com.hxtt.sql.an.a(Unknown Source)



at com.hxtt.sql.an.if(Unknown Source)



at com.hxtt.sql.an.executeQuery(Unknown Source)



首先,不管调用栈的方法,先根据提示文字not more than 50 queries once,搜索内容,这里使用反编译后的java文件,使用notepad++文件搜索


这里找到两处,两处的结果都在at com.hxtt.b.am这个类下

代码如下

private static final String dM = "allows executing not more than 50 queries once. You can order commercial version from http://www.hxtt.com .";

public static final SQLException if(
	final String s)
	{
		return a(s + " "
				+ "allows executing not more than 50 queries once. You can order commercial version from http://www.hxtt.com .",
				40960);
	}

复制与if相关的方法,新建测试文件调用throw if("HXTT Access Version 6.0 For Evaluation Purpose");可得到与报错一致的结果

接下来分析调用方法,打开IDEA,新建工程,引用这个jar


展开引用的jar,找到com.hxtt.b.am这个类

第一个要寻找的方法为com.hxtt.b.am.a(Unknown Source),实际上,通过前面的文件搜索已经找到第二个方法,这里我们点击里面的a方法,结合Ctrl键可以跳转到改方法



前两个方法找完,填一下调用栈的表

方法
调用行
实际方法定义
参数个数
at com.hxtt.b.am.a(Unknown Source)
503
public static final SQLException a(String var0, int var1) {
return new SQLException(var0, if(var1), var1);
}
2
at com.hxtt.b.am.if(Unknown Source)
550
public static final SQLException if(String var0) {
return a((String)(var0 + " " + "allows executing not more than 50 queries once. You can order commercial version from http://www.hxtt.com ."), 40960);
}
1

接下来找com.hxtt.sql.b0这个类

由于b0这个类调用了am类的if方法,并且参数为1个,根据这个线索,搜索关键字am.if(

搜索结果中有3处调用了这个方法




向上找方法名


这里正好对应上调用栈第三行的at com.hxtt.sql.b0.a(Unknown Source),填上一行

at com.hxtt.sql.b0.a(Unknown Source)
1248
private Object a(an var1, int var2, de var3, cd var4, bm var5, ba var6, a3 var7) throws SQLException {
7

继续找调用,搜索this.a( 并且参数是7个的

找到两处



不过对应的方法不是同一个,但方法名都是if,一并记录下来

at com.hxtt.sql.b0.a(Unknown Source)
1043
1080
protected synchronized void a(ay var1, an var2, int var3, de var4, ba var5) throws SQLException {
protected synchronized Object a(an var1, int var2, de var3, ba var4) throws SQLException {
5
4

到这里b0类的也就找完了,后面找com.hxtt.sql.an类的方法

搜索b0.a没有结果,但是搜索b0会发现

搞了个变量表示别找不着哦,不要搜b0.a了,搜goto.a有惊喜

前面的4个和5个参数都找着了



这俩都在一个方法里

at com.hxtt.sql.an.a(Unknown Source)
265
protected Object a(int var1, de var2, ba var3) throws SQLException {
3

后面的调用栈找的方法都一样,搜参数,看个数,如果个数一样看参数的对应类型,后面找到的如下

at com.hxtt.sql.an.a(Unknown Source)
261
protected Object a(int var1, de var2, Object var3) throws SQLException {
3
at com.hxtt.sql.an.if(Unknown Source)
228
private Object if(int var1, String var2, Object var3) throws SQLException {
3
at com.hxtt.sql.an.executeQuery(Unknown Source)
126
public ResultSet executeQuery(String var1) throws SQLException {
1

调用栈全表

方法
调用行
实际方法定义
参数个数
at com.hxtt.b.am.a(Unknown Source)
503
public static final SQLException a(String var0, int var1) {
return new SQLException(var0, if(var1), var1);
}
2
at com.hxtt.b.am.if(Unknown Source)
550
public static final SQLException if(String var0) {
return a((String)(var0 + " " + "allows executing not more than 50 queries once. You can order commercial version from http://www.hxtt.com ."), 40960);
}
1
at com.hxtt.sql.b0.a(Unknown Source)
1248
private Object a(an var1, int var2, de var3, cd var4, bm var5, ba var6, a3 var7) throws SQLException {
7
at com.hxtt.sql.b0.if(Unknown Source)
1152
private Object if(an var1, int var2, de var3, cd var4, bm var5, ba var6, a3 var7) throws SQLException {
 
at com.hxtt.sql.b0.a(Unknown Source)
1043
1080
protected synchronized void a(ay var1, an var2, int var3, de var4, ba var5) throws SQLException {
protected synchronized Object a(an var1, int var2, de var3, ba var4) throws SQLException {
5
4
at com.hxtt.sql.an.a(Unknown Source)
265
protected Object a(int var1, de var2, ba var3) throws SQLException {
3
at com.hxtt.sql.an.a(Unknown Source)
261
protected Object a(int var1, de var2, Object var3) throws SQLException {
3
at com.hxtt.sql.an.if(Unknown Source)
228
private Object if(int var1, String var2, Object var3) throws SQLException {
3
at com.hxtt.sql.an.executeQuery(Unknown Source)
126
public ResultSet executeQuery(String var1) throws SQLException {
1

其实调用栈不用分析这么多,分析到b0已经足够,往后分析的只是理一理思路。

由于超过限制是抛出异常,我们不让它抛出异常就可以了

之前找到am.if之前有个throw,那么这一句就是抛出异常的了


理论上来说,如果有源代码,只要去掉throw这句就好了。或者把前面的判断的值改为false。case 75和case 76的同样也是这个道理

三、使用JBE修改字节码

之前使用Javassist该过一些字节码,虽然Javassist有直接操作字节码的API,但是都很少有人用,逆向的时候多用来改方法的返回值或者直接重写方法体。由于这个是改方法体里面的东西,还是使用专用的工具比较好。

这里可以看到case的字节码呈现


这里是case 73 里面的字节码内容分,看到sipush 503的意思是把503这个数压入栈顶,后面用来做比较,看到这里就很简单了吧,把MAX_INT放入栈顶比较完不就一直是false了,在常量池建立一个整形常量,值为2147483647,后面ldc #常量编号(JBE编辑的时候直接用 ldc 2147483647)就行了,后面两个case同理




猜你喜欢

转载自blog.csdn.net/gsls200808/article/details/79874527