test.class和Time4.class(java逆向)

201807 test.class Time4.class

第一小题:test.class

首先,明确一下题目的意思和我们目的:
题目其实输出了两个部分,第一个就是由“201807”对应的“Welcome”:
在这里插入图片描述

第二个是判断当前时间是否在“2018-7-1 00:00:00”和“2018-7-31 23:59:59”之间,如果是则输出当前时间并等待输入,如果不是则输出当前时间并退出。
在这里插入图片描述

方法有很多种,这里就没有用第一题的解法了。尝试了另外两种不同的解法。

方法一:直接用二进制编辑器修改.class文件

先用编译器打开test.class查看源代码:
在这里插入图片描述

查看源代码,可以发现两个日期格式的参数是String类型,且本身没有类型检查,而我们的目的是使代码输出“Welcome”,而源代码只有在当前日期为“201807”时输出“Welcome”,所以我们把“yyyyMM”字符串直接改为“201807”字符串即可输出“Welcome”。
用编辑器以16进制打开test.class,找到“yyyyMM”字符串所在的那一行:
在这里插入图片描述

把“yyyyMM”字符串直接改为“201807”字符串(16进制是修改对应的ASCII码):
在这里插入图片描述

保存test.class,运行:
在这里插入图片描述

这里我们只是解决了第一个问题输出Welcome,还有第二个问题使当前时间符合规范不退出。我们没有跟上面一样把“yyyy-MM-dd HH:mm:ss”字符串直接改为“2018-07-24 12:12:12”字符串,因为源代码中使用的SimpleDateFormat类的parse()函数需要正则表达式来分割时间,我们把“yyyy-MM-dd HH:mm:ss”字符串直接改为“2018-07-24 12:12:12”字符串会报错。
所以我们只能修改其他的地方了。既然是比较当前时间与“2018-7-1 00:00:00”和“2018-7-31 23:59:59”的大小,我们没法把时间改在这里面,但我们可以把时间改成无限大,即把“2018-7-1 00:00:00”改为“0000-0-0 00:00:00”、把“2018-7-31 23:59:59”和“9999-12-31 23:59:59”。
在这里插入图片描述

修改:这里因为内存已经限定了7的位数只有一位,所以我们只能把它改成最大的9了,最多将把“2018-7-1 00:00:00”改为“0000-0-0 00:00:00”、把“2018-7-31 23:59:59”和“9999-9-31 23:59:59”。但其实还可以把31、23、59也改成99,日期类即使超过了一般的限制也没什么关系,但反正已经改成9999年之后了,差几个月也没什么关系了:
在这里插入图片描述

保存test.class,运行:
在这里插入图片描述

成功输出“Welcome”且没有退出,进入了程序。

方法二:用Bytecode字节码查看器和JClassLib包的代码修改.class文件

用编译器打开.class文件,查看.class源码:
在这里插入图片描述

发现代码的逻辑是当输入201807时,先将201807转换成大整数,然后201807乘以445再加上43597487644106,再将这个大整数转换成字符串就“是Welcome”了。而我们要使所有的时间都可以输入“Welcome”,所以关键就是修改445和43597487644106。
我的想法就是将445改为0,然后将43597487644106改为“Welcome”对应的大整数24599839172947301。
求Welcome对应大整数的源代码:

import java.math.BigInteger;

/**
 * 文件注释:
 *
 * @Auther: Legends
 * @Date: /22 18:44
 * @Description:   求Welecome对应的大整数
 */
public class New {
    public static void main(String[] args) {
        String test = "Welcome";
        //字符串转16进制字符串
        String s4 = str2HexStr(test);
        //再转大整数
        BigInteger biginteger = HexStr2int(s4);
        System.out.println("Welcome对应的大整数为:"+biginteger);
    }

    public static BigInteger HexStr2int(String s)
    {
        BigInteger biginteger = new BigInteger(s, 16);
        return biginteger;
    }

    public static String str2HexStr(String s)
    {
        char ac[] = "0123456789ABCDEF".toCharArray();
        StringBuilder stringbuilder = new StringBuilder("");
        byte abyte0[] = s.getBytes();
        for(int j = 0; j < abyte0.length; j++)
        {
            int i = (abyte0[j] & 0xf0) >> 4;
            stringbuilder.append(ac[i]);
            i = abyte0[j] & 0xf;
            stringbuilder.append(ac[i]);
        }
        return stringbuilder.toString().trim();
    }
}

