(Android) 如何使用HOOK实现动态注入以及自动化操作

(Android) 如何使用HOOK实现动态注入以及自动化操作

为什么会有这边博文?

最近一直在搞一些apk破解以及自动化方面的东西.觉得有必要记录一下.也是为了修改下自己懒的毛病(很久很久很久没更新博客了)

一. 项目需求

项目功能:

本文将使用QQ为例,利用Hook实现自动登录,自动退出登录功能

项目流程:

流程比较简单
WX20190621-113232@2x.png

二. 资源准备

大致需要准备以下东西:

  1. 一台空闲的安卓手机,能root最好.
  2. 安装VirtualXposed(传送门),安装QQ(传送门,提取码: ty58)(注意QQ是8.0.0.4000版本,不同版本可能会影响hook点),对于不懂怎么使用hook的请参考
  3. 将QQ安装到VirtualXposed
  4. QQ脱壳获取源代码(不懂脱壳操作请点这里)

三. 功能实现

3.1 实现自动从QQ新用户页跳转到登陆页

第一次启动qq的时候,qq会停留在,显然要实现登陆的话我们需要让其自动进入登陆页面,如图:
登陆图片.png

3.1.1 获取新用户页的堆栈信息(手机需要连接电脑)
adb shell dumpsys activity >>输出路径

下面是导出的堆栈信息:
堆栈信息.png

我们可以得到登陆界面的RegisterGuideView.以及登陆按钮的16进制值7f0b0da9

3.1.2 获取登陆按钮逻辑的Hook点

通过PowerGREP工具对脱壳后的QQdex源码(脱壳后可得到十几个dex文件)进行字符串搜索找到RegisterGuideView所在的dex,然后通过jeb工具反编译该dex, 以下是RegisterGuideView类的源码

package com.tencent.mobileqq.activity.registerGuideLogin;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View$OnClickListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import com.tencent.mobileqq.activity.RegisterPhoneNumActivity;
import com.tencent.mobileqq.app.QQAppInterface;
import com.tencent.mobileqq.statistics.ReportController;
import com.tencent.qphone.base.util.QLog;

public class RegisterGuideView extends GuideBaseFragment implements View$OnClickListener {
   
    private View a;
    private Button a;
    private Button b;

    public RegisterGuideView() {
   
        super();
    }

    @SuppressLint(value={
   "ValidFragment"}) public RegisterGuideView(QQAppInterface arg1) {
   
        super(arg1);
    }

    public void onClick(View arg14) {
   
        Intent v0;
        switch(arg14.getId()) {
   
            case 2131430824: {
   
                ReportController.b(this.a, "CliOper", "", "", "0X8007576", "0X8007576", 0, 0, "", "", "", "");
                v0 = new Intent(this.a, RegisterPhoneNumActivity.class);
                v0.putExtra("key_register_from", 2);
                v0.putExtra("leftViewText", this.a.getString(2131499116));
                v0.addFlags(67108864);
                this.a.startActivity(v0);
                break;
            }
            case 2131430825: {
   
                ReportController.b(this.a, "CliOper", "", "", "0X8007575", "0X8007575", 0, 0, "", "", "", "");
                v0 = this.a.getIntent();
                v0.putExtra("from_register_guide", true);
                v0.putExtra("is_need_show_logo_animation", true);
                GuideBaseFragment v0_1 = GuideHandler.a(this.a, this.a);
                if(this.a == null) {
   
                    return;
                }

                this.a.a(v0_1);
                break;
            }
        }
    }

    public View onCreateView(LayoutInflater arg7, ViewGroup arg8, Bundle arg9) {
   
        View v1 = arg7.inflate(2130903607, arg8, false);
        this.a = v1.findViewById(2131428759);
        this.a.setVisibility(0);
        this.a = v1.findViewById(2131430825);
        this.b = v1.findViewById(2131430824);
        this.a.setOnClickListener(((View$OnClickListener)this));
        this.b.setOnClickListener(((View$OnClickListener)this));
        View v0 = v1.findViewById(2131430823);
        try {
   
            ((ImageView)v0).setImageDrawable(new BitmapDrawable(this.getResources(), this.getActivity().getAssets().open("splash.jpg")));
        }
        catch(Throwable v0_1) {
   
            QLog.e("LoginActivity.RegisterGuideView", 1, "onCreateView error:" + v0_1.getMessage());
        }

        return v1;
    }
}


通过我们得到的登陆按钮的16进制值7f0b0da9可以确定10进制值2131430825,从而确定变量a是登陆按钮.

3.1.3 通过Hook 实现登陆按钮点击

由于我们已经找到了登陆按钮相关的类和按钮变量对象,接下来我们只需要通过hook拿到该按钮对象,实现点击即可自动进入登陆页面
以下是核心代码:

/**
     * hook新用户页,拿到登陆按钮,模拟点击登陆
     */
    public static void hookRegisterGuideLogin()
    {
   
        XposedHelpers.findAndHookMethod("com.tencent.mobileqq.activity.registerGuideLogin.RegisterGuideView", context.getClassLoader(), "onCreateView", LayoutInflater.class, ViewGroup.class, Bundle.class, new XC_MethodHook()
        {
   
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable
            {
   
                super.afterHookedMethod(param);

                final Object obj = param.thisObject;

                
                doMainLooper(context, 1000, new Runnable()
                {
   
                    @Override
                    public void run()
                    {
   
                        //得到按钮对象
                        Object viewObj = ReflectUtils.getFieldValueForFiledClsNm(obj, "a", "android.widget.Button");

                        if (viewObj instanceof Button)
                        {
   
                            //点击按钮
                            ((Button) viewObj).performClick();
                        }
                    }
                });

            }
        });
    }

目前为止,我们就已经完成了长征的第一步,从新用户页自动点击到登陆页. 下面是成果演示:

前往登陆界面.gif

可以看到我们已经实现了从新用户页点击到登陆页了.

3.2 实现登陆页自动填充登陆账号和密码并自动登陆
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值