提高Android代码的安全性_自定义类加载器

大熊 2013-12-06 11:15 阅读:6476


自定义了类加载器,代码如下:
public class TestClassLoader extends ClassLoader {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            String code = "yv66vgAAADIAIgcAAgEABFRlc3QHAAQBABBqYXZhL2xhbmcvT2JqZWN0AQAGPGluaXQ+AQADKClWAQAEQ29kZQoAAwAJDAAFAAYBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAGTFRlc3Q7AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYJABEAEwcAEgEAEGphdmEvbGFuZy9TeXN0ZW0MABQAFQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwgAFwEABHRlc3QKABkAGwcAGgEAE2phdmEvaW8vUHJpbnRTdHJlYW0MABwAHQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAClNvdXJjZUZpbGUBAAlUZXN0LmphdmEAIQABAAMAAAAAAAIAAQAFAAYAAQAHAAAALwABAAEAAAAFKrcACLEAAAACAAoAAAAGAAEAAAABAAsAAAAMAAEAAAAFAAwADQAAAAkADgAPAAEABwAAADMAAgABAAAACbIAEBIWtgAYsQAAAAIACgAAAAYAAQAAAAEACwAAAAwAAQAAAAkAHgAfAAAAAQAgAAAAAgAh";
            baos.write(Base64.decode(code, Base64.DEFAULT));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return super.defineClass(baos.toByteArray(), 0,
            baos.toByteArray().length);
    }
    public static void main(String[] args) throws Exception {
        ClassLoader cl = new TestClassLoader();
        Class clazz = cl.loadClass("Test");
        Method method = clazz.getMethod("main", new Class[] { String[].class });
        method.invoke(null, new Object[] { new String[] {} });
    }
}

在JAVA可以正常运行,在android却报如下错误:

研究表明在android中是不允许自定义类加载器的。
虽然不可以自定义类加载器,但是可以实现动态加载字节码的功能。
File file = new File(Environment.getExternalStorageDirectory()
                        + File.separator + "test.jar");
                ClassLoader cl = new DexClassLoader(file.getAbsolutePath(),
                        Environment.getExternalStorageDirectory().toString(),
                        null, getClassLoader());
                try {
                    Class clazz = cl.loadClass("com.dynamic.DynamicTest");
                    Object object = clazz.newInstance();
                    Method method = clazz.getMethod("helloWorld",
                        new Class[] {});
                    String str = (String) method
                            .invoke(object, new Object[] {});
                    Toast.makeText(MainActivity.this, str, Toast.LENGTH_LONG)
                            .show();
                } catch (Exception e) {
                    e.printStackTrace();
                }

其中test.jar的内容为用dx工具将class字节码,打包成dex字节码的jar文件。用这个动态加载字节码的类加载器,我们可以做很多动态功能的实现。例如可以从网络上下载某些功能的jar文件,动态调用jar文件中的方法。

0条评论

登陆后可评论