代码结果截图:
在这里插入图片描述

这样不管输入的日期时什么因为是乘以0,所以消除了日期的影响,直接将大整数“24599839172947301”转换成对应的字符串“Welcome”即可。这里我们之所以没有像方法一一样直接用16进制编辑器修改,是因为在16进制编辑器中的“43597487644106”是占14位,而“24599839172947301”是占17位,无法直接通过编辑器直接修改16进制代码扩容。所以这就是我们用代码来修改的原因。
先用java字节码查看软件Bytecode查看test.class对应的字节码:
在这里插入图片描述

我们要修改的常量字符串有:“2018-7-1 00:00:00”、“2018-7-31 23:59:59”、“445”、“43597487644106”(也可以修改“yyyyMM”,但修改这个已经在方法一中实现了,就不重复修改了),找到对应的常量字节码在常量池中的位置:
“2018-7-1 00:00:00”:
在这里插入图片描述
“2018-7-31 23:59:59”:
在这里插入图片描述

“445”:
在这里插入图片描述

“43597487644106”:
在这里插入图片描述

78、79、89、92、CONSTANT_Utf8_info这些都是字符串常量的标识,我们待会就通过这些标识找到它们,再修改。

源代码:

/**
 * 文件注释:
 *
 * @Auther: Legends
 * @Date: /22 21:48
 * @Description:  修改.class的方法
 */
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.gjt.jclasslib.io.ClassFileWriter;
import org.gjt.jclasslib.structures.CPInfo;
import org.gjt.jclasslib.structures.ClassFile;
import org.gjt.jclasslib.structures.InvalidByteCodeException;
import org.gjt.jclasslib.structures.constants.ConstantUtf8Info;

