简单逆向Java程序
前置
来源
这个程序是我同学编写的一个学生分数管理系统,我将对这个已经编译的程序进行测试、逆向,找出其中的问题,并进行改进。
运行环境
- macOS 15.4
- IntelliJ IDEA 2024.2.3
- OpenJDK 23.0.2
- TomCat 11.0.4
- Safari 15.4
运行结果





主要问题
在使用程序后发现:
- 缺少绩点计算
- 添加学生时没有对学号进行唯一性检查
- 添加成绩时没有对成绩进行唯一性检查
接下来对这些问题进行改进。
逆向
由于没有源码,需要通过逆向方式恢复代码。
Java 的 .class 文件可以使用 FernFlower 反编译器(IDEA
内置)进行反编译。
Score.class
package com.example.javadzy;
import java.io.Serializable;
public class Score implements Serializable {
private String course;
private int grade;
public Score(String course, int grade) {
this.course = course;
this.grade = grade;
}
public String getCourse() {
return this.course;
}
public void setCourse(String course) {
this.course = course;
}
public int getGrade() {
return this.grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
}
Student.class
package com.example.javadzy;
import java.io.Serializable;
import java.util.ArrayList;
public class Student implements Serializable {
private String name;
private ArrayList<Score> scores;
public Student(String name) {
this.name = name;
this.scores = new ArrayList<>();
}
public String getName() {
return this.name;
}
public ArrayList<Score> getScores() {
return this.scores;
}
public void addScore(Score score) {
this.scores.add(score);
}
}
Statistics 统计类
public class Statistics {
public float average = 0.0F;
public int max = 0;
public int min = 100;
public float passRate = 0.0F;
public Statistics(Student student) {
int sum = 0;
int passCount = 0;
for (Score score : student.getScores()) {
sum += score.getGrade();
if (score.getGrade() > max) max = score.getGrade();
if (score.getGrade() < min) min = score.getGrade();
if (score.getGrade() >= 60) passCount++;
}
if (!student.getScores().isEmpty()) {
average = (float) sum / student.getScores().size();
passRate = (float) passCount / student.getScores().size();
}
}
}
数据存储
程序通过序列化保存学生数据。
ObjectOutputStream
ObjectInputStream
数据结构:
TreeMap<Integer, Student>
GPA计算改进
public double gpa(float score) {
if (score >= 90) return 4;
else if (score >= 85) return 3.7;
else if (score >= 82) return 3.3;
else if (score >= 78) return 3;
else if (score >= 75) return 2.7;
else if (score >= 72) return 2.3;
else if (score >= 68) return 2;
else if (score >= 64) return 1.5;
else if (score >= 60) return 1;
else return 0;
}
JSP页面展示
<p>
平均绩点:<%= stats.gpa %>
平均分:<%= stats.average %>
最高分:<%= stats.max %>
最低分:<%= stats.min %>
及格率:<%= stats.passRate %>
</p>
数据结构优化
原结构:
ArrayList<Score>
复杂度:
O(n)
优化为:
HashMap<String, Integer>
优势:
- 查找 O(1)
- 方便检测课程重复
新结构
private HashMap<String, Integer> scores;
public void addScore(String course, Integer score) {
if (scores.containsKey(course)) {
throw new RuntimeException("课程重复");
}
scores.put(course, score);
}
重构结果



总结
通过这次逆向工程:
- 理解了 Java 反编译流程
- 分析了程序结构
- 重构了数据结构
- 增加了 GPA 功能
这也是一次典型的 Java程序逆向 + 重构实践。
posted on 2026-03-12 09:21 litroenade 阅读(13) 评论(0) 收藏 举报
浙公网安备 33010602011771号