之前很多同学叫要怎么hook startactivity 今天小编就来给大家讲解一下,图文的方式可以有点难看懂,不过小编会尽量写详细一点,当然小编也会有地方出错,希望大家可以多多指点一下。
一个活动界面启动另一个活动界面,需要打印相关的日志内容,就需要我们的start Activity,我们就要去hook。
startActivity的实现代码是由底层完成的,代理startActivity就必须找到他的最终启动去实现跳转的逻辑。所以呢我们要去分析startActivity的底层代码。
那如何使用HOOK startActivity呢?
接下来就给大家介绍介绍,请大家细细听来。
1.先定义两个活动界面,完成跳转。
2.找到最终代理的地方来代理这个 start activity。
3.声明一个tag以及代理的类。
4.定义 ActivityThread里面原始的 Instrumentation对象。
5.定义原始方法里面的正真启动activity的方法。
6.打印一些activity启动前后的日志信息,也可以修改相应的参数信息。
7.调用方法是否在底层,是否需要反射调用,以及设置可见。
8.进行代理在APPlication程序的入口点来写代码。
9.在APPlication定义一个线程和其他一些字符串。
10.获取当前ActivityThread对象,然后进行调用。
11.拿到在ActivityThread类里面最原始的mlnstrumentation对象。
12.构建我们的代理对象。
13.通过反射,换掉字段。
14.做个标记,方便后面查看。
15.运行完毕查看日志是否hook成功。
上面已经介绍完我们的步骤了接下来我们就要来实际的操作一下。
我们首先打开eclipse工具,我们在这个hook start activity工程里新建了4个类。
分别是两个activity活动界、一个代理类和instrumentation。
我们先去了解一下两个活动界面。
①.secondActivity
②.MainActivity
那么我们需要MainActivity跳转到secondActivity的时候是需要startActivity来启动它的。我们想要hook它也是要最终找到startActivity的地方,我们这个时候就要在MainActivity里面去找到startActivity。
找到真正启动的地方,我们按住ctrl键把我们的光标移到到方法上面就会显示一个下划线,此时可以点击进去查看它的底层源码。
我们来到真正定义的地方,发现里面还有一个startActivity。
真正启动我们的活动界面,那么我们还是同样的操作,按住ctrl键找到真正startActivity的地方。
找到之后我们会发现里面插入intent以及其他参数。
我们简单的做了一个if判断,判断之后我们会发现startActivityForResult其实它真正去实现的。
那么我们去看一下startActivityForResult。
来到startActivityForResult之后,我们会发现有很多的参数,也像之前一样,做了一个简单的判断,判断之后我们可以看到,他真正的启动点其实是minstrumentation去调用execstarActivities,那么其实真正的启动点是execstaractivities。
它又是被我们的minstrumentation所调用,那么我们找到我们的minstrumentation,这个类的定义地方我去简单的做一个搜索。
搜索我们该类定义的地方。
我们找到该类定义的地方,我们会发现它是由大写的I开头的Instrumentation这个类,我们点击这个类。
我们可以发现该类是由public calss 来修饰的,这就证明要用到我们的静态代理,我们先做一个埋点要记住,我们要用到的就是静态代理。
那么我们在这里面要找到execstartActivity它真正用到的地方,我们去搜索一下。
这个时候我们就来到他真正逻辑处,我们可以发现是ActivityRestult这个类,它是execStartAcivity这个方法最终实现的,那么我们找到它最终实现的一个点,它就是我们要去代理的一个类。
我们找到了代理类的一个关键点,那么我们就要去编写代码,首先我们在这里,在我们的代理类里面做一些相关逻辑,我们代理类去继承我们的instrumentation,继承完毕之后,我们可以看到这里面首先定义了一个TAG。
TAG之后又定义了我们真正要代理的这个对象,定义完毕之后我要给大家提醒一下,ActivityThead里面最原始的instrumentation这个对象,这里千万不要写成小写m的instrumentation
然后在里面定义我们的instrumentation这个对象可以换了一个名字,可以发现然后通过构造函数来传递一个对象。
然后我们会发现我们的instrumentation这个对象被传递进去进去,传递进去之后在这里,又给我们刚刚定义的所赋的值。
这个方法由原始方法的instrumentation有execStartAcivity方法来定,所以我们在这里实现的时候它会传入一些相关的参数。
传入完毕之后呢就开始打印我们的一些日志,在这里我们也可以把startActivity的一个参数作为一个修改,那么在这里同时我们也打印几条日志,也就是说我们可以打开我们的startActivity。
由于我们的这个方法是在底层完成的,是隐藏的,那么我们需要来反射进行调用,首先我们找到该方法。这里我们已经找到,找到之后我们在这里面给它设置可见。
然后在这里我们会发现有一个异常语句,如果这个类的成员变量instrumentation这个对象你写错了,写的小写m开头的话,我们的代码会执行到这个异常语句里去。
那么代理类准备完毕之后呢?我们是不是要去定义我们的代理地方,此时我们要定义在MyAPPlication里面。
定义完毕之后,我们在这里获取当前的ActivityThread对象,也就是主线程,UI主线程。
然后我们在这里面设置可见。
那么这些代码我们都准备完毕之后呢我们要先去运行一遍,查看我们的HOOK的最终结果。
启动我们的程序。
我们的程序已经启动完毕,我们在这里去找一下它的相关日志信息。
那么它的参数已经被hook出来了。
在这里我们可以做打开startActivity方法之前的一些事情以及之后的一些事情,这就证明我们hook成功了。 好了以上就是小编给大家带来的 startActivity HOOK,如果有不懂的朋友们可以来问我。如果小编哪里没对,大家也可以多多提提意见。