Xposed HOOK入门体验

2020-10-05  本文已影响0人  Sharkchilli

Xposed框架介绍

Xposed框架是一款开源java层的HOOK框架,其功能是可以在不修改APK的情况下影响程序运行(修改系统)的框架服务,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。自己编写HOOK功能是相当麻烦的所以我们一般使用这些hook框架来做HOOK,这样我们就可以把精力放在业务逻辑上了。常用的Hook框架有Xposed、CydiaSubstrate和ADBI/DDI,这里Xposed感觉是最易用的了。

工作原理

Xposed框架是由rovo89开发的一款针对Android平台的动态劫持项目,是一款可以在不修改APK的情况下影响程序运行(修改系统)的框架服务,通过替换/system/bin/app_process 程序控制 zygote 进程,从而使 app_process 在启动过程中加载XposedBridge.jar 这个jar包,从而完成对Zygote进程及其创建的Dalvik虚拟机的劫持。

Zygote进程在启动过程中,除了创建一个Dalvik虚拟机实例之外,还会将Java运行时库加载到进程中来,同时还会注册一些Android核心类的JNI方法到前面创建的Dalvik虚拟机实例中去。

一个应用程序被孵化出来的时候,其不仅会获得Zygote进程中的Dalvik虚拟机实例,还会与Zygote一起共享Java运行时库,这也是可以将XposedBridge.jar这个jar包加载到每一个Android应用中的原因。
XposedBridge有一个私有的Native方法:hookMethodNative,这个方法也在app_process中使用。该函数提供一个方法对象利用Java的反射机制来对内置的方法覆写。

环境

Android Studio
Android4.4.4
Xposed2.7.apk

Xposed框架的安装

将Xposed2.7.apk安装到你的手机上进入后界面如下


image.png

进入框架


image.png
点击安装/更新
重启之后就安装完成了

目标项目的编写

这里为了更清楚的展示效果这里被HOOK的项目也由我们自己编写
创建项目


image.png
image.png

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="HOOK"
         />

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java

package com.shark.xposedtarget;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, toastMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    public String toastMessage() {
        return "我未被劫持";
    }
}

项目运行效果如下


image.png

HOOK模块的编写

同上创建项目后
AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.shark.hookmodle">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <!--告诉Xposed框架这个是Xposed模块-->
        <meta-data
            android:name="xposedmodule"
            android:value="true" />
        <!--模块的描述信息-->
        <meta-data
            android:name="xposeddescription"
            android:value="这是一个Xposed例程" />
        <!--模块支持的最低版本-->
        <meta-data
            android:name="xposedminversion"
            android:value="53" />

        
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

主要添加了meta-data等信息上面的注释已经说明
接下来在build.gradle添加XposedBridgeApi-xx.jar

找到build.gradle,加上:

repositories {
    jcenter()
}

以及

compileOnly 'de.robv.android.xposed:api:82'
compileOnly 'de.robv.android.xposed:api:82:sources'

这句代码是告诉AndroidStuido使用jcenter作为代码仓库,从这个仓库里远程寻找 de.robv.android.xposed:api:82 这个API。这个网上很少有Xposed教程介绍它的!(我们不用自己找XposedBridgeApi.jar了。注意!此处要用compileOnly这个修饰符!网上有些写的是provide ,现在已经停用了!)

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.shark.hookmodle"
        minSdkVersion 19
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

repositories {
    jcenter()
}

dependencies {
    compileOnly 'de.robv.android.xposed:api:82'
    compileOnly 'de.robv.android.xposed:api:82:sources'
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

新建一个类“HookTest.java”,代码如下:

package com.shark.hookmodle;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class HookTest implements IXposedHookLoadPackage {
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        if (loadPackageParam.packageName.equals("com.shark.xposedtarget")) {
            XposedBridge.log(" has Hooked!");
            Class clazz = loadPackageParam.classLoader.loadClass(
                    "com.shark.xposedtarget.MainActivity");
            XposedHelpers.findAndHookMethod(clazz, "toastMessage", new XC_MethodHook() {
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                    //XposedBridge.log(" has Hooked!");
                }
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    param.setResult("你已被劫持");
                }
            });
        }
    }
}

最后一步,添加入口点
右键点击 “main ” 文件夹 , 选择new --> Folder -->Assets Folder,新建assets 文件夹:

然后右键点击 assets文件夹, new--> file,文件名为xposed_init(文件类型选text),并在其中写上入口类的完整路径(就是自己编写的那一个Hook类),这样, Xposed框架就能够从这个 xposed_init 读取信息来找到模块的入口,然后进行Hook操作了:


image.png

将此模块安装到手机上

运行

勾选我们开发的模块


image.png

重启后运行目标app结果如下


image.png
上一篇下一篇

猜你喜欢

热点阅读