Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

atlas hack assert failed? #4

Closed
ghost opened this issue Nov 5, 2015 · 5 comments
Closed

atlas hack assert failed? #4

ghost opened this issue Nov 5, 2015 · 5 comments

Comments

@ghost
Copy link

ghost commented Nov 5, 2015

https://github.com/CtripMobile/DynamicAPK/blob/master/bundle/src/ctrip/android/bundle/hack/SysHacks.java
'''
package ctrip.android.bundle.hack;

import android.app.Application;
import android.app.Instrumentation;
import android.app.Service;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.Build;
import android.view.ContextThemeWrapper;

import java.util.ArrayList;
import java.util.Map;

import ctrip.android.bundle.hack.Hack.HackedClass;
import ctrip.android.bundle.hack.Hack.HackedField;
import ctrip.android.bundle.hack.Hack.HackedMethod;
import ctrip.android.bundle.log.Logger;
import ctrip.android.bundle.log.LoggerFactory;
import dalvik.system.DexClassLoader;

/**

  • Created by yb.wang on 14/12/31.

  • Hack 系统的功能:包括类加载机制,资源加载,Context等
    */
    public class SysHacks extends Hack.HackDeclaration implements Hack.AssertionFailureHandler {
    public static HackedClass ActivityThread;
    public static HackedMethod ActivityThread_currentActivityThread;
    public static HackedField<Object, ArrayList<android.app.Application>> ActivityThread_mAllApplications;
    public static HackedField<Object, Instrumentation> ActivityThread_mInstrumentation;
    public static HackedField<Object, Map<String, Object>> ActivityThread_mPackages;
    public static HackedField<Object, Object> ActivityThread_sPackageManager;
    public static HackedClass Application;
    public static HackedMethod Application_attach;
    public static HackedClass<android.content.res.AssetManager> AssetManager;
    public static HackedMethod AssetManager_addAssetPath;
    public static HackedClass ClassLoader;
    public static HackedMethod ClassLoader_findLibrary;
    public static HackedClass ContextImpl;
    public static HackedField<Object, android.content.res.Resources> ContextImpl_mResources;
    public static HackedField<Object, android.content.res.Resources.Theme> ContextImpl_mTheme;
    public static HackedClass<android.view.ContextThemeWrapper> ContextThemeWrapper;
    public static HackedField<ContextThemeWrapper, Context> ContextThemeWrapper_mBase;
    public static HackedField<ContextThemeWrapper, Resources> ContextThemeWrapper_mResources;
    public static HackedField<ContextThemeWrapper, android.content.res.Resources.Theme> ContextThemeWrapper_mTheme;
    public static HackedClass<android.content.ContextWrapper> ContextWrapper;
    public static HackedField<ContextWrapper, Context> ContextWrapper_mBase;
    public static HackedClass<dalvik.system.DexClassLoader> DexClassLoader;
    public static HackedMethod DexClassLoader_findClass;
    public static ArrayList GeneratePackageInfoList;
    public static ArrayList GetPackageInfoList;
    public static HackedClass IPackageManager;
    public static HackedClass LexFile;
    public static HackedMethod LexFile_close;
    public static HackedMethod LexFile_loadClass;
    public static HackedMethod LexFile_loadLex;
    public static HackedClass LoadedApk;
    public static HackedField<Object, String> LoadedApk_mAppDir;
    public static HackedField<Object, Application> LoadedApk_mApplication;
    public static HackedField<Object, ClassLoader> LoadedApk_mBaseClassLoader;
    public static HackedField<Object, ClassLoader> LoadedApk_mClassLoader;
    public static HackedField<Object, String> LoadedApk_mResDir;
    public static HackedField<Object, Resources> LoadedApk_mResources;
    public static HackedClass Resources;
    public static HackedField<Resources, Object> Resources_mAssets;
    public static HackedClass<android.app.Service> Service;
    public static HackedClass Instrumentation;

    public static boolean sIsIgnoreFailure;
    public static boolean sIsReflectAvailable;
    public static boolean sIsReflectChecked;
    private AssertionArrayException mExceptionArray;
    static final Logger log;

    public SysHacks() {
    this.mExceptionArray = null;
    }

    static {
    log = LoggerFactory.getLogcatLogger("SysHacks");
    sIsReflectAvailable = false;
    sIsReflectChecked = false;
    sIsIgnoreFailure = false;
    GeneratePackageInfoList = new ArrayList();
    GetPackageInfoList = new ArrayList();
    }

    public static boolean defineAndVerify() throws AssertionArrayException {
    if (sIsReflectChecked) {
    return sIsReflectAvailable;
    }
    SysHacks atlasHacks = new SysHacks();
    try {
    Hack.setAssertionFailureHandler(atlasHacks);
    if (Build.VERSION.SDK_INT == 11) {
    atlasHacks.onAssertionFailure(new HackAssertionException("Hack Assertion Failed: Android OS Version 11"));
    }
    allClasses();
    allConstructors();
    allFields();
    allMethods();
    if (atlasHacks.mExceptionArray != null) {
    sIsReflectAvailable = false;
    throw atlasHacks.mExceptionArray;
    }
    sIsReflectAvailable = true;
    return sIsReflectAvailable;
    } catch (Throwable e) {
    sIsReflectAvailable = false;
    log.log("HackAssertionException", Logger.LogLevel.ERROR, e);
    throw new AssertionArrayException("defineAndVerify HackAssertionException");
    } finally {
    Hack.setAssertionFailureHandler(null);
    sIsReflectChecked = true;
    }
    }

    public static void allClasses() throws HackAssertionException {
    if (Build.VERSION.SDK_INT <= 8) {
    LoadedApk = Hack.into("android.app.ActivityThread$PackageInfo");
    } else {
    LoadedApk = Hack.into("android.app.LoadedApk");
    }
    ActivityThread = Hack.into("android.app.ActivityThread");
    Resources = Hack.into(Resources.class);
    Application = Hack.into(Application.class);
    AssetManager = Hack.into(AssetManager.class);
    IPackageManager = Hack.into("android.content.pm.IPackageManager");
    Service = Hack.into(Service.class);
    ContextImpl = Hack.into("android.app.ContextImpl");
    ContextThemeWrapper = Hack.into(ContextThemeWrapper.class);
    ContextWrapper = Hack.into("android.content.ContextWrapper");
    sIsIgnoreFailure = true;
    ClassLoader = Hack.into(ClassLoader.class);
    DexClassLoader = Hack.into(DexClassLoader.class);
    LexFile = Hack.into("dalvik.system.LexFile");
    Instrumentation = Hack.into("android.app.Instrumentation");
    sIsIgnoreFailure = false;
    }

    public static void allFields() throws HackAssertionException {

    ActivityThread_mInstrumentation = ActivityThread.field("mInstrumentation");
    ActivityThread_mInstrumentation.ofType(Instrumentation.class);
    ActivityThread_mAllApplications = ActivityThread.field("mAllApplications");
    ActivityThread_mAllApplications.ofGenericType(ArrayList.class);
    ActivityThread_mPackages = ActivityThread.field("mPackages");
    ActivityThread_mPackages.ofGenericType(Map.class);
    ActivityThread_sPackageManager = ActivityThread.staticField("sPackageManager").ofType(IPackageManager.getmClass());
    LoadedApk_mApplication = LoadedApk.field("mApplication");
    LoadedApk_mApplication.ofType(Application.class);
    LoadedApk_mResources = LoadedApk.field("mResources");
    LoadedApk_mResources.ofType(Resources.class);
    LoadedApk_mResDir = LoadedApk.field("mResDir");
    LoadedApk_mResDir.ofType(String.class);
    LoadedApk_mClassLoader = LoadedApk.field("mClassLoader");
    LoadedApk_mClassLoader.ofType(ClassLoader.class);
    LoadedApk_mBaseClassLoader = LoadedApk.field("mBaseClassLoader");
    LoadedApk_mBaseClassLoader.ofType(ClassLoader.class);
    LoadedApk_mAppDir = LoadedApk.field("mAppDir");
    LoadedApk_mAppDir.ofType(String.class);
    ContextImpl_mResources = ContextImpl.field("mResources");
    ContextImpl_mResources.ofType(Resources.class);
    ContextImpl_mTheme = ContextImpl.field("mTheme");
    ContextImpl_mTheme.ofType(android.content.res.Resources.Theme.class);
    sIsIgnoreFailure = true;
    ContextThemeWrapper_mBase = ContextThemeWrapper.field("mBase");
    ContextThemeWrapper_mBase.ofType(Context.class);
    sIsIgnoreFailure = false;
    ContextThemeWrapper_mTheme = ContextThemeWrapper.field("mTheme");
    ContextThemeWrapper_mTheme.ofType(android.content.res.Resources.Theme.class);
    try {
        if (Build.VERSION.SDK_INT >= 17 && ContextThemeWrapper.getmClass().getDeclaredField("mResources") != null) {
            ContextThemeWrapper_mResources = ContextThemeWrapper.field("mResources");
            ContextThemeWrapper_mResources.ofType(Resources.class);
        }
    } catch (NoSuchFieldException e) {
        log.log("Not found ContextThemeWrapper.mResources on VERSION " + Build.VERSION.SDK_INT, Logger.LogLevel.WARN);
    }
    ContextWrapper_mBase = ContextWrapper.field("mBase");
    ContextWrapper_mBase.ofType(Context.class);
    Resources_mAssets = Resources.field("mAssets");
    

    }

    public static void allMethods() throws HackAssertionException {
    ActivityThread_currentActivityThread = ActivityThread.method("currentActivityThread", new Class[0]);
    AssetManager_addAssetPath = AssetManager.method("addAssetPath", String.class);
    Application_attach = Application.method("attach", Context.class);
    ClassLoader_findLibrary = ClassLoader.method("findLibrary", String.class);
    if (LexFile != null && LexFile.getmClass() != null) {
    LexFile_loadLex = LexFile.method("loadLex", String.class, Integer.TYPE);
    LexFile_loadClass = LexFile.method("loadClass", String.class, ClassLoader.class);
    LexFile_close = LexFile.method("close", new Class[0]);
    DexClassLoader_findClass = DexClassLoader.method("findClass", String.class);
    }
    }

    public static void allConstructors() throws HackAssertionException {
    }

    public boolean onAssertionFailure(HackAssertionException hackAssertionException) {
    if (!sIsIgnoreFailure) {
    if (this.mExceptionArray == null) {
    this.mExceptionArray = new AssertionArrayException("atlas hack assert failed");
    }
    this.mExceptionArray.addException(hackAssertionException);
    }
    return true;
    }
    }
    '''
    找亮点

