吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1192|回复: 0
收起左侧

[Android 求助] 第一二代壳的编写中资源加载的问题

[复制链接]
S1mba 发表于 2020-10-18 10:44
25吾爱币
最近想学习写壳,在网上看了很多教程,但是他们的demo都没有提到资源加载的问题。我的demo运行后会出现找不到layout的问题。报错如下

报错

报错

然后我的加载资源代码如下:

资源加载

资源加载

资源在这里替换:

资源替换

资源替换

实际运行中看log发现原APK确实用的是我加载的资源,但就是无法找到layout

log

log

如图TAG是提示的是脱壳Application的log
TAG是demo的是原APK的log
可以看到资源应该已经被替换成功了啊
代码:
[Java] 纯文本查看 复制代码
public class ProxyApplication extends Application {

    public String apkName;
    public String dexPath;
    public String libPath;

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        Log.i("提示:", "进入attachBaseContext方法!");
        try {
//            File dex = this.getDir("payload_odex", MODE_PRIVATE);
//            File lib = this.getDir("payload_lib", MODE_PRIVATE);
//            dexPath = dex.getAbsolutePath();
//            libPath = lib.getAbsolutePath();
//            apkName = dex.getAbsolutePath() + "/shell.apk";
//            File dexFile = new File(apkName);
//            if (!dexFile.exists()) {
//                dexFile.createNewFile();
//                byte[] dexdata = this.readDexFileFromApk();
//
//                // 分离出解壳后的apk文件已用于动态加载
//                this.splitPayLoadFromDex(dexdata);
//            }

            String filesDir = this.getCacheDir().getAbsolutePath();
            Log.i("提示:", filesDir);
            apkName = filesDir + File.separator + "srcapk.apk";
//            String dexPath = filesDir + File.separator + "srcapk.dex";

            Object activityThreadObject = RefinvokeMethod.invokeStaticMethod("android.app.ActivityThread", "currentActivityThread", new Class[]{}, new Object[]{});
            String shellPackageName = this.getPackageName();
            ArrayMap mPackages = (ArrayMap) RefinvokeMethod.getField("android.app.ActivityThread", activityThreadObject, "mPackages");
            WeakReference wr = (WeakReference) mPackages.get(shellPackageName);
            ClassLoader oldCl = (ClassLoader) RefinvokeMethod.getField("android.app.LoadedApk", wr.get(), "mClassLoader");
            DexClassLoader dcl = new DexClassLoader(apkName, filesDir, null, oldCl);
            RefinvokeMethod.setField("android.app.LoadedApk", "mClassLoader", wr.get(), dcl);
            Log.i("提示:", "类加载已被替换成自定义的Dex加载器!");
            try {
                Object objectMain = dcl.loadClass("com.example.forceversion.MainActivity");
                Log.i("提示:", "MainActivity.java类加载完毕!");
            } catch (Exception e) {
            }
        } catch (Exception e) {
            Log.i("提示:", "load apk classloader error:" + Log.getStackTraceString(e));
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("提示:", "进入onCreate方法!");
        Log.i("提示:", "basecontext:" + this.getBaseContext());
        Log.i("提示:", "context:" + this.getApplicationContext());
        Log.i("提示:", "资源0:" + this.getApplicationContext().getResources());
        loadResources(apkName);
        String applicationName = "";
        ApplicationInfo ai = null;
        try {
            ai = this.getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
            applicationName = ai.metaData.getString("ApplicationName");
            Log.i("提示:", "成功获取到apk的application名称" + applicationName);
        } catch (Exception e) {
        }

        Object ActivityThreadObj = RefinvokeMethod.invokeStaticMethod("android.app.ActivityThread", "currentActivityThread", new Class[]{}, new Object[]{});
        Object mBoundApplication = RefinvokeMethod.getField("android.app.ActivityThread", ActivityThreadObj, "mBoundApplication");
        Object info = RefinvokeMethod.getField("android.app.ActivityThread$AppBindData", mBoundApplication, "info");

        RefinvokeMethod.setField("android.app.LoadedApk", "mApplication", info, null);
        Object minitApplication = RefinvokeMethod.getField("android.app.ActivityThread", ActivityThreadObj, "mInitialApplication");
        ArrayList<Application> mAllApplications = (ArrayList<Application>) RefinvokeMethod.getField("android.app.ActivityThread", ActivityThreadObj, "mAllApplications");
        mAllApplications.remove(minitApplication);
        ApplicationInfo mApplicationInfo = (ApplicationInfo) RefinvokeMethod.getField("android.app.LoadedApk", info, "mApplicationInfo");
        ApplicationInfo appInfo = (ApplicationInfo) RefinvokeMethod.getField("android.app.ActivityThread$AppBindData", mBoundApplication, "appInfo");

        mApplicationInfo.className = applicationName;
        appInfo.className = applicationName;

        Application app = (Application) RefinvokeMethod.invokeMethod("android.app.LoadedApk", "makeApplication", info, new Class[]{boolean.class, Instrumentation.class}, new Object[]{false, null});
        Context mBase = (Context) RefinvokeMethod.invokeMethod("android.app.Application","getBaseContext",app,new Class[]{}, new Object[]{});
        RefinvokeMethod.setField("android.app.ContextImpl","mResources",mBase,mResources);

        Log.i("提示:", "app: " + app);
        RefinvokeMethod.setField("android.app.ActivityThread", "mInitialApplication", ActivityThreadObj, app);

        ArrayMap mProviderMap = (ArrayMap) RefinvokeMethod.getField("android.app.ActivityThread", ActivityThreadObj, "mProviderMap");
        Iterator it = mProviderMap.values().iterator();

        while (it.hasNext()) {
            Object mProviderClientRecord = it.next();
            Object mLocalProvider = RefinvokeMethod.getField("android.app.ActivityThread$ProviderClientRecord", mProviderClientRecord, "mLocalProvider");
            RefinvokeMethod.setField("android.content.ContentProvider", "mContext", mLocalProvider, app);
        }

        Log.i("提示:", "反射application完成,准备拉起源apk!");


        Log.i("提示:", "context:" + this.getApplicationContext());
        Log.i("提示:", "资源1:" + this.getApplicationContext().getResources());
        app.onCreate();
        Log.i("提示:", "源apk成功拉起!脱壳完毕!");

    }

    protected AssetManager mAssetManager;
    protected Resources mResources;


    protected void loadResources(String dexPath) {
        try {
            Class cls = Class.forName("android.content.res.AssetManager");
            AssetManager assetManager = (AssetManager) cls.getConstructor().newInstance();
            Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
            addAssetPath.invoke(assetManager, dexPath);
            mAssetManager = assetManager;
            mResources = new Resources(assetManager, super.getResources().getDisplayMetrics(),
                    super.getResources().getConfiguration());

        } catch (Exception e) {
            Log.i("提示:", "loadResource error:" + Log.getStackTraceString(e));
            e.printStackTrace();
        }

        Log.i("提示:", "资源加载完毕!" + mResources);
    }
}


没有将APK写进dex是为了方便

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止回复与主题无关非技术内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-3-29 22:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表