Skip to content

Commit

Permalink
Merge pull request #101 from marc1006/openDexFile
Browse files Browse the repository at this point in the history
Implement method to load classes at runtime
  • Loading branch information
oleavr committed Aug 30, 2015
2 parents 0897ef6 + 4795c5b commit ba1a8ce
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions bindings/gumjs/gumscript-runtime-java.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@
return classFactory.use(className);
};

this.openClassFile = function (filePath) {
return classFactory.openClassFile(filePath);
};

this.choose = function (className, callbacks) {
assertCalledInJavaPerformCallback();
return classFactory.choose(className, callbacks);
Expand Down Expand Up @@ -305,6 +309,7 @@
let patchedClasses = {};
let patchedMethods = new Set();
let loader = null;
const FILE_PATH = Symbol('FILE_PATH');
const PENDING_CALLS = Symbol('PENDING_CALLS');

function initialize() {
Expand Down Expand Up @@ -371,6 +376,59 @@
return new C(C.__handle__, null);
};

function DexFile(filePath) {
this[FILE_PATH] = filePath;
}

DexFile.prototype = {
load() {
if (loader === null) {
throw new Error("Not allowed outside Java.perform() callback");
}
const File = factory.use("java.io.File");
const f = File.$new(this[FILE_PATH]);
if (!f.exists()) {
throw new Error("File isn't available");
}

const currentApplication = factory.use("android.app.ActivityThread").currentApplication();
const optimizedDexOutputPath = currentApplication.getDir("outdex", 0);
const DexClassLoader = factory.use("dalvik.system.DexClassLoader");

let classLoader = null;
if (loader !== null) {
classLoader = DexClassLoader.$new(f.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(), null, loader);
} else {
classLoader = DexClassLoader.$new(f.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(), null, currentApplication.getClassLoader());
}

loader = classLoader;
},
getClassNames() {
if (loader === null) {
throw new Error("Not allowed outside Java.perform() callback");
}
const classNames = [];
const File = factory.use("java.io.File");
const DexFile = factory.use("dalvik.system.DexFile");
const currentApplication = factory.use("android.app.ActivityThread").currentApplication();
const dx = DexFile.loadDex(this[FILE_PATH], File.createTempFile("opt", "dex",
currentApplication.getCacheDir()).getPath(), 0);

const enumeratorClassNames = dx.entries();
while (enumeratorClassNames.hasMoreElements()) {
classNames.push(enumeratorClassNames.nextElement());
}
return classNames;
}
};

this.openClassFile = function (filePath) {
return new DexFile(filePath);
};

this.choose = function (className, callbacks) {
if (api.flavor !== 'dalvik')
throw new Error("choose() is only supported on Dalvik for now");
Expand Down

0 comments on commit ba1a8ce

Please sign in to comment.