package com.introspy.core; import java.lang.reflect.GenericDeclaration; import java.lang.reflect.Member; import android.util.Log; import com.introspy.hooks.HookList; import com.introspy.custom_hooks.CustomHookList; import com.introspy.logging.LoggerConfig; import com.saurik.substrate.*; public class Main { // static private String _TAG = LoggerConfig.getTag(); static private String _TAG_ERROR = LoggerConfig.getTagError(); static private String _TAG_LOG = LoggerConfig.getTagLog(); static private boolean _debug = false; public static void initialize() { HookConfig[] _config = HookList.getHookList(); HookConfig[] _custom_config = CustomHookList.getHookList(); initializeConfig(_config); initializeConfig(_custom_config); MS.hookClassLoad("android.app.ContextImpl", new MS.ClassLoadHook() { public void classLoaded(Class<?> resources) { ApplicationState.initApplicationState(resources); } }); } protected static void initializeConfig(HookConfig[] config) { for (final HookConfig elemConfig : config) { if (!elemConfig.isActive()) continue; MS.hookClassLoad(elemConfig.getClassName(), new MS.ClassLoadHook() { public void classLoaded(Class<?> resources) { _hookMethod(resources, elemConfig); } }); } } @SuppressWarnings({ "unchecked", "rawtypes" }) protected static void _hookMethod(Class<?> resources, final HookConfig elemConfig) { GenericDeclaration pMethod = null; final String className = elemConfig.getClassName(); final String methodName = elemConfig.getMethodName(); final Class<?>[] parameters = elemConfig.getParameters(); Log.i(_TAG_LOG, "### Hooking: " + className + "->" + methodName + "() with " + parameters.length + " args"); try { // check if the method is a constructor if (className.substring(className.lastIndexOf('.') + 1).equals(methodName)) pMethod = resources.getDeclaredConstructor(parameters); else pMethod = resources.getMethod(methodName, parameters); } catch (NoSuchMethodException e) { Log.w(_TAG_ERROR, "Error - No such method: " + methodName + " with " + parameters.length + " args"); for (int j = 0; j < parameters.length; j++) Log.i(_TAG_ERROR, "Arg "+ (j+1) +" type: " + parameters[j]); return; } final MS.MethodPointer old = new MS.MethodPointer(); MS.hookMethod_(resources, (Member) pMethod, new MS.MethodHook() { public Object invoked(final Object resources, final Object... args) throws Throwable { if (ApplicationConfig.isEnabled()) _hookMethodImpl(old, resources, elemConfig, args); return old.invoke(resources, args); } }, old); } @SuppressWarnings("rawtypes") protected static void _hookMethodImpl(final MS.MethodPointer old, Object resources, final HookConfig elemConfig, Object... args) { String packageName = ApplicationConfig.getPackageName(); String dataDir = ApplicationConfig.getDataDir(); String type = elemConfig.getSubType(); if (packageName != null && dataDir != null && LoadConfig.getInstance().initConfig(dataDir) && LoadConfig.getInstance().getHookTypes().contains(type)) { try { elemConfig.getFunc().init(elemConfig, resources, old, args); if (LoadConfig.getInstance().getHookTypes().contains("STACK TRACES")) elemConfig.getFunc().enableTraces(); else elemConfig.getFunc().disableTraces(); if (LoadConfig.getInstance().getHookTypes().contains("NO DB") || LoadConfig.getInstance().getHookTypes().contains("SQLite")) elemConfig.getFunc().disableDBlogger(); else elemConfig.getFunc().enableDBlogger(); elemConfig.getFunc().init(elemConfig, resources, old, args); if (_debug) Log.i(_TAG_LOG, "=== Calling: " + elemConfig.getMethodName()); elemConfig.getFunc().execute(args); } catch (Exception e) { Log.w(_TAG_ERROR, "-> Error in injected code: [" + e + "]" + "\nApp: " + ApplicationConfig.getPackageName() + ", method: " + elemConfig.getMethodName() + ", class: " + elemConfig.getClassName()); // Log.w(_TAG_ERROR, LoggerErrorHandler._getStackTrace()); } } } }