@imagebody
Copy link

这里面是伯奎连恒和我当初的代码。携程?只会copy么?

@TediWang
Copy link

TediWang commented Nov 6, 2015

淘宝的各位好,看来有必要声明一下这个事情了。2014年在看了到这2篇文章:
http://log4think.com/use-apache-felix-in-android/
http://log4think.com/use-knopflerfish-in-android/
对osgi运用到手机有了新的方案,osgi是一个开源的框架,bundle也是其中之一。
Android上要解决代码的动态加载和资源的分区加载,难点就是资源怎么分区。
我们真正解决的是资源的分区,修改了aapt源码,并且我们的脚本也是耗费了大量精力去实现分包,R文件的合并,同时也实现了hotfix。我们也把这个实践开源了,其中修改过的aapt源代码和打包的gradle脚本,毫无保留的分享给大家,希望能帮助到更多的Android开发者。

@guoguo338
Copy link

淘宝的代码偷过来稍微改改就开源标榜是自己的了。人需要自知之明。

@zjutyujf
Copy link

zjutyujf commented Nov 6, 2015

淘宝本身也会开源,借鉴可以,其他的不多说了,希望可以再采坑的路上进步吧

@TediWang
Copy link

TediWang commented Nov 9, 2015

感谢手淘的各位~希望通过大家的努力,能一起进步,为国内的技术发展尽一下绵薄的力量,如果有问题可以联系我:tediwang@gmail.com

@TediWang TediWang closed this as completed Nov 9, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants