Skip to content

Commit

Permalink
jNorm v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
stschott committed Jul 3, 2024
1 parent 853ea59 commit cec4645
Show file tree
Hide file tree
Showing 24 changed files with 2,778 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
output/
input/
normalizer-cli/target/
normalizer-core/target/
target/
out/
.idea/
out2/
42 changes: 42 additions & 0 deletions jnorm-cli/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jnorm</artifactId>
<groupId>jnorm-oss</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>jnorm-cli</artifactId>

<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>jnorm-oss</groupId>
<artifactId>jnorm-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>

</project>
77 changes: 77 additions & 0 deletions jnorm-cli/src/main/java/jnorm/cli/CliHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package jnorm.cli;

import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;

public class CliHandler {
static final String inputDirOpt = "i";
static final String optimizationOpt = "o";
static final String prettyPrintOpt = "p";
static final String renameOpt = "r";
static final String simpleRenameOpt = "r2";
static final String normalizationOpt = "n";
static final String outputDirOpt = "d";
static final String aggressiveOpt = "a";
static final String classFileOpt = "c";
static final String standardizationOpt = "s";

Options options;

public CliHandler() {
options = new Options();

Option filePath =
Option.builder(inputDirOpt)
.argName(inputDirOpt)
.hasArg()
.desc("Input directory")
.required(true)
.build();

Option outputDir =
Option.builder(outputDirOpt)
.argName(outputDirOpt)
.hasArg()
.desc("Output directory")
.required(false)
.build();

Option renaming =
Option.builder(renameOpt)
.argName(renameOpt)
.hasArg()
.desc("Rename each identifier deterministically in order to minimize propagated diffs, receives the hashing window as parameter")
.required(false)
.type(Number.class)
.build();

Option optimization = new Option(optimizationOpt, "Apply Soot internal optimizations");
Option prettyPrint = new Option(prettyPrintOpt, "Apply additional pretty-printing");
Option normalization = new Option(normalizationOpt, "Apply normalizations");
Option simpleRenaming = new Option(simpleRenameOpt, "Strip the numbers from each identifier");
Option aggressive = new Option(aggressiveOpt, "Apply aggressive normalizations");
Option standardization = new Option(standardizationOpt, "Apply local name standardization");
Option classFile = new Option(classFileOpt, "Generate .class files instead of .jimple files");

options.addOption(filePath);
options.addOption(outputDir);
options.addOption(optimization);
options.addOption(prettyPrint);
options.addOption(normalization);
options.addOption(simpleRenaming);
options.addOption(renaming);
options.addOption(aggressive);
options.addOption(standardization);
options.addOption(classFile);
}

public void showHelpMessage(Options options) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("DiffOptimizer", options);
}

public Options getOptions() {
return this.options;
}
}
43 changes: 43 additions & 0 deletions jnorm-cli/src/main/java/jnorm/cli/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package jnorm.cli;

import jnorm.core.Normalizer;
import org.apache.commons.cli.*;

