grooidshell-example icon indicating copy to clipboard operation
grooidshell-example copied to clipboard

Where to find the source code of grooid.jar

Open alexyuyxj opened this issue 9 years ago • 2 comments

i am trying to fix this issue(GroovyClassLoader broken in Android API 24), can you tell me how to find the source code of grooid.jar

alexyuyxj avatar Nov 01 '16 03:11 alexyuyxj

I think may be I have fixed this bug, and here is my solution: override method "createClass" of class "ClassCollector" in "GrooidClassLoader", then catch its "byte[] code" argument. This is the compiled groovy class which we are going to transform into dex file.

My english is bad, so I am going to paste some java codes, which may be much clearer.

firstly, groovy class:

class Test {
    static main(args) {
        println 111111111
    }
}

secondly, override ClassCollector.createClass:

return new ClassCollector(loader, unit, su) {
    protected Class createClass(byte[] code, ClassNode classNode) {
        try {
            FileOutputStream fos = new FileOutputStream("/sdcard/" + classNode + ".class");
            fos.write(code);
            fos.flush();
            fos.close();
        } catch (Throwable t) {}
        return super.createClass(code, classNode);
    }
    …………
};

and then reload the byte array into dex:

private HashMap<String, byte[]> readAssets(String dir) throws Throwable {
    HashMap<String, byte[]> classes = new HashMap<String, byte[]>();
    String path = "Test.class";
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    InputStream is = getAssets().open(path);
    byte[] buf = new byte[1024];
    int len = is.read(buf);
    while (len > 0) {
        baos.write(buf, 0, len);
        len = is.read(buf);
    }
    is.close();
    baos.close();
    classes.put(path, baos.toByteArray());
}
ClassDefItem item = CfTranslator.translate(classPath, classBytes, cfOptions, dexOptions);
dex.add(item);

finally, call "Test.main()" by reflection:

try {
    Class<?> Test = Class.forName("Test");
    Method mth = Test.getMethod("main", String[].class);
    mth.invoke(null, Array.newInstance(String.class, 0));
} catch (Throwable t) {
    t.printStackTrace();
}

alexyuyxj avatar Nov 10 '16 05:11 alexyuyxj

Are you sure this method really works? I have tested that the createClass method(in the ClassCollector) was never called if it crashed with this. BUG! exception in phase 'semantic analysis' in source unit 'script14710549832242032452851.groovy' throw with null exception

BennyKok avatar Dec 26 '16 09:12 BennyKok