android 全局hook_【Hook】实现无清单启动Activity

本文详细介绍了如何使用Hook技术实现Android全局无清单启动Activity,通过伪造Intent欺骗系统检测,以及在真正跳转前还原Intent,避免错误。文章提供了一个Demo,展示了具体的hook实现步骤,并分析了相关源码,揭示了Android系统启动Activity的内部机制。
摘要由CSDN通过智能技术生成

09822aa6a9210bffa2c20ea20b872286.png

引子

Hook技术在android开发领域算是一项黑科技,那么一个新的概念进入视线,我们最关心的3个问题就是,它是什么,有什么用,怎么用

本系列将由浅入深 手把手讲解这三大问题。

本文是第三篇, 高级篇。

前面两篇Hook博文,写了两个demo,一个是hook入门,一个是略微复杂的Activity启动流程的hook。

那么玩点更高端的吧, 正常开发中,所有 Activity都要在 AndroidManifest.xml中进行注册,才可以正常跳转,通过 hook,可以绕过系统对 activity注册的检测,即使不注册,也可以正常跳转。

鸣谢

感谢大神的博文 https://www.jianshu.com/p/eb4121b037e2


正文大纲

一.整体思路
二.源码索引
三.hook核心代码
四.最终效果

Demo地址:

https://github.com/18598925736/ActivityHookDemo/tree/startActivityWithoutRegiste

正文

提示:本文所有源码索引图,都基于 SDK28-android9.0系统.


一.整体思路

在之前Activity启动流程的hook的Demo里,我进行了 Activity流程的 hook,最终采用的方案,是 HookAMS,实现了全局的 startActivity动作的 劫持. 现在就从这个AMS的 hook为起点,来实现 无清单启动Activity.

Activity启动流程的 hook的Demo里,最后实现的效果是,每次跳转 Activity,都能看到这个日志:

f62244ea41092fee87575ce2902bc60e.png

那么,我们既然侦测到了 startActivity这个方法的调用,那么自然就可以拿到里面的实参,比如, IntentIntent是跳转意图,从哪里来,跳到哪里去的信息,都包含在 Intent里面.而, manifestActivity的检测,也是要根据 Intent里面的信息来的.所以,要骗过系统,要假装我们跳的 Activity是已经注册过的,那么只需要将 Intent里面的信息换成 已经在 manifest中注册的某个 Activity就可以了( 这里可能就有人像抬杠了,你怎么知道manifest里面一定有注册Activity....如果一个Activity都没有,你的app是怎么启动的呢,至少得有一个LauncherActivity吧--!).

确定思路: 1.在AMS的hook函数中,将 真实的Intent中的信息,替换成manifest中已有的Activity信息. 骗过系统的检测机制。2.虽然骗过了系统的检测机制,但是这么一来,每一次的跳转,都会跳到 "假"Activity,这肯定不是我们想要的效果,那么就必须,在真正的跳转时机之前,将 真实的Activity信息,还原回去, 跳到原本该去的 Activity.

对应的核心代码,其实也就两句话:dd7248e4a316a5a55262af7a317688f1.png


二.源码索引

下图大致画出了:Activity.startActivity动作开始,到最终 跳转动作的最终执行者 全过程.

1f8530bc1b1ac245b29bdb5e9f5425e6.png

下面开始看源码,从 Activity.startActivity开始:

1e13bf2123f034fbfc5c99543189b5dc.png1fd320daf6b22ee0e80582419a6fbc5e.png8af9a1129cec8053f1c33a6b4c8c289c.png7ae4fd79d68625948d41e2c9f900eb5a.png

这里开始分支:if(mParent==null),但是两个分支最终执行如下:

966b89f3264cbf9fc9318673be4b704e.png9e8bea94cc7f2601122011a6f4e3ac7c.png

很显然,两者都是同样的调用过程:

Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(....);

mMainThread.sendActivityResult(...);

第一句, execStartActivity 是 对一些参数的合法性校验,如果不合法,那就会直接抛出异常,比如之前的 8517f2005828481889f1040dffb56783.png第二句, sendActivityResult才是真正的 跳转动作执行者

先进入第一句Instrumentation.ActivityResultar=mInstrumentation.execStartActivity看看,既然是合法性校验,且看他是如何校验的。

这是 InstrumentationexecStartActivity方法503d5ea647f558c85b4e278e4cb3c9df.png结论:它是通过AMS去校验的,AMS startActivity会返回一个int数值,随后, checkStartActivityResult方法会根据这个 int值,抛出响应的异常,或者什么都不做.a8812d6be90ddd959b8ad9edf6bf30fc.png

再进入第二句 mMainThread.sendActivityResult看真正的跳转动作是如何执行的:ps:这里其实有个诀窍,既然我们的终极目标是要骗过系统的Activity Intent检测,那么,跟着Intent这个变量,就不会偏离方向.

4788b59858620bc24a1ee62dea19dd6f.png

既然intent被封装到了 ClientTransaction,交给了 mAppThread,那么继续:

ec08a8d6deb00b3bd03dd2fefd5a08ea.png前方有坑,请注意:androidStudio里并不能直接跳转,所以要手动,找到下图中的方法,这个 ClientTransactionHandlerActivityThread的父类.37ab1ccd0cd3dfdaf5eb0a15c1d895b5.png上图中,调用了 sendMessage(int,Object),在 ActivityThread中找到这个方法的实现:7a34f0c71b981820ac9cdb5b8df65204.png找它的最终实现:a2fd47ab31333b207345f40f14ff0f9b.png找到另一个关键点:mH ,a59761ee5142ef59de70976e07b0efe9.pngH类的定义:(太长了,我就不完整截图了,留下关键的信息)

final H mH = new H();

class H extends Handler {

...

public static final int EXECUTE_TRANSACTION = 159;

String codeToString(int code) {

if (DEBUG_MESSAGES) {

switch (code) {

case EXECUTE_TRANSACTION: return "EXECUTE_TRANSACTION";

case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";

}

}

return Integer.toString(code);

}

public void handleMessage(Message msg) {

if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));

switch (msg.what) {

case EXECUTE_TRANSACTION:

final ClientTransaction transaction = (ClientTransaction) msg.obj;

mTransactionExecutor.execute(transaction);

if (isSystem()) {

// Client transactions inside system process are recycled on the client side

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值