吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2362|回复: 45
上一主题 下一主题
收起左侧

[Android 原创] Android逆向学习(八)Xposed快速上手(上)

  [复制链接]
跳转到指定楼层
楼主
Rytter 发表于 2025-5-4 22:42 回帖奖励

Android逆向学习(八)Xposed快速上手(上)

这是吾爱破解正己大大教程中的Xposed快速上手内容的实践,然后我的系统还是ubuntu,这是作业的实现。

前言

xposed是一个用来hook的工具,简而言之,通过替换/system/bin/app_process程序控制zygote进程,这样的话,app_process在启动过程中会加载XposedBridge.jar这个jar包,从而完成对Zygote进程以及创建的Dalvik虚拟机的劫持。

看起来有点烧脑是不是,没关系,会用就行!

之前的博客中我们讲解了frida这个框架(个人比较喜欢用这个来分析),但是一个问题是frida框架需要通过电脑端进行控制,也就是我们需要在电脑端运行python程序,然后通过这个程序进行hook。

如果说我们想要长久的使用一个hook程序,也就是不使用电脑也能hook,frida是很难实现的,但是xposed可以实现,只需要编写好插件,xposed就能根据这个插件长久的执行hook操作,不需要再使用电脑连接。

不过xposed现在已经不再支持最新的系统,所以本章节在手机端主要用到的是Lsposed框架。

原理

首先讲解一下xposed原理,这就要涉及到android的基本的原理。

Dalvik 是 Android 系统最初使用的虚拟机,用于执行 Android 应用程序。它不是 Java 虚拟机(JVM),但可以运行将 Java 源码编译成 .dex(Dalvik Executable)格式的字节码文件。每个 Android 应用都在一个独立的 Dalvik 实例中运行。

注意:从 Android 5.0(Lollipop)开始,Dalvik 被新的 ART(Android Runtime)替代了,但原理上是类似的,都是“虚拟机”或“运行时环境”。

每个 Android 应用在运行时都会拥有一个独立的虚拟机实例(在 Dalvik 时代如此,后来的 ART 运行时也是一样的概念)。

更准确地说:

  • 每个 App 运行在 自己的进程中
  • 这个进程内有一个独立的虚拟机实例(Dalvik 或 ART);
  • 各个 App 之间的虚拟机 互相隔离,互不影响。

所以说,相当于每个虚拟机中负责保存变量等信息,具体执行的时候,再放到CPU上

Xposed 的本质:修改 ART/Dalvik 的方法调用流程

1. Android 应用运行流程复习(简化版):

  1. Java/Kotlin 代码编译成 .dex
  2. 运行时被 ART(或老版本的 Dalvik)虚拟机加载;
  3. 虚拟机会调用类的方法;
  4. 方法的执行依赖虚拟机内部的“方法表”(method table)和类元信息。

    2. Xposed 的关键做法:

在方法被调用前,修改其在虚拟机中的元数据指针,插入你自己的代码逻辑。

换句话说,就是把这个“指向原始函数”的指针,改为“指向你自己的 Hook 逻辑”。

环境准备

手机环境

首先在Magisk中开启Zygisk。

之后下载LSposed软件:https://github.com/LSPosed/LSPosed

下载安装完成后重启手机

下载后桌面上可能不会出现图标,这时候在拨号键输入代号码 *#*#5776733#*#*

就可以显示出LSposed控制面板,然后勾选强制显示就可以显示出桌面图标,方便进入:

到这里,LSposed就安装完成

电脑环境

首先使用Android Studio创建一个空activity

之后的配置默认就好,如果习惯用java可以用java,因为现在google强推kotlin以替换java语言,所以这次我用的直接就是kotlin

创建完成后,对目录结构进行配置,首先是下载xposed的包,可能有小伙伴要问,不是用的LSposed吗,为什么要用xposed。

原因是LSposed兼容了原来的xposed插件,也就是可以利用原来xposed包开发LSposed包。

下载包的话主要在以下几个文件内修改:

settings.gradle.kts
pluginManagement {
    repositories {
        google {
            content {
                includeGroupByRegex("com\\.android.*")
                includeGroupByRegex("com\\.google.*")
                includeGroupByRegex("androidx.*")
            }
        }
        mavenCentral()
        gradlePluginPortal()
        maven { url =  uri("https://maven.aliyun.com/repository/public/") } //添加这一行
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        maven { url =  uri("https://maven.aliyun.com/repository/public/") } //添加这一行
        google()
        mavenCentral()
    }
}

rootProject.name = "LSposedHook"
include(":app")
build.gradle.kts(app目录下的那个)
dependencies {
    compileOnly("de.robv.android.xposed:api:82") //添加这一行
    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.appcompat)
    implementation(libs.material)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
}

之后Sync以下,就可以下载包了

下载完成之后,开始编写包,首先创建以下几个文件:

  1. assets下的xposed_init
  2. HookEntry
  3. 在src/main/res/values下面创建一个arrays.xml文件

创建完成这三项之后,在AndroidManifest.xml下加入这些meta-data:

<meta-data
    android:name="xposedmodule"
    android:value="true" />
<meta-data
    android:name="xposeddescription"
    android:value="Hook isVip() always return true" />
<meta-data
    android:name="xposedminversion"
    android:value="54" />
<meta-data
    android:name="xposedscope"
    android:resource="@array/xposedscope"/>

如下图所示,加入到application的标签中,这样LSposed才能识别到这是一个xposed插件:

然后xposed_init中加入kt文件的包名,比如创建的kt文件叫HookEntry,那么xposed_init中就写入一个这个(就是包名加上类名):

com.example.lsposedhook.HookEntry

这样LSposed就知道这个类里面有插件的代码。

之后在arrays.xml中加入以下内容:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="xposedscope" >
        <!-- 这里填写模块的作用应用的包名,能填多个,这里就填一个。 -->
        <item>com.zj.wuaipojie</item>
    </string-array>
</resources>

这可以表明该模块是用于这个应用的。

编写LSposed脚本

目标

通过hook完成挑战二

脚本编写

在HookEntry中写入:

package com.example.lsposedhook // 定义当前类的包名,和项目结构对应

// 引入 Xposed 框架提供的接口和工具类
import de.robv.android.xposed.IXposedHookLoadPackage // Xposed 的主接口,用于处理加载的包
import de.robv.android.xposed.callbacks.XC_LoadPackage // 包加载时的回调参数
import de.robv.android.xposed.XposedBridge // 提供日志输出等功能
import de.robv.android.xposed.XC_MethodReplacement // 用于替换目标方法的实现
import de.robv.android.xposed.XposedHelpers // 提供方法查找和 Hook 的辅助工具类

class HookEntry : IXposedHookLoadPackage { // 实现 Xposed 的主入口接口
    override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
        // 判断当前加载的包是否是我们要 Hook 的目标 App
        if (lpparam.packageName != "com.zj.wuaipojie") return // 如果不是目标包则直接返回,不做处理

        XposedBridge.log("程序开始执行") // 打日志,说明模块开始执行 hook 操作

        try {
            // Hook 目标类中的 isvip 方法,并替换它的返回值为 true
            XposedHelpers.findAndHookMethod(
                "com.zj.wuaipojie.ui.ChallengeSecond", // 要 hook 的类的完整类名(含包名)
                lpparam.classLoader,                   // 类加载器,用于加载目标类
                "isvip",                               // 要 hook 的方法名
                XC_MethodReplacement.returnConstant(true) // 替换方法,始终返回 true
            )
            XposedBridge.log("Hook isvip 成功") // Hook 成功的日志
        } catch (e: Throwable) {
            // 捕获异常并打印日志,便于调试
            XposedBridge.log("Hook isvip 失败: ${e.message}")
        }
    }
}

安装这个模块的方式也很简单,直接点击运行就可以了

