Android hook技術之小試牛刀
一、瞭解Hook概念
Hook是鉤子的意思。我們知道應用執行依賴系統各種各樣的API。當某些API不能滿足我們的要求時,如果想修改它的功能,使之能滿足我們的要求。就要用到Hook技術。
在Android開發中,我們同樣能利用Hook的原理讓系統某些方法執行時,實際呼叫的是我們自己定義的方法,從而滿足我們的要求。
二、利用java反射實現簡單的Hook——將在Manifest中註冊的MainActivity替換成沒在Manifest中註冊過的TestActivity。
2.1)新建一個Android專案,建立MainActivity和TestActivity,TestActivity不在AndroidManifest.xml中配置。
2.2)寫一個InstrumentationHook繼承系統的Instrumentation,並重寫父類的newActivity方法
- publicclass InstrumentationHook extends Instrumentation {
- @Override
- public Activity newActivity(Class<?> clazz, Context context, IBinder token,
- Application application, Intent intent, ActivityInfo info,
- CharSequence title, Activity parent, String id,
- Object lastNonConfigurationInstance) throws InstantiationException,
- IllegalAccessException {
- Log.d(this, " CustomInstrumentation#newActivity call 1");
- return
- title, parent, id, lastNonConfigurationInstance);
- }
- @Override
- public Activity newActivity(ClassLoader cl, String className, Intent intent)
- throws InstantiationException, IllegalAccessException,
- ClassNotFoundException {
- Log.d(this, " CustomInstrumentation#newActivity call 3 parmas className:" + className + " intent:" + intent.toString());
- Activity activity = createActivity(intent);
- if (activity != null) {
- return activity;
- }
- returnsuper.newActivity(cl, className, intent);
- }
- /*可以在createActivity攔截替換某個activity,下面自是一個簡單例子*/
- protected Activity createActivity(Intent intent) {
- String className = intent.getComponent().getClassName();
- Log.d(this, "createActivity className=" + className);
- if ("hook.jason.com.androidhook.MainActivity".equals(className)) {
- try {
- Class<? extends Activity> PluginActivity = (Class<? extends Activity>) Class
- .forName("hook.jason.com.androidhook.TestActivity");
- return PluginActivity.newInstance();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- returnnull;
- }
- }
2.3)獲取當前應用的ActivityThread,並替換系統預設定義的mInstrumentation例項
- /**
- * Created by zeyu,Jia
- */
- publicclass HookManager {
- static Object activityThreadInstance;
- publicstaticvoid init() throws ClassNotFoundException,
- NoSuchMethodException, IllegalAccessException,
- IllegalArgumentException, InvocationTargetException {
- Class<?> activityThread = Class.forName("android.app.ActivityThread");
- Method currentActivityThread = activityThread
- .getDeclaredMethod("currentActivityThread");
- activityThreadInstance = currentActivityThread.invoke(null);
- }
- publicstaticvoid injectInstrumentation() throws NoSuchFieldException,
- IllegalAccessException, IllegalArgumentException {
- Log.i(HookManager.class, " start injectInstrumentation");
- Field field_instrumentation = activityThreadInstance.getClass()
- .getDeclaredField("mInstrumentation");
- field_instrumentation.setAccessible(true);
- InstrumentationHook instrumentationHook = new InstrumentationHook();
- field_instrumentation.set(activityThreadInstance, instrumentationHook);
- }
- }
2.4)在MyApplication的onCreate裡替換ActivityThread裡的mInstrumentation變數
- publicclass MyApplication extends Application {
- @Override
- publicvoid onCreate() {
- try {
- Log.d(this, " onCreate starting init");
- HookManager.init();
- HookManager.injectInstrumentation();
- } catch (Exception e) {
- Log.d(this, " onCreate e:" + e.toString());
- }
- super.onCreate();
- }
- }
2.5)執行後介面如下:
2.6)具體log如下:
03-18 17:28:55.621 436-436/hook.jason.com.androidhook D/AndroidHook: MyApplication : onCreate starting init
03-18 17:28:55.623 436-436/hook.jason.com.androidhook I/AndroidHook: Class : start injectInstrumentation
03-18 17:28:55.633 436-436/hook.jason.com.androidhook D/AndroidHook: InstrumentationHook : CustomInstrumentation#newActivity call 3 parmas className:hook.jason.com.androidhook.MainActivity intent:Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=hook.jason.com.androidhook/.MainActivity }
03-18 17:28:55.633 436-436/hook.jason.com.androidhook D/AndroidHook: InstrumentationHook : createActivity className=hook.jason.com.androidhook.MainActivity
03-18 17:28:55.674 436-436/hook.jason.com.androidhook D/AndroidHook: TestActivity : onCreate
03-18 17:28:55.752 436-436/hook.jason.com.androidhook D/AndroidHook: TestActivity : onResume
03-18 17:28:55.775 436-436/hook.jason.com.androidhook D/AndroidHook: TestActivity : onPause
03-18 17:28:55.789 436-436/hook.jason.com.androidhook D/AndroidHook: TestActivity : onAttachedToWindow
03-18 17:39:55.838 436-436/hook.jason.com.androidhook D/AndroidHook: TestActivity : onRestart
03-18 17:39:55.855 436-436/hook.jason.com.androidhook D/AndroidHook: TestActivity : onResume
03-18 17:40:26.044 436-436/hook.jason.com.androidhook D/AndroidHook: TestActivity : onPause
從log中可以看出MainActivity的onCreate方法根本沒有執行,走的是沒有配置的TestActivity類