/** * OpenAtlasForAndroid Project * The MIT License (MIT) Copyright (OpenAtlasForAndroid) 2015 Bunny Blue,achellies * <p> * Permission is hereby granted, free of charge, to any person obtaining a copy of this software * and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to the following conditions: * <p> * The above copyright notice and this permission notice shall be included in all copies * or substantial portions of the Software. * <p> * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * @author BunnyBlue **/ package com.openatlas.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.content.res.Resources.Theme; import android.os.Build.VERSION; import android.view.ContextThemeWrapper; import com.openatlas.hack.Hack.AssertionFailureHandler; import com.openatlas.hack.Hack.HackDeclaration; import com.openatlas.hack.Hack.HackedClass; import com.openatlas.hack.Hack.HackedField; import com.openatlas.hack.Hack.HackedMethod; import com.openatlas.log.Logger; import com.openatlas.log.LoggerFactory; import java.util.ArrayList; import java.util.Map; import dalvik.system.DexClassLoader; /**** * this class is OpenAtlas Core Inject Implementation,hook system implementation * 1 hack Class(such hack class ActivityThread) * 2 hack method(such ActivityThread_currentActivityThread,mean currentActivityThread at class ActivityThread) * 3 hack field(such ActivityThread_mAllApplications,field mAllApplications at class ActivityThread) * *****/ public class OpenAtlasHacks extends HackDeclaration implements AssertionFailureHandler { /** * This manages the execution of the main thread in an * application process, scheduling and executing activities, * broadcasts, and other operations on it as the activity * manager requests. */ public static HackedClass<Object> ActivityThread; /** Reference to singleton ActivityThread*/ public static HackedMethod ActivityThread_currentActivityThread; public static HackedField<Object, ArrayList<Application>> ActivityThread_mAllApplications; public static HackedField<Object, Application> ActivityThread_mInitialApplication; 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> Application; public static HackedMethod Application_attach; public static HackedClass<AssetManager> AssetManager; /** * Add an additional set of assets to the asset manager.This can be either a directory or ZIP file. * Returns the cookie of the added asset, or 0 on failure.solve resource problem **/ public static HackedMethod AssetManager_addAssetPath; public static HackedClass<ClassLoader> ClassLoader; /** * Returns the absolute path of the native library with the specified name, * or {@code null}. If this method returns {@code null} then the virtual * machine searches the directories specified by the system property */ public static HackedMethod ClassLoader_findLibrary; /** * Common implementation of Context API, which provides the base * context object for Activity and other application components. */ public static HackedClass<Object> ContextImpl; public static HackedField<Object, Resources> ContextImpl_mResources; public static HackedField<Object, Theme> ContextImpl_mTheme; /** * A ContextWrapper that allows you to modify the theme from what is in the * wrapped context. */ public static HackedClass<ContextThemeWrapper> ContextThemeWrapper; public static HackedField<ContextThemeWrapper, Context> ContextThemeWrapper_mBase; public static HackedField<ContextThemeWrapper, Resources> ContextThemeWrapper_mResources; public static HackedField<ContextThemeWrapper, Theme> ContextThemeWrapper_mTheme; /** * Proxying implementation of Context that simply delegates all of its calls to * another Context. Can be subclassed to modify behavior without changing * the original Context. **/ public static HackedClass<ContextWrapper> ContextWrapper; public static HackedField<ContextWrapper, Context> ContextWrapper_mBase; public static HackedClass<DexClassLoader> DexClassLoader; public static HackedMethod DexClassLoader_findClass; public static ArrayList<HackedMethod> GeneratePackageInfoList; public static ArrayList<HackedMethod> GetPackageInfoList; public static HackedClass<Object> IPackageManager; /** * LexFile is Ali YunOS exectue file format like dex,run on lemur vm * */ public static HackedClass<Object> LexFile; public static HackedMethod LexFile_close; public static HackedMethod LexFile_loadClass; public static HackedMethod LexFile_loadLex; //define support ali YunOS end /** * Local state maintained about a currently loaded .apk,used by ActivityThread */ public static HackedClass<Object> 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> Resources; public static HackedField<Resources, Object> Resources_mAssets; public static HackedClass<Service> Service; protected static final Logger log; public static boolean sIsIgnoreFailure; public static boolean sIsReflectAvailable; public static boolean sIsReflectChecked; private AssertionArrayException mExceptionArray; public OpenAtlasHacks() { this.mExceptionArray = null; } static { log = LoggerFactory.getInstance(OpenAtlasHacks.class); sIsReflectAvailable = false; sIsReflectChecked = false; sIsIgnoreFailure = false; GeneratePackageInfoList = new ArrayList<HackedMethod>(); GetPackageInfoList = new ArrayList<HackedMethod>(); } /** * hack all defined class,method ,and field ***/ public static boolean defineAndVerify() throws AssertionArrayException { if (sIsReflectChecked) { return sIsReflectAvailable; } OpenAtlasHacks atlasHacks = new OpenAtlasHacks(); try { Hack.setAssertionFailureHandler(atlasHacks); if (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.error("HackAssertionException", e); } finally { Hack.setAssertionFailureHandler(null); sIsReflectChecked = true; } return sIsIgnoreFailure; } /** * hack all defined classes ***/ private static void allClasses() throws HackAssertionException { if (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"); sIsIgnoreFailure = false; } /*** * hack all defied fields **/ private static void allFields() throws HackAssertionException { ActivityThread_mInstrumentation = ActivityThread.field( "mInstrumentation").ofType(Instrumentation.class); ActivityThread_mAllApplications = ActivityThread.field( "mAllApplications").ofGenericType(ArrayList.class); ActivityThread_mInitialApplication = ActivityThread.field( "mInitialApplication").ofType(Application.class); ActivityThread_mPackages = ActivityThread.field("mPackages") .ofGenericType(Map.class); ActivityThread_sPackageManager = ActivityThread.staticField( "sPackageManager").ofType(IPackageManager.getmClass()); LoadedApk_mApplication = LoadedApk.field("mApplication").ofType( Application.class); LoadedApk_mResources = LoadedApk.field("mResources").ofType( Resources.class); LoadedApk_mResDir = LoadedApk.field("mResDir").ofType(String.class); LoadedApk_mClassLoader = LoadedApk.field("mClassLoader").ofType( ClassLoader.class); LoadedApk_mBaseClassLoader = LoadedApk.field("mBaseClassLoader") .ofType(ClassLoader.class); LoadedApk_mAppDir = LoadedApk.field("mAppDir").ofType(String.class); ContextImpl_mResources = ContextImpl.field("mResources").ofType( Resources.class); ContextImpl_mTheme = ContextImpl.field("mTheme").ofType(Theme.class); sIsIgnoreFailure = true; ContextThemeWrapper_mBase = ContextThemeWrapper.field("mBase").ofType( Context.class); sIsIgnoreFailure = false; ContextThemeWrapper_mTheme = ContextThemeWrapper.field("mTheme") .ofType(Theme.class); try { if (VERSION.SDK_INT >= 17 && ContextThemeWrapper.getmClass().getDeclaredField( "mResources") != null) { ContextThemeWrapper_mResources = ContextThemeWrapper.field( "mResources").ofType(Resources.class); } } catch (NoSuchFieldException e) { log.warn("Not found ContextThemeWrapper.mResources on VERSION " + VERSION.SDK_INT); } ContextWrapper_mBase = ContextWrapper.field("mBase").ofType( Context.class); Resources_mAssets = Resources.field("mAssets"); } /*** * hack all defined methods **/ private static void allMethods() throws HackAssertionException { ActivityThread_currentActivityThread = ActivityThread.method( "currentActivityThread"); 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"); DexClassLoader_findClass = DexClassLoader.method("findClass", String.class); } } private static void allConstructors() throws HackAssertionException { } @Override 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; } }