public class ChangeClass
{
    public static void main(String[] args){
        //用文件输入流将.class文件的内容读入
        String filePath = "D:\\test.class";
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(filePath);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //数据输入流
        DataInput di = new DataInputStream(fis);
        ClassFile cf = new ClassFile();
        try {
            //即将数据流读入ClassFile类的对象
            cf.read(di);
        } catch (InvalidByteCodeException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        //获取常量池数组
        CPInfo[] infos = cf.getConstantPool();
        //遍历常量池
        int count = infos.length;
        for (int i = 0; i < count; i++) {
                //找到第78个常量字符串,修改“2018-7-1 00:00:00”为“0000-0-0 00:00:00”
                if(i == 78){
                    ConstantUtf8Info uInfo = (ConstantUtf8Info)infos[i];
                    uInfo.setBytes("0000-0-0 00:00:00".getBytes());
                    infos[i]=uInfo;
                }
                //找到第79个常量字符串,修改“2018-7-31 23:59:59”为“9999-9-31 23:59:59”
                if(i == 79){
                    ConstantUtf8Info uInfo = (ConstantUtf8Info)infos[i];
                    uInfo.setBytes("9999-9-31 23:59:59".getBytes());
                    infos[i]=uInfo;
                }
                //找到第79个常量字符串,修改“445”为“000”
                if(i == 89){
                    ConstantUtf8Info uInfo = (ConstantUtf8Info)infos[i];
                    uInfo.setBytes("000".getBytes());
                    infos[i]=uInfo;
                }
                //找到第79个常量字符串,修改“43597487644106”为“24599839172947301”
                if(i == 92){
                    ConstantUtf8Info uInfo = (ConstantUtf8Info)infos[i];
                    uInfo.setBytes("24599839172947301".getBytes());
                    infos[i]=uInfo;
                }
                //逐个输出常量池中的常量和类型
                if (infos[i] != null) {
                    System.out.print(i);
                    System.out.print(" = ");
                    try {
                        System.out.print(infos[i].getVerbose());
                    } catch (InvalidByteCodeException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.print(" = ");
                    System.out.println(infos[i].getTagVerbose());
                    if(i == 92){
                        break;
                    }
                }
        }
        cf.setConstantPool(infos);
        try {
            fis.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        File f = new File(filePath);
        try {
            ClassFileWriter.writeToFile(f, cf);
        } catch (InvalidByteCodeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

实验结果截图:
在这里插入图片描述

修改后的.class文件:
在这里插入图片描述

运行test.class文件:
在这里插入图片描述

成功输出结果Welecome,且没有退出!!!

第二小题:Time4.class

先用编译器反编译查看.class源代码:
在这里插入图片描述

题目是比较了当前日期与“2018-07”是否相等,又比较了当前的年份、“_”、当前月份连接而成的字符串与“2018-07”是否相等,我们在使用本机时间进入程序的时候是走的第三个分支:JOptionPane.showMessageDialog(var9, var3 + var10.m(var3) + var10.u(var8));所以关键就在于m函数和u函数。m函数是将p = "070097105108101100033"转成字符串“Failed!”。而u函数是一个字符自身求与的函数,返回结果为6个空格!!!
题目比较简单,所以我们也没有用第一题和第二题第一问的复杂方法了。

方法一:直接将当前日期的初始化格式“yyyy-MM”改为“2018-07”:

这样无论当前时间为多少,程序都会认为我们的时间是“2018-07”。用编辑器以16进制打开Time4.class,找到“yyyy-MM”:
在这里插入图片描述

修改为“2018-07”:
在这里插入图片描述

保存,运行Time4.classs:
在这里插入图片描述

果然所有的当前时间都被初始化为“2018-07”了,并成功输出了Welcome。

方法二:将p = “070097105108101100033”(对应字符串Failed!)改为p=”087101108099111109101”(对应字符串Welcome):

在这里插入图片描述

这里刚好因为Failed!后面加了个!才与Welcome长度相等,否则长度不相等就得用第一问的方法修改常量池了。直接修改后:
在这里插入图片描述

保存,运行Time4.class:
在这里插入图片描述

成功在当前时间输出Welcome。

第三种方法是,将时间变量var1 = “2018-07”,修改为当前时间“2019-03”:

使得程序判定进入s函数,再将d = “%5;+B=.”(对应Failed!)修改为“[KEU>CR”(对应Welcome),但这并不是个一劳永逸的办法,每个月都得修改一次当前时间,就不使用了。

好的,使用 MyBatis-Plus 逆向工程生成实体类的步骤如下: 1. 首先需要在 pom.xml 中添加 MyBatis-Plus 的依赖: ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.2</version> </dependency> ``` 2. 在 resources 目录下创建一个名为 generator 的文件夹,用来存放 MyBatis-Plus 的代码生成器配置文件。 3. 在 generator 文件夹下创建一个名为 generatorConfig.xml 的配置文件,配置文件内容如下: ```xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <context id="mysql" targetRuntime="MyBatis3"> <!-- 数据库连接信息 --> <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/test?serverTimezone=UTC" userId="root" password="root"> </jdbcConnection> <!-- 指定实体类生成的包名和位置 --> <javaModelGenerator targetPackage="com.example.entity" targetProject="src/main/java"> <property name="enableSubPackages" value="true"/> <property name="trimStrings" value="true"/> </javaModelGenerator> <!-- 指定 Mapper 接口生成的包名和位置 --> <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"> <property name="enableSubPackages" value="true"/> </sqlMapGenerator> <!-- 指定 Mapper 映射文件生成的包名和位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.mapper" targetProject="src/main/java"> <property name="enableSubPackages" value="true"/> </javaClientGenerator> <!-- 指定要生成的表名 --> <table tableName="user"></table> </context> </generatorConfiguration> ``` 4. 在 Maven 的 Plugins 中添加 MyBatis-Plus 的代码生成器插件: ```xml <build> <plugins> <!-- MyBatis-Plus 代码生成器插件 --> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.4.0</version> <dependencies> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.2</version> </dependency> </dependencies> <configuration> <!-- 指定 MyBatis-Plus 代码生成器配置文件 --> <configurationFile>src/main/resources/generator/generatorConfig.xml</configurationFile> <overwrite>true</overwrite> <verbose>true</verbose> </configuration> </plugin> </plugins> </build> ``` 5. 执行 Maven 的 mybatis-generator:generate 命令,即可生成实体类: ```bash mvn mybatis-generator:generate ``` 以上就是使用 MyBatis-Plus 的逆向工程生成实体类的步骤。需要注意的是,配置文件中需要指定数据库连接信息、实体类、Mapper 接口和映射文件的生成位置以及要生成的表名等信息。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值