需要注意的是,要勾选上这个,不然更新脚本很麻烦。

运行结果

通过执行可以看到,最后isvip被成功hook,而且在LSposed的应用中也能够看到输出的日志。

然后看到程序的结果也变了

免费评分

参与人数 22威望 +1 吾爱币 +40 热心值 +19 收起 理由
2623 + 1 我很赞同!
正己 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
hatetosay + 1 + 1 用心讨论,共获提升!
FchiyuT + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
张伯伦 + 1 + 1 用心讨论,共获提升!
sYn_ + 1 我很赞同!
hihopkc + 1 + 1 用心讨论,共获提升!
whereismy + 1 谢谢@Thanks!
z13678 + 2 + 1 我很赞同!
melooon + 1 + 1 我很赞同!
crizquan + 1 + 1 我很赞同!
风子09 + 1 + 1 用心讨论,共获提升!
allspark + 1 + 1 用心讨论,共获提升!
Liuzr + 1 + 1 谢谢@Thanks!
SDF521 + 1 + 1 谢谢@Thanks!
moo1s + 1 + 1 谢谢@Thanks!
oreges + 1 + 1 用心讨论,共获提升!
mobaixin + 1 + 1 谢谢@Thanks!
芽衣 + 1 + 1 用心讨论,共获提升!
Psyber + 1 谢谢@Thanks!
Atnil + 1 谢谢@Thanks!
金晓琴苑 + 1 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

来自 #
 楼主| Rytter 发表于 2025-5-6 11:19 |楼主
代码在这里:
通过网盘分享的文件:LSposedHook.zip
链接: https://pan.baidu.com/s/15qH0gaEgapH0DEahn5EWLA 提取码: y596

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
风子09 + 1 + 1 经过一晚测试,对于com.zj.wuaipojie 可以完成编译测试,修改代码后对于其 ...

查看全部评分

推荐
bfqn123 发表于 2025-5-11 15:40
多谢大神提供思路。我想搞清楚一点,民间入侵和国家政府网络安全工作人员入侵手法是否一致?
比如我拍了一张照片,民间黑客需要入侵我手机,然后再查看我的手机图片。但是要是这个入侵方有政府背景(如去感兴趣请参考《反有组织犯罪法》关于可能有国家机关工作人员参与有组织纠缠犯罪的描述),能调动国家级别的技术或者资源,比方说可以从我手机后台查到我的手机的信息,包括这张照片。
这两种入侵方式从技术上来说,手机日志或者其它手机特征是否有相同的体现?比如遭受民间入侵方入侵,设备记录有“Connecting to IP: 192.168.1.100 (unknown host) at [timestamp]”,显示手机与一个非本地网络中不熟悉的IP地址建立连接。或者有“Repeated connection attempts to 10.0.0.200 on port 8080”,表明手机在不断尝试连接到特定IP的某个端口,可能是攻击者在进行数据传输或控制指令的发送。
但是如果是这个入侵方是政府贪腐分子,借助了国家级别的技术,我的手机或者相关设备也有这样的显示吗?还是会显示别的内容?还是根本就会没有任何显示?
沙发
twl288 发表于 2025-5-5 06:43
3#
asmyy 发表于 2025-5-5 07:17
感谢分享,好好学习
4#
longlonghaha 发表于 2025-5-5 08:27
学到了   不错  感谢分享
5#
xiaoyudian 发表于 2025-5-5 08:53
谢谢分享
6#
fuchen520 发表于 2025-5-5 08:58
学习了!!!
7#
aizhen1984 发表于 2025-5-5 10:06
学习一下看看,感谢分享
8#
gaomeng0608 发表于 2025-5-5 10:10
通俗易懂,谢谢你的教程
9#
AlanDreamtrave 发表于 2025-5-5 10:31
感谢分享,好好学习
10#
Psyber 发表于 2025-5-5 11:25
非常棒的教程
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-5-19 23:02

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表