use of org.mapleir.ir.cfg.ControlFlowGraph in project maple-ir by LLVM-but-worse.
the class ClassRenamerPass method accept.
/*private String getClassName(String name) {
int i = name.lastIndexOf('/');
if(i == -1) {
return name;
} else {
return name.substring(i + 1, name.length());
}
}*/
@Override
public int accept(AnalysisContext cxt, IPass prev, List<IPass> completed) {
ApplicationClassSource source = cxt.getApplication();
Collection<ClassNode> classes = CollectionUtils.collate(source.iterator());
// int min = RenamingUtil.computeMinimum(classes.size());
int n = RenamingUtil.numeric("aaa");
int step = 27;
for (ClassNode cn : classes) {
String className = RenamingUtil.getClassName(cn.name);
if (!heuristic.shouldRename(className, cn.access)) {
System.out.println("Heuristic bypass " + cn.name);
}
String newName = heuristic.shouldRename(className, cn.access) ? RenamingUtil.createName(n) : className;
String s = RenamingUtil.getPackage(cn.name) + newName;
n += step;
remapping.put(cn.name, s);
// System.out.println(cn.name + " -> " + s);
cn.name = s;
}
for (ClassNode cn : classes) {
cn.superName = remapping.getOrDefault(cn.superName, cn.superName);
{
List<String> ifaces = new ArrayList<>();
for (int i = 0; i < cn.interfaces.size(); i++) {
String s = cn.interfaces.get(i);
ifaces.add(remapping.getOrDefault(s, s));
}
cn.interfaces = ifaces;
}
unsupported(cn.signature);
// unsupported(cn.sourceFile);
// unsupported(cn.sourceDebug);
cn.outerClass = remapping.getOrDefault(cn.outerClass, cn.outerClass);
// unsupported(cn.outerMethod);
// unsupported(cn.outerMethodDesc);
unsupported(cn.visibleAnnotations);
unsupported(cn.invisibleAnnotations);
unsupported(cn.visibleTypeAnnotations);
unsupported(cn.invisibleTypeAnnotations);
unsupported(cn.attrs);
unsupported(cn.innerClasses);
for (FieldNode f : cn.fields) {
unsupported(cn.signature);
{
Type type = Type.getType(f.desc);
String newType = resolveType(type, remapping);
if (newType != null) {
f.desc = newType;
}
}
unsupported(f.visibleAnnotations);
unsupported(f.invisibleAnnotations);
unsupported(f.visibleTypeAnnotations);
unsupported(f.invisibleTypeAnnotations);
unsupported(f.attrs);
}
for (MethodNode m : cn.methods) {
m.desc = resolveMethod(m.desc, remapping);
unsupported(m.signature);
{
List<String> exceptions = new ArrayList<>();
for (int i = 0; i < m.exceptions.size(); i++) {
String s = m.exceptions.get(i);
exceptions.add(remapping.getOrDefault(s, s));
}
m.exceptions = exceptions;
}
unsupported(m.parameters);
unsupported(m.visibleAnnotations);
unsupported(m.invisibleAnnotations);
unsupported(m.visibleTypeAnnotations);
unsupported(m.invisibleTypeAnnotations);
unsupported(m.attrs);
unsupported(m.annotationDefault);
unsupported(m.visibleParameterAnnotations);
unsupported(m.invisibleParameterAnnotations);
for (TryCatchBlockNode tcbn : m.tryCatchBlocks) {
tcbn.type = remapping.getOrDefault(tcbn.type, tcbn.type);
}
ControlFlowGraph cfg = cxt.getIRCache().getFor(m);
for (ExceptionRange<BasicBlock> er : cfg.getRanges()) {
Set<Type> newTypeSet = new HashSet<>();
for (Type t : er.getTypes()) {
// FIXME:
String s = t.getInternalName();
if (remapping.containsKey(s)) {
newTypeSet.add(Type.getType("L" + remapping.get(s) + ";"));
} else {
newTypeSet.add(t);
}
}
er.setTypes(newTypeSet);
}
if (m.localVariables != null) {
m.localVariables.clear();
for (LocalVariableNode lvn : m.localVariables) {
String newDesc = resolveType(Type.getType(lvn.desc), remapping);
if (newDesc != null) {
lvn.desc = newDesc;
}
unsupported(lvn.signature);
}
}
unsupported(m.visibleLocalVariableAnnotations);
unsupported(m.invisibleLocalVariableAnnotations);
for (BasicBlock b : cfg.vertices()) {
for (Stmt stmt : b) {
if (stmt.getOpcode() == Opcode.FIELD_STORE) {
FieldStoreStmt fs = (FieldStoreStmt) stmt;
String owner = fs.getOwner();
fs.setOwner(remapping.getOrDefault(owner, owner));
{
Type type = Type.getType(fs.getDesc());
String newType = resolveType(type, remapping);
if (newType != null) {
fs.setDesc(newType);
}
}
} else if (stmt.getOpcode() == Opcode.RETURN) {
ReturnStmt ret = (ReturnStmt) stmt;
String newType = resolveType(ret.getType(), remapping);
if (newType != null) {
ret.setType(Type.getType(newType));
}
} else if (stmt instanceof AbstractCopyStmt) {
AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
VarExpr v = copy.getVariable();
String newType = resolveType(v.getType(), remapping);
if (newType != null) {
v.setType(Type.getType(newType));
}
}
for (Expr e : stmt.enumerateOnlyChildren()) {
if (e.getOpcode() == Opcode.CAST) {
CastExpr cast = (CastExpr) e;
String newType = resolveType(cast.getType(), remapping);
if (newType != null) {
cast.setType(Type.getType(newType));
}
} else if (e.getOpcode() == Opcode.CATCH) {
CaughtExceptionExpr caught = (CaughtExceptionExpr) e;
String newType = resolveType(caught.getType(), remapping);
if (newType != null) {
caught.setType(Type.getType(newType));
}
} else if (e.getOpcode() == Opcode.DYNAMIC_INVOKE) {
throw new UnsupportedOperationException();
} else if (e.getOpcode() == Opcode.INVOKE) {
InvocationExpr invoke = (InvocationExpr) e;
invoke.setOwner(remapping.getOrDefault(invoke.getOwner(), invoke.getOwner()));
invoke.setDesc(resolveMethod(invoke.getDesc(), remapping));
} else if (e.getOpcode() == Opcode.FIELD_LOAD) {
FieldLoadExpr fl = (FieldLoadExpr) e;
fl.setOwner(remapping.getOrDefault(fl.getOwner(), fl.getOwner()));
String newType = resolveType(fl.getType(), remapping);
if (newType != null) {
fl.setDesc(newType);
}
} else if (e.getOpcode() == Opcode.INIT_OBJ) {
InitialisedObjectExpr init = (InitialisedObjectExpr) e;
init.setOwner(remapping.getOrDefault(init.getOwner(), init.getOwner()));
init.setDesc(resolveMethod(init.getDesc(), remapping));
} else if (e.getOpcode() == Opcode.INSTANCEOF) {
InstanceofExpr inst = (InstanceofExpr) e;
String newType = resolveType(inst.getCheckType(), remapping);
if (newType != null) {
inst.setCheckType(Type.getType(newType));
}
} else if (e.getOpcode() == Opcode.NEW_ARRAY) {
NewArrayExpr na = (NewArrayExpr) e;
String newType = resolveType(na.getType(), remapping);
if (newType != null) {
na.setType(Type.getType(newType));
}
} else if (e.getOpcode() == Opcode.ALLOC_OBJ) {
AllocObjectExpr uninit = (AllocObjectExpr) e;
String newType = resolveType(uninit.getType(), remapping);
if (newType != null) {
uninit.setType(Type.getType(newType));
}
} else if (e.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr v = (VarExpr) e;
String newType = resolveType(v.getType(), remapping);
if (newType != null) {
v.setType(Type.getType(newType));
}
} else if (e.getOpcode() == Opcode.CONST_LOAD) {
ConstantExpr c = (ConstantExpr) e;
Object cst = c.getConstant();
if (cst instanceof Type) {
Type t = (Type) cst;
if (t.getSort() == Type.OBJECT) {
String newType = resolveType(t, remapping);
if (newType != null) {
c.setConstant(Type.getType(newType));
}
} else {
throw new UnsupportedOperationException(String.format("Unsupported ctype %s (%d)", t, t.getSort()));
}
}
}
}
}
}
}
}
source.rebuildTable();
return classes.size();
}
use of org.mapleir.ir.cfg.ControlFlowGraph in project maple-ir by LLVM-but-worse.
the class FieldRenamerPass method accept.
@Override
public int accept(AnalysisContext cxt, IPass prev, List<IPass> completed) {
Map<FieldNode, String> remapped = new HashMap<>();
// int totalFields = 0;
// int i = RenamingUtil.computeMinimum(totalFields);
ApplicationClassSource source = cxt.getApplication();
int i = RenamingUtil.numeric("aaaaa");
for (ClassNode cn : source.iterate()) {
// totalFields += cn.fields.size();
for (FieldNode fn : cn.fields) {
remapped.put(fn, RenamingUtil.createName(i++));
}
}
InvocationResolver resolver = cxt.getInvocationResolver();
for (ClassNode cn : source.iterate()) {
for (MethodNode m : cn.methods) {
ControlFlowGraph cfg = cxt.getIRCache().getFor(m);
for (BasicBlock b : cfg.vertices()) {
for (Stmt stmt : b) {
if (stmt.getOpcode() == Opcode.FIELD_STORE) {
FieldStoreStmt fs = (FieldStoreStmt) stmt;
FieldNode f = resolver.findField(fs.getOwner(), fs.getName(), fs.getDesc(), fs.getInstanceExpression() == null);
if (f != null) {
if (remapped.containsKey(f)) {
fs.setName(remapped.get(f));
} else if (mustMark(source, f.owner.name)) {
System.err.println(" no remap for " + f + ", owner: " + f.owner.name);
}
} else {
if (mustMark(source, fs.getOwner())) {
System.err.println(" can't resolve field(set): " + fs.getOwner() + "." + fs.getName() + " " + fs.getDesc() + ", " + (fs.getInstanceExpression() == null));
}
}
}
for (Expr e : stmt.enumerateOnlyChildren()) {
if (e.getOpcode() == Opcode.FIELD_LOAD) {
FieldLoadExpr fl = (FieldLoadExpr) e;
FieldNode f = resolver.findField(fl.getOwner(), fl.getName(), fl.getDesc(), fl.getInstanceExpression() == null);
if (f != null) {
if (remapped.containsKey(f)) {
fl.setName(remapped.get(f));
} else if (mustMark(source, f.owner.name)) {
System.err.println(" no remap for " + f + ", owner: " + f.owner.name);
}
} else {
if (mustMark(source, fl.getOwner())) {
System.err.println(" can't resolve field(get): " + fl.getOwner() + "." + fl.getName() + " " + fl.getDesc() + ", " + (fl.getInstanceExpression() == null));
}
}
}
}
}
}
}
}
for (Entry<FieldNode, String> e : remapped.entrySet()) {
e.getKey().name = e.getValue();
}
System.out.printf(" Renamed %d fields.%n", remapped.size());
return remapped.size();
}
use of org.mapleir.ir.cfg.ControlFlowGraph in project maple-ir by LLVM-but-worse.
the class Boot2 method main.
public static void main(String[] args) throws Exception {
logging = true;
// Load input jar
// File f = locateRevFile(135);
// Load input jar
// File f = locateRevFile(135);
File f = new File(args[0]);
SingleJarDownloader<ClassNode> dl = new SingleJarDownloader<>(new JarInfo(f));
dl.download();
String appName = f.getName().substring(0, f.getName().length() - 4);
ApplicationClassSource app = new ApplicationClassSource(appName, dl.getJarContents().getClassContents());
//
// ApplicationClassSource app = new ApplicationClassSource("test", ClassHelper.parseClasses(CGExample.class));
// app.addLibraries(new InstalledRuntimeClassSource(app));
File rtjar = new File(System.getProperty("java.home"), "lib/rt.jar");
// File androidjar = new File("res/android.jar");
app.addLibraries(rt(app, rtjar));
IRCache irFactory = new IRCache(ControlFlowGraphBuilder::build);
AnalysisContext cxt = new BasicAnalysisContext.BasicContextBuilder().setApplication(app).setInvocationResolver(new DefaultInvocationResolver(app)).setCache(irFactory).setApplicationContext(new SimpleApplicationContext(app)).setDataFlowAnalysis(new LiveDataFlowAnalysisImpl(irFactory)).build();
for (ClassNode cn : cxt.getApplication().iterate()) {
// continue;
for (MethodNode m : cn.getMethods()) {
// if (!m.name.equals("mapTypes"))
// continue;
cxt.getIRCache().getFor(m);
}
}
System.out.println("Generated " + cxt.getIRCache().size() + " cfgs");
// do passes
PassGroup masterGroup = new PassGroup("MasterController");
for (IPass p : getTransformationPasses()) {
masterGroup.add(p);
}
run(cxt, masterGroup);
for (Entry<MethodNode, ControlFlowGraph> e : cxt.getIRCache().entrySet()) {
MethodNode mn = e.getKey();
ControlFlowGraph cfg = e.getValue();
cfg.verify();
}
for (Entry<MethodNode, ControlFlowGraph> e : cxt.getIRCache().entrySet()) {
MethodNode mn = e.getKey();
// if (!mn.name.equals("openFiles"))
// continue;
ControlFlowGraph cfg = e.getValue();
// System.out.println(cfg);
// CFGUtils.easyDumpCFG(cfg, "pre-destruct");
cfg.verify();
BoissinotDestructor.leaveSSA(cfg);
// CFGUtils.easyDumpCFG(cfg, "pre-reaalloc");
LocalsReallocator.realloc(cfg);
// CFGUtils.easyDumpCFG(cfg, "post-reaalloc");
// System.out.println(cfg);
cfg.verify();
// System.out.println("Rewriting " + mn.name);
(new ControlFlowGraphDumper(cfg, mn)).dump();
// System.out.println(InsnListUtils.insnListToString(mn.instructions));
}
dumpJar(app, dl, masterGroup, "out/rewritten.jar");
}
use of org.mapleir.ir.cfg.ControlFlowGraph in project maple-ir by LLVM-but-worse.
the class CleanBoot method main.
public static void main(String[] args) throws Exception {
ClassNode cn = ClassHelper.create(new FileInputStream(new File("MemeIn.class")));
IRCache irFactory = new IRCache();
for (MethodNode mn : cn.getMethods()) {
// if (!mn.getName().equals("merge"))
// continue;
// if (mn.getName().equals("merge"))
// System.out.println(InsnListUtils.insnListToString(mn.node.instructions));
ControlFlowGraph cfg = irFactory.getNonNull(mn);
// if (mn.getName().equals("merge"))
// System.out.println(cfg);
// if (mn.getName().equals("merge"))
// CFGUtils.easyDumpCFG(cfg, "pre-destruct");
cfg.verify();
BoissinotDestructor.leaveSSA(cfg);
// if (mn.getName().equals("merge"))
// CFGUtils.easyDumpCFG(cfg, "pre-reaalloc");
LocalsReallocator.realloc(cfg);
// if (mn.getName().equals("merge"))
// CFGUtils.easyDumpCFG(cfg, "post-reaalloc");
// System.out.println(cfg);
cfg.verify();
System.out.println("Rewriting " + mn.getName());
(new ControlFlowGraphDumper(cfg, mn)).dump();
System.out.println(InsnListUtils.insnListToString(mn.node.instructions));
}
new FileOutputStream(new File("Meme.class")).write(ClassHelper.toByteArray(cn, ClassWriter.COMPUTE_FRAMES));
}
use of org.mapleir.ir.cfg.ControlFlowGraph in project maple-ir by LLVM-but-worse.
the class CompilationDemo method main.
public static void main(String[] args) throws IOException {
// File f = new File("res/Bad.jar");
// SingleJarDownloader<ClassNode> dl = new SingleJarDownloader<>(new JarInfo(f));
// dl.download();
// for (ClassNode cn : dl.getJarContents().getClassContents().namedMap().values()) {
String className = "HelloWorld";
JavaClassCompiler compiler = new JavaClassCompiler();
byte[] bytes = compiler.compile(className, "public class " + className + " { public static void main(String[] args) { System.out.println(\"Hello world\"); } }");
if (bytes == null) {
System.out.println("Compilation failed!");
} else {
ASMFactory cnFactory = new DefaultASMFactory();
ClassNode cn = cnFactory.create(bytes, className);
for (MethodNode mn : cn.getMethods()) {
System.out.println(mn.getJavaDesc());
ControlFlowGraphBuilder builder = new ControlFlowGraphBuilder(mn, false);
ControlFlowGraph cfg = builder.buildImpl();
System.out.println(cfg);
BoissinotDestructor.leaveSSA(cfg);
LocalsReallocator.realloc(cfg);
System.out.println(cfg);
}
}
}
Aggregations