hpnog/javaDependenceGraph
GitHub: hpnog/javaDependenceGraph
一个基于GUI的Java程序依赖图生成工具,集成了语法语义分析、控制流与数据依赖可视化,并支持导出为DOT格式。
Stars: 23 | Forks: 6
# javaDependenceGraph - JAST2DyPDG
## 安装与运行
为了安装并运行此应用程序,请确保您已安装 **jdk** 和 **maven**。
```
cd COMP_project/
mvn clean install
mvn exec:java -Dexec.mainClass=pdg_gui.mainframe
```
这将启动项目的 GUI。例如,为了进行测试,请选择 examples 文件夹中的 *.java 文件以及“Call Graph”。
## 概述
该工具是一个针对 _Java_ 编程语言输入文件的 **Program Dependence Graph** 生成器,其结果可输出为 dot 文件。
它封装了一个易于使用的 GUI,以便通过 **PDG** 的中间表示形式更好地分析提供给应用程序的代码。
该项目是作为 FEUP 编译器课程的项目开发的。
### 功能集:
* 对给定代码进行语法检查(通过 GUI 报告错误);
* 对给定代码进行语义检查(通过 GUI 报告错误);
* 为提供的整个文件生成 Program Dependence Graph(包含 Control Flow 边和 Data Dependecy 边);
* 将生成的图导出为 dot 文件格式。
## 语法分析
分析由项目中使用的 _javaparser library_ 执行。程序执行在遇到第一个语法错误时终止,并在程序 GUI 中报告。
所使用的 javaparser 通过 CompilationUnit 对象提供输入代码的 AST。
## 语义分析
* 变量声明重复
* 检查重复的变量声明;
* 检查方法声明中重复的参数;
* 检查类中重复的字段。
* 变量声明检查位于
* 赋值表达式(例如:a=a+2);
* 二元表达式(例如:a<3);
* 一元表达式(例如:c++);
* 方法调用表达式;
* 检查它们是否为参数或字段(fieldExpressions,例如:myclass.field1)。
* 方法声明检查
* 如果一个方法调用了另一个未声明的方法,将会报告;
* 方法可以在调用它的任何其他函数之后或之前声明,符合 Java 规范。
* 方法参数检查
* 检查参数数量以及它们是否已声明;
* 支持对象函数调用(例如:Person p; p.getName())。
* 方法返回类型检查
* 检查函数返回变量的类型是否与方法声明的类型相同(不检查字面量)。
## 中间表示
### 符号表
* ClassScopes
* 包含类方法的哈希表,键为名称,值为返回类型;
* 包含字段的哈希表;
* className 参数;
* MethodScopes
* 包含每个方法参数的哈希表,键为方法名,值为其类型;
* 包含每个方法局部变量的哈希表,键为方法名,值为其类型;
* 相应的 className、methodName 和 Type 参数;
* LoopScopes
* 包含每个循环局部变量的哈希表,键为循环名,值为其类型;
* 相应的 className 和 methodName 参数;
* 允许在一条语句中进行多个变量声明(例如:String d,e,f,g;),它们都会被添加到符号表中。
### PDG - Program Dependence Graph
为了在 Java 应用程序中开发图,我们决定使用一个 **DirectedGraph** 对象,其边包含比 **DefaultEdge** 类所允许的更多信息。因此,我们创建了一个名为 **RelationshipEdge** 的子类。
为了用所需信息填充图,我们利用了语义分析算法。该算法遍历 AST 以验证分布在各节点中的特定标准。因此,图的填充与语义分析是混合进行的。
#### FDG - Flow Depenence Graph
为了实现 **Flow Dependence Graph**,我们必须记录所有变量的所有访问和定义。为此,我们必须创建所有作用域类(**LoopScope**、**ClassScope** 和 **MethodScope**)的超类,以保证所有 Scope 都有一个包含其自身 Scope 中所有已更改和已访问变量的 **ArrayList**。
```
class Scope {
ArrayList varChanges = new ArrayList<>();
ArrayList varAccesses = new ArrayList<>();
}
```
每次访问变量时,它都会存储在当前 Scope 的数组中,并会对我们当前所在的 Scope 进行搜索。当发现定义时,就会添加一条新边。由于该算法是递归的,当一个 Scope 结束时,该 Scope 就不再位于 **ArrayList** 中。
#### CDG - Control Dependence Graph
**Control Dependence Graph** 按照 AST 已提供的顺序进行填充。如前所述,我们使用递归算法,这使我们能够非常有效地填充图的这一部分,而无需为其实现创建特定的结构。
## 概览
对于语法分析,使用了如上所述的 Java 开源解析器。
使用递归算法处理 AST 的每个节点,逐个分支地执行符号表构建、语义分析和逐节点的图生成。
为了能够显示图,我们需要将 **DirectedGraph** 转换为 **JGraphT**。为此,我们必须重写 **toString** 和 **equals** 函数。这种重写对于将图导出为 _.dot_ 文件也很有用,因为它们不接受图中显示的某些字符。
## 测试套件和测试基础架构
某些包含 Java 代码的测试文件被用于测试程序的语法和语义特性以及图生成功能,未使用自动化测试。
这些测试文件是专门设计用来测试程序的每个特性和细节的,在错误检测和随后的修复中非常有效。
## 任务分配
总的来说,我们认为所有小组成员为完成这项任务付出了同等的努力。
* Francisco Pinho - Parser 解析, TableSymbol, Semantic;
* Francisco Rodrigues - Parser 解析, AST, Graph;
* João Nogueira - AST, Graph, Semantic;
* Marta Lopes - AST, TableSymbol, Semantic.
注意:我们认为 GUI 是由小组所有成员共同开发的。
## 优点
* 我们的应用程序帮助用户理解什么是 **Program Dependence Graph** 以及它应该代表什么。它将不同的边显示为 **Flow Dependencies** 或 **Control dependencies**,这一事实使我们能够理解节点交互之间的区别,并理解 Java 中所有变量、方法和类是如何工作的。它具有通过解析器实现的完整语法和词法分析,以及由我们完成的语义分析,涵盖了该语言的所有主要方面,如果在此分析中发生任何错误,用户将在 GUI 中收到通知。
* 用户友好的 GUI 允许任何用户毫无困难地使用我们的应用程序,无论之前是否使用过该应用程序。
* 内置控制台允许用户快速确认错误是什么以及它们位于何处。
* 总之,**Program Dependence Graph** 在代码分析中有许多用途,特别是在代码优化方面。
## 缺点
Java 语言的语义分析非常复杂,因此错误报告并不十分详尽。在方法参数的符号表方面,所使用的 HashTable 数据结构是一个限制,因为方法调用中的参数类型检查需要一个有序集合,这一点直到开发后期才被发现,而所需的代码重构量对于截止日期来说太大了,因此方法调用参数的类型检查不得不被废弃。
### Class 3MIEIC01 - Group 4
```
Name: Francisco Pinho, Nr: 201303744, Grade: 17, Contribution: 25%
Name: Francisco Rodrigues, Nr: 201305627, Grade: 17, Contribution: 25%
Name: João Nogueira, Nr: 201303882, Grade: 17, Contribution: 25%
Name: Marta Lopes, Nr: 201208067, Grade: 17, Contribution: 25%
```
标签:DOT文件, Graphviz, GUI, JAST, JS文件枚举, Maven, PDG, TLS抓取, 云安全监控, 云资产清单, 代码分析, 代码可视化, 凭证管理, 域名枚举, 域名枚举, 控制流, 教育工具, 数据依赖, 浏览器安全, 漏洞验证, 程序依赖图, 编译器, 语义检查, 语法检查, 软件安全, 逆向工程, 静态分析