首页
社区
课程
招聘
[原创]APK反破解之四:Android代码动态加载技术
发表于: 2011-11-2 19:53 33914

[原创]APK反破解之四:Android代码动态加载技术

2011-11-2 19:53
33914

转载请注明出处:http://www.blogjava.net/zh-weir/archive/2011/10/29/362294.html  

Android类动态加载技术

    Android应用开发在一般情况下,常规的开发方式和代码架构就能满足我们的普通需求。但是有些特殊问题,常常引发我们进一步的沉思。我们从沉思中产生顿悟,从而产生新的技术形式。

    如何开发一个可以自定义控件的Android应用?就像eclipse一样,可以动态加载插件;如何让Android应用执行服务器上的不可预知的代码?如何对Android应用加密,而只在执行时自解密,从而防止被破解?……

    熟悉Java技术的朋友,可能意识到,我们需要使用类加载器灵活的加载执行的类。这在Java里已经算是一项比较成熟的技术了,但是在Android中,我们大多数人都还非常陌生。

类加载机制      

    Dalvik虚拟机如同其他Java虚拟机一样,在运行程序时首先需要将对应的类加载到内存中。而在Java标准的虚拟机中,类加载可以从class文件中读取,也可以是其他形式的二进制流。因此,我们常常利用这一点,在程序运行时手动加载Class,从而达到代码动态加载执行的目的。

    然而Dalvik虚拟机毕竟不算是标准的Java虚拟机,因此在类加载机制上,它们有相同的地方,也有不同之处。我们必须区别对待。

    例如,在使用标准Java虚拟机时,我们经常自定义继承自ClassLoader的类加载器。然后通过defineClass方法来从一个二进制流中加载Class。然而,这在Android里是行不通的,大家就没必要走弯路了。参看源码我们知道,Android中ClassLoader的defineClass方法具体是调用VMClassLoader的defineClass本地静态方法。而这个本地方法除了抛出一个“UnsupportedOperationException”之外,什么都没做,甚至连返回值都为空。

static void Dalvik_java_lang_VMClassLoader_defineClass(const u4* args, JValue* pResult)
{

    Object* loader = (Object*) args[0];
    StringObject* nameObj = (StringObject*) args[1];
    const u1* data = (const u1*) args[2];
    int offset = args[3];
    int len = args[4];

    Object* pd = (Object*) args[5];
    char* name = NULL;

    name = dvmCreateCstrFromString(nameObj);
    LOGE("ERROR: defineClass(%p, %s, %p, %d, %d, %p)\n", loader, name, data, offset, len, pd);

    dvmThrowException("Ljava/lang/UnsupportedOperationException;", "can't load this type of class file");

    free(name);
    RETURN_VOID();
}
/**//* --this doesn't work in current version of Dalvik--

    if (data != null) {

        System.out.println("--- Found class " + name + " in zip[" + i + "] '" + mZips[i].getName() + "'");

        int dotIndex = name.lastIndexOf('.');
        if (dotIndex != -1) {

            String packageName = name.substring(0, dotIndex);

            synchronized (this) {

                Package packageObj = getPackage(packageName);

                if (packageObj == null) {
                    definePackage(packageName, null, null, null, null, null, null, null);
                }
            }
        }

        return defineClass(name, data, 0, data.length);
    }
*/

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 6
支持
分享
最新回复 (10)
雪    币: 76
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
先占个座 ,手机的很有前途
2011-11-8 11:38
0
雪    币: 220
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我也在用Andoird的系统,抢个沙发慢慢看
2011-11-9 01:39
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
关于classloader,建议看看“dynamic class loading in the java virtual machine”和“The.Java.Programming.Language,4th.Edition"的16.13章节。
2011-11-13 00:27
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
很不错。有时间再详细看看。。
2012-11-25 23:32
0
雪    币: 156
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
给个示例就好了。呵呵
2013-1-21 11:01
0
雪    币: 13
活跃值: (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
不是很明白,既然有最后解密的过程,自然就可以找到解密的算法和密钥,再怎么动态加载类又有什么用呢?
2013-1-23 14:46
0
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
mark一下,免得以后忘了
2016-1-12 14:28
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
正好用到。感谢
2016-1-14 01:01
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
先收藏了,用到时再来看
2016-1-14 08:13
0
雪    币: 211
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
支持支持。
2016-1-14 11:16
0
游客
登录 | 注册 方可回帖
返回
//