public class Main {

public static void main(String[] args){
CliHandler cli = new CliHandler();
Options options = cli.getOptions();

CommandLineParser parser = new DefaultParser();
CommandLine cmdLine = null;
try {
// Show help message
if (options.hasOption("help") || options.hasOption("h") || args.length < 1) {
cli.showHelpMessage(options);
}
cmdLine = parser.parse(options, args);
} catch (ParseException e) {
System.err.println("Parsing failed. Reason: " + e.getMessage());
System.exit(1);
}

System.out.println("Running jNorm with the following configuration: " + String.join(" ", args));

final String inputDir = cmdLine.getOptionValue(CliHandler.inputDirOpt);
final String outputDir = cmdLine.getOptionValue(CliHandler.outputDirOpt) != null ? cmdLine.getOptionValue(CliHandler.outputDirOpt) : "output";
final boolean applyOptimization = cmdLine.hasOption(CliHandler.optimizationOpt);
final boolean applyPrettyPrint = cmdLine.hasOption(CliHandler.prettyPrintOpt);
final boolean applyNormalization = cmdLine.hasOption(CliHandler.normalizationOpt);
final int renamingWindow = cmdLine.getOptionValue(CliHandler.renameOpt) != null ? Integer.parseInt(cmdLine.getOptionValue(CliHandler.renameOpt)) : -1;
final boolean applySimpleRenaming = cmdLine.hasOption(CliHandler.simpleRenameOpt);
final boolean applyAggressiveNormalization = cmdLine.hasOption(CliHandler.aggressiveOpt);
final boolean applyStandardization = cmdLine.hasOption(CliHandler.standardizationOpt);
final boolean classFileGeneration = cmdLine.hasOption(CliHandler.classFileOpt);

Normalizer normalizer = new Normalizer(inputDir, outputDir, applyOptimization, applyNormalization, applyAggressiveNormalization, applyStandardization, applyPrettyPrint, applySimpleRenaming, renamingWindow);
normalizer.normalize();

// System.out.println(normalizer.getStatistics());
}
}
28 changes: 28 additions & 0 deletions jnorm-core/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jnorm</artifactId>
<groupId>jnorm-oss</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>jnorm-core</artifactId>

<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.soot-oss</groupId>
<artifactId>soot</artifactId>
<version>4.4.1</version>
</dependency>

</dependencies>

</project>
82 changes: 82 additions & 0 deletions jnorm-core/src/main/java/jnorm/core/AggressiveBodyTransformer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package jnorm.core;

import jnorm.core.model.NormalizationStatistics;
import soot.*;
import soot.jimple.AssignStmt;
import soot.jimple.CastExpr;
import soot.options.Options;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AggressiveBodyTransformer extends BodyTransformer {
private NormalizationStatistics statistics;

public AggressiveBodyTransformer(NormalizationStatistics statistics) {
this.statistics = statistics;
}

public void addToSootConfig() {
PackManager.v()
.getPack("jtp")
.add(new Transform("jtp.aggressive", this));
Options.v().set_verbose(true);
soot.options.Options.v().setPhaseOption("jtp", "enabled:" + true);
soot.options.Options.v().setPhaseOption("jtp.aggressive", "enabled:" + true);
}

@Override
protected void internalTransform(Body body, String s, Map<String, String> map) {
try {
removeTypeCasts(body);
} catch (Exception e) {
e.printStackTrace();
}
}

private void removeTypeCasts(Body body) {
UnitPatchingChain unitChain = body.getUnits();
Map<Local, Local> localAliases = new HashMap<>();
List<Unit> unitsToRemove = new ArrayList<>();

for (Unit unit : unitChain) {
if (unit instanceof AssignStmt) {
AssignStmt assignStmt = (AssignStmt) unit;
Value lhs = assignStmt.getLeftOp();
Value rhs = assignStmt.getRightOp();

if (rhs instanceof CastExpr) {
// Unit is a type cast
CastExpr castExpr = (CastExpr) rhs;
Value castOp = castExpr.getOp();

if (lhs instanceof Local && castOp instanceof Local) {
Local oldLocal = (Local) lhs;
Local newLocal = (Local) castOp;
unitsToRemove.add(unit);
localAliases.putIfAbsent(oldLocal, newLocal);
continue;
}
}
}

// Check if unit makes use of a type cast local
List<ValueBox> valueBoxes = unit.getUseAndDefBoxes();
for (ValueBox vb : valueBoxes) {
Value value = vb.getValue();

if (!(value instanceof Local)) continue;
Local currentLocal = (Local) value;

if(!localAliases.containsKey(currentLocal)) continue;
Local newLocal = localAliases.get(currentLocal);

vb.setValue(newLocal);
if (statistics != null) statistics.typecheck += 1;
}
}
unitsToRemove.forEach(unitChain::remove);
}
}
Loading

0 comments on commit cec4645

Please sign in to comment.