首页
社区
课程
招聘
1
[分享][下载][讨论][推荐][原创]安卓dex不落地加载实现方法
发表于: 2025-3-23 19:09 2381

[分享][下载][讨论][推荐][原创]安卓dex不落地加载实现方法

2025-3-23 19:09
2381

此代码网络上可能是独一份
更多资源:https://bbs.kanxue.com/homepage-854079.htm

工具 和 样例 下载位置最低部

# 不多说直接上代码:
此方法放在Application的attachBaseContext()中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private void test() {
        try {
            ClassLoader classLoader = getBaseContext().getClassLoader();
            ByteBuffer[] byteBuffer = {readFileByBB()};//dex文件列表
             
            Class<?> forName = Class.forName("dalvik.system.InMemoryDexClassLoader");
            Constructor<?> declaredConstructor = forName.getDeclaredConstructor(byteBuffer.getClass(),ClassLoader.class);//所有构造函数,包括公共的、私有的和受保护的构造函数
            Object newInstance = declaredConstructor.newInstance(byteBuffer,classLoader);//InMemoryDexClassLoader
             
            Class<?> superclass = forName.getSuperclass();
            Field field = forName.getSuperclass().getDeclaredField("pathList");
            field.setAccessible(true);//可读取
            Object pathListObj = field.get(newInstance);
            Class<?> DexPathList = Class.forName("dalvik.system.DexPathList");
            ArrayList<IOException> arrayList = new ArrayList<>();
            Method method = DexPathList.getMethod("makeInMemoryDexElements", byteBuffer.getClass(),List.class);
            Object invoke = method.invoke(null,byteBuffer, arrayList);//DexPathList$Element
            int length = Array.getLength(invoke);
            Object[] list = new Object[length];
            for (int i = 0; i < length; i++) {
                Object object = Array.get(invoke, 0);//DexPathList$Element[]
                list[i] = object;
            }
             
            make_dex_elements(classLoader,list);
             
            Class<?> loadClass = classLoader.loadClass("com.TestApp");
            System.out.println("----"+loadClass.getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

关键代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private void make_dex_elements(ClassLoader classLoader, Object[] list) {
        Class<?> BaseDexClassLoader = classLoader.getClass().getSuperclass();
        try {
            Field field = BaseDexClassLoader.getDeclaredField("pathList");//BaseDexClassLoader.pathList
            field.setAccessible(true);
            Object DexPathList = field.get(classLoader);//DexPathList
            Class<? extends Object> class1 = DexPathList.getClass();//dalvik.system.DexPathList
             
            Field dexElements = class1.getDeclaredField("dexElements");
            dexElements.setAccessible(true);
            Object object = dexElements.get(DexPathList);//DexPathList$Element[] dexElements 属性值
             
            int length = Array.getLength(object);
            Class<?> forName = Class.forName("dalvik.system.DexPathList$Element");
             
            Object[] mergedArray = (Object[]) Array.newInstance(forName, length+list.length);
             
            System.arraycopy(list, 0, mergedArray, 0, list.length);
             
            // 将第二个数组的元素复制到新数组中
            System.arraycopy(object, 0, mergedArray, list.length, length);
             
            dexElements.set(DexPathList,mergedArray);
             
            System.out.println("----");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("----");
         
    }

在onCreate中调用以下方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public void replaceApplicationContext(Application application) {
        Log.w("NDK_JIAGU", "replaceApplicationContext");
        try {
            // 先获取到ContextImpl对象
            Context contextImpl = application.getBaseContext();
 
            // 替换ContextImpl的代理Application
            Reflect.invokeMethod(contextImpl.getClass(), contextImpl,
                    new Object[]{sDelegateApplication}, "setOuterContext",
                    Context.class);
 
            // 替换ActivityThread的代理Application
            Object mMainThread = Reflect.getFieldValue(contextImpl.getClass(), contextImpl,
                    "mMainThread");
            Reflect.setFieldValue("android.app.ActivityThread", mMainThread, "mInitialApplication",
                    sDelegateApplication);
            // 替换ActivityThread的mAllApplications
            ArrayList<Application> mAllApplications =
                    (ArrayList<Application>) Reflect.getFieldValue("android.app.ActivityThread",
                            mMainThread, "mAllApplications");
            mAllApplications.add(sDelegateApplication);
            mAllApplications.remove(application);
 
            // 替换LoadedApk的代理Application
            Object loadedApk = Reflect.getFieldValue(contextImpl.getClass(), contextImpl,
                    "mPackageInfo");
            Reflect.setFieldValue("android.app.LoadedApk", loadedApk, "mApplication",
                    sDelegateApplication);
 
            // 替换LoadedApk中的mApplicationInfo中name
            ApplicationInfo applicationInfo =
                    (ApplicationInfo) Reflect.getFieldValue("android.app.LoadedApk",
                            loadedApk
                            , "mApplicationInfo");
            applicationInfo.className = sDelegateApplication.getClass().getName();
            sDelegateApplication.onCreate();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

以代码复制即可完成不落地加载
最后再说一句这不重要,重要的是如何反逆向,使用java加载dex的壳,毫无抵抗力,不如使用C/C++完成以上操作

百度网盘
https://pan.baidu.com/s/1_aXBjbU7pj2FnXXRmuXDWw
提取码: gngf

蓝奏云:
app:
https://wwsq.lanzoue.com/b021yzbhif 密码:hvgg
3.3.1
https://wwsq.lanzoue.com/b021yzbhjg 密码:728i
3.3.5
https://wwsq.lanzoue.com/b021yzbhli 密码:fcu2

加密工具使用方法:https://bbs.kanxue.com/thread-276989.htm
3.3.1:https://bbs.kanxue.com/thread-276989.htm
3.3.5:版本已实现不落地加载,和加解密速度优化


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2025-3-30 15:45 被富到流油^-^编辑 ,原因: 补充
上传的附件:
收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
你瞒我瞒
这个讨论对我很有帮助,谢谢!
2025-3-24 09:20
最新回复 (2)
雪    币: 839
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
根本学不过来
2025-3-23 19:24
0
雪    币: 506
活跃值: (3358)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
mb_elqwyvnm 根本学不过来
复制代码,就可以
2025-3-23 19:30
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册