目录

充电学习中...

Tips 置顶! 有更新!

该文章已经加密。

浅谈安卓逆向工程-注入篇 置顶! 有更新!

浅谈安卓逆向工程-注入篇 写在前面 何为注入(Inject)? 不同于Spring框架中常常提到的依赖注入,逆向工程中的注入往往更贴合其原本的含义,即将代码注入到目标进程中去,这些被注入的代码可能用于分析、监控目标进程行为,同时也有可能被用于其他恶意目的。 本文将结合市面流行的注入工具框架,通过注入时机、方式、目标、范围等维度对Android平台的注入做一个更加全面的剖析。另外,需要说明的是,通过修改Rom重新编译镜像的方式进行代码注入只能适用于特定机型,一般很少用于生产阶段,因此本文将排除这种方式。 内核态的注入 与用户态的各种应用服务相比,内核态更接近设备的硬件层(HAL),配合驱动程序可以直接操作硬件,同时也往往拥有更高级别的权限。Android使用的是较老版本并且精简过的Linux内核,内核和Android系统是相互独立的,因此正确的内核刷写并不会影响Android系统的使用,但是由于不同机型使用的内核不尽相同,错误的刷机操作可能导致设备变砖,通用性较差,因此本文不讨论重新编译内核刷入的注入手段,而是着眼于从内核驱动角度进行注入。 二进制补丁+内核驱动 既然注入的宗旨即注入代....

如何把一台手机的屏幕投到另一台手机上 有更新!

如何把一台手机的屏幕投到另一台手机上 在PC上,我们可以用Scrcpy将手机的屏幕投屏过来,并且可以直接在PC上操作手机 而用手机控制手机,一般的做法是用一些远程工具(例如RustDesk、向日葵等)传输视频流,然后通过无障碍服务进行模拟操作,这种方式需要目标设备开启无障碍服务。 如果只需要传输视频流而不需要模拟操作,其实可以借助adb和scrcpy来完成,由于scrcpy并没有适配安卓arm64版本,所以我们需要自行对视频流进行解析,下图是这一方案的流程图,注意,这种方案下,控制端需要root权限 方案难点 控制端使用ADB Scrcpy的视频流传输在本地的localabstract,需要通过adb将此端口转发出来,这在作为控制端的安卓设备上并不容易实现 被控端ADB授权 使用OTG线连接两台设备时,可以像PC一样对设备进行手动授权。而使用无线方式连接,需要确保wifi ADB开启,同时也需要授权 视频流解析 Scrcpy的视频流基于screenrecord获取,而screenrecord传输的并非是标准协议的视频,而是H264视频裸流,需要自己解析视频数据播放 效果展示 流程 被控....

安卓开机自启动方案----基于Magisk

安卓开机自启动方案----基于Magisk 一、需求描述 本文的开机自启动应用场景并非普通的安卓APP启动,主要的目标是在设备启动时执行shell脚本,并使用frida-inject进行frida脚本注入动作。在通常的情况下,开机启动某个app可以通过安卓的广播功能来进行,但是此方式并不能确保成功启动,在锁屏情况下也可能导致失败,并且对于有些国内深度定制的安卓系统是完全无效的。 二、Init.d尝试 起初,由于我们的场景是拥有root权限的,笔者打算通过激活安卓的Init.d来实现需求。大致的流程如下: 安装环境(busybox)-激活init.d-复制shell脚本到指定目录 这套方案在经过一番尝试后被我放弃了,原因如下: 部署繁琐,需要安装busybox并激活init.d,这一步骤实现完全自动话有些麻烦,当大规模批量部署时,耗时会大大增加 不能够适配所有安卓设备或系统,比如我用的测试机器红米Note3 MIUI9就失败了 三、使用Magisk实现 刷入Magisk,刷入方法可以见此文章,如果不需要xposed功能可以不刷EdXposed,本文中我们只将Magisk用于自启动,所以不....

修改IP地址,看这一篇就够了! 有更新!

前言 本文将介绍各个平台下,通过软硬件方式修改IP的各种思路和方法,基本涵盖了所有使用场景和需求,如果你正在找相关的内容,那一定可以帮到你! 本文探讨的是修改出口IP,即公网IP,而内网IP的修改不在本文的探讨范围 基本思路 实现修改IP的方式有很多,但是其底层逻辑可以分成两类: 1.直接修改 正如解决“如何将一头大象放入冰箱”一样,改IP本身就有一些简单粗暴的解决方式,以手机为例,先打开再关闭手机的飞行模式可能就能得到一个不同的出口IP,不过这一过程并不可控,无法保证每一次都能出现预期的结果 2.使用代理 使用代理往往是更好的实现方式,顾名思义,使用代理,可以让代理服务器处理原本从自身IP发出的请求,从而实现修改出口IP,这也是目前最主流的方法 直接修改 比起“直接修改”的说法,其实更好的描述方式是“让上游重新为设备分配IP” PC端 PC环境下,可以使用拨号方式更改出口IP,前提是使用拨号上网的方式,每次重新拨号,就可以得到一个同一网段的新IP,这也是市面上的VPS不能用作公网服务器的原因,因为IP会动态变化 ADSL拨号的的代码可以参考这个项目 事实上,移动设备本身也可以拨号,只....

安卓内核定制开发笔记(一)内核源码编译 有更新!

安卓内核定制开发笔记(一)内核源码编译 注意:本文默认读者知晓刷机风险,并且熟练进行刷机操作 测试设备:一加3T 安卓P 测试系统:Ubuntu 20.04 先放上前后对比图,如下图内核版本名称从3.18.120-perf+变为了3.18.120-perf+cube 刷内核前: 刷内核后: 一、环境准备 1.安装依赖 apt install git gnupg flex bison gperf build-essential zip curl zlib1g-dev libc6-dev-i386 x11proto-core-dev libx11-dev libgl1-mesa-dev libxml2-utils xsltproc unzip bc gcc-aarch64-linux-gnu 2.安装交叉编译工具链 git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 根据需要迁出分支 git checkout -B an....

安卓内核定制开发笔记(三)系统调用Hook 有更新!

安卓内核定制开发笔记(三)系统调用Hook 在上一篇文章中,我们已经探讨了对系统调用的简单Hook,但是在实际应用中,只是监控系统调用的出入参是无法满足需求的,我们预期得到一个类似于inline hook的功能,也就是在hook到调用的同时,可以对出入参进行修改。这一功能在用户态非常容易实现,与正向开发无异,但是内核态由于各种保护机制,无法直接修改用户态的内存,导致这一实现有些麻烦,可以参考看雪文章[原创]内核层偷天换日之hook openat进行文件重定向-Android安全-看雪-安全社区|安全招聘|kanxue.com 我们可以看到内核代码中对openat调用号的声明 int openat(int dirfd, const char __user *pathname, int flags, umode_t modex) 可以看到,关键的路径入参被const和__user修饰,这代表这是一个用户态的常量,而内核模块工作在内核态,与用户态是隔离的,内核策略也限制了内核态和用户态内存的互相访问,所以内核模块是无法直接修改这个参数的。 解决方案 为了解决这一问题,我们需要使用内核提供的....

安卓内核定制开发笔记(二)系统调用拦截 有更新!

安卓内核定制开发笔记(二)系统拦截 在第一篇文章中,我们已经已一加3T为例,尝试编译和刷入了官方内核,并且解决的一些驱动问题,接下来我们将在此基础上去实现对系统调用的Hook,以openat为例 Hook原理 系统调用是内核开放给用户态的"接口",而各个系统调用的地址被保存在系统调用表(sys_call_table)中,所以只需要修改对应调用号(例如openat)在系统调用表中的地址就可以实现对系统调用的hook了 开发流程 1.获取sys_call_table地址 方法一: 在内核编译页面,找到System.map,里面保存了编译后的符号地址,可以在内核编译输出目录直接执行以下命令 cat System.map |grep "sys_call_table" 方法二: 动态获取,内核版本4.4以下可以用 // 内核4.4以下可以用 static void getsyscall_table(void) { unsigned long *syscall_table; unsigned long int i; for (i = (unsigned long int)sys_close; i....

拆解QtScrcpy的熄屏控制功能 有更新!

QtScrcpy 是一款优秀的安卓投屏开源软件,其投屏效果接近于直接在PC上使用模拟器,但是本文的关注点在于其一个相对冷门的功能----关闭屏幕 不同于下面的电源键按钮,关闭屏幕只会熄灭手机屏幕而不会真的锁屏,众所周知手机的屏幕几乎是耗电最高的硬件,那么当设备需要长时间运行时,熄灭屏幕可以延长设备寿命、减少设备散热(更重要的是,屏幕内容将无法被直接看到)。 那么,这是如何实现的呢?起初我以为这是adb原本就支持的功能,但是翻遍了adb的手册也只能找到模拟电源键,即只能实现真锁屏。那就只能去查阅QtScrcpy源码了,顺便也去了解了一下QtScrcpy的工作原理。 QtScrcpy熄屏实现 QtScrcpy实现代码如下 本质上是调用了安卓android.view.SurfaceControl类的setDisplayPowerMode方法来实现,而调用这个方法,需要ACCESS_SURFACE_FLINGER权限,但权限又只有系统app才能申请,那么QtScrcpy是如何解决的呢?答案就是利用adb权限,QtScrcpy会先将scrcpy-server(在源码中是个安卓项目,有main....

Xposed用于生产部署实践 有更新!

Xposed用于生产部署实践 一、需求说明 在调试阶段,Frida肯定是比Xposed方便很多,虽然网上也有Xposed的免重启版本,但是始终是要重新安装apk,重新打开目标hookapp。而frida则无需重启,将js注入即可,除此之外还有可以swap启动,so层hook等优点。 但是到了生产阶段,Xposed会比Frida更方便,更稳定,原因在于Frida如果要脱离PC运行,一般的做法是使用frida-inject,但是往往不能满足需求,因为常见的场景即为注入hook脚本到指定app,然后外部调用app的加密算法,而原生的js对此支持并不完善。如果不脱离PC,则就需要通过RPC来调用,涉及到手机和PC两台设备,稳定性降低。而Xposed则可以完全脱离PC运行,只需要在安卓端起一个http服务,然后配置端口转发即可使用。 二、构建及部署过程 1.Xposed环境安装 在手机或PC上安装Xposed框架,这一步不再赘述,目前XposedBridge最新版本为89 2.编写测试Xposed hook插件 可以先用frida调试完毕,然后再移植到xposed上,由于我们的需求是调用,而不是....

Ubuntu20.4编译AOSP源码实践 有更新!

Ubuntu20.4编译AOSP源码实践 本文记录使用Ubuntu20.4编译AOSP的过程以及一些错误解决,使用的编译的分支为 android-8.1.0_r38 参考清华大学开源软件站构建代码仓库,本文采用repo同步的方式进行构建,构建的操作系统是Ubuntu20.4 一.Ubuntu虚拟机配置 主要关注内存和磁盘大小,本文中我分配了8G内存和200G的磁盘空间 二.依赖库安装 需要安装java环境、官方给定的环境依赖,ubuntu20.4自带python环境,如果没有需自行安装,用到的命令如下 # 环境安装 echo "更新apt-get" sudo apt-get update echo "安装jdk8" yes | sudo apt-get install openjdk-8-jdk echo "安装python2" yes | sudo apt-get install python echo "安装curl" yes | sudo apt-get install curl echo "安装git" yes | sudo apt-get install git echo "....

Art下Xposed解析整理 有更新!

Art下Xposed解析整理 Xposed主要实现两大功能,即注入和Hook,本文将主要分析整理Xposed框架从安装到使用一些关键实现 一、项目介绍 1.XposedInstaller 用于Xposed框架及模块的管理工作,最终产物即是我们看到的Xposed安装器应用 2.Xposed 本质上是Xposed版的zygote(孵化器),由XposedInstaller来将原生的zygote进行替换,从而达到注入的目的 3.XposedBridge 此项目产物即XposedBridge.jar,也就是Xposed待注入的jar包,编写Xposed模块时使用到的一些类如XposedHelpers、XposedBridge都在这里 4.android_art 此项目编译编译生成需要替换的系统so库例如libart.so 二、安装过程 详细的安装过程不是本文关注的重点,本文只探讨一些关键部分 在XposedInstall中点击Install将会下载Xposed需要的zip包,jar包内容物如下图(图片来自珍惜Any博客) 在"flash-script.sh"中,我们可以看到该脚本对于下载的z....

Xcubebase_Riru打包部署实践(过反调试、Frida持久化) 有更新!

Xcubebase_Riru打包部署实践(过反调试、Frida持久化) 一、需求起因 在研究某加壳APP时,发现其做了反调试,无法直接使用frida。使用adb shell查看包名下的进行列表,并结合加固壳特征发现,此app的壳使用了双进程保护,主线程已经被子进程ptrace,并且检测到子进程关闭后,主进程也会自动关闭。由于需求是只需要对其做hook分析即可,经过搜索找到一个曲线救国的方案。 简单来说,此方案的原理即是利用Magisk模块Riru,将frida-gumjs注入到孵化器进程,以达到hook的目的,由于没有调试行为,所以也不会受到反调试的影响 二、打包Xcubebases_riru 此处先介绍xcubebase_riru模块的build,主要的坑都在这里 作者的git项目使用的是版本为10的Riru,而目前最新版本已经到了25,经过测试,直接将此项目clone下来是无法build的,我的做法是参照Riru Demo项目的设置,将Riru的版本升级到25 下面是需要改动的地方 1.gradle文件名 将项目根目录的module.example.gradle文件名修改为modu....

使用frida-gumjs将sekiro注入到任意app进程 有更新!

使用frida-gumjs将sekiro注入到任意app进程 在之前的文章中,我们讨论了原生环境下,使用NPS和Sekiro在黑盒调用场景下的一些差别和优劣,其中提到Sekiro相比于NPS,对目标应用的代码有入侵性,在实际应用时,如果要向目标app进程注入sekiro,常用的途径一般是利用xposed模块,除此之外可能就需要解包添加代码。而本文重点介绍这一需求的另一种实现方式,即先将Sekiro打包成dex文件,然后通过Frida进行载入。当然,在这之前我们需要先将Frida进行持久化,实现的方式有两中,一是使用frida-inject实现脱离pc环境运行,二是借助Magisk的Riru模块将frida-gumjs引擎注入孵化器。由于第一种方案需要执行shell命令来启动app,因此我们暂不考虑。第二种实现方式见文章。 1.将Sekiro打包成Dex文件 这一步骤我们直接用Android Studio实现,新建一个空白的安卓项目,然后引入Sekiro库,如下 implementation 'com.virjar.sekiro.business:sekiro-business-api:....

使用Clash+NPS将安卓设备作为代理服务器 有更新!

使用Clash+NPS将安卓设备作为代理服务器 出于IP真实性、稳定性的需求,需要将手机4G网络的IP作为代理IP进行访问,本文整理了使用Clash+NPS进行部署搭建的过程。 一、资料准备 NPS安卓客户端 Clash安卓客户端 Clash空白配置文件(设置直连即可) NPS后端(本文默认已提供后端,若没有后端则需要先部署) 将NPS、Clash客户端安装到安卓设备,再将配置文件推送到手机存储 二、NPS安卓客户端部署 1.NPS后端创建客户端 在nps管理后台创建新客户端,如下图 密钥可以自己设置,也可以自动生成,保持唯一即可 2.NPS安卓客户端连接 如下图,填入正确的ip(域名):端口号、密钥,选择tcp模式,再点击start即可。启动后观察日志输出为succeed并且nps后端显示此客户端为在线状态表示连接成功。 3.创建代理转发规则 在NPS后端控制台中添加tcp隧道,将客户端的7890端口转发到服务端端口中,clash局域网访问端口默认为7890,可以根据需要自行修改。成功后如下图 三、Clash配置 运行Clash,在配置选项中,选择从文件导入配置,找到前面推....

NPS和Sekiro两种方式实现内网服务暴露的异同比较 有更新!

黑盒调用场景下NPS和Sekiro的异同比较   前段时间一直在思考NPS和Sekiro之间的异同点以及适用的场景,其实关于这个问题Sekiro的作者已经给出了很多观点,本文将从我自己的使用经验出发,整理总结一些我自己的想法 1.NPS   用原作者的话说,这是"一款轻量级、高性能、功能强大的内网穿透代理服务器",举个例子来说,利用NPS,你可以将本地环境的服务暴露到公网环境,以达到可以通过域名或者公网ip访问的目的。当然,单纯的服务暴露将带来一系列安全隐患,为了解决这一问题,NPS也提供了例如白名单,身份验证等一系列功能。例如本博客基于solo,而solo部署在家里的树莓派中,利用NPS实现了通过域名进行访问。   从我的使用经验来看,NPS最大的优点在于对项目的代码做到0侵入性,调用方和被穿透的目标是没有任何感知的,同时NPS也没有任何的语言依赖,只要目标项目使用的协议在NPS的支持范围内就都能够使用,而NPS已经支持了大多数流行的协议,例如tcp、udp、http(s)、p2p等。   关于缺点,Sekiro作者的观点集中在两点,第一点是NPS对于客户端的状态没有更加细致的感知,....

安卓开机自启动方案 有更新!

安卓开机自启动方案----基于Magisk 一、需求描述 本文的开机自启动应用场景并非普通的安卓APP启动,主要的目标是在设备启动时执行shell脚本,并使用frida-inject进行frida脚本注入动作。在通常的情况下,开机启动某个app可以通过安卓的广播功能来进行,但是此方式并不能确保成功启动,在锁屏情况下也可能导致失败,并且对于有些国内深度定制的安卓系统是完全无效的。 二、Init.d尝试 起初,由于我们的场景是拥有root权限的,笔者打算通过激活安卓的Init.d来实现需求。大致的流程如下: 安装环境(busybox)-激活init.d-复制shell脚本到指定目录 这套方案在经过一番尝试后被我放弃了,原因如下: 部署繁琐,需要安装busybox并激活init.d,这一步骤实现完全自动话有些麻烦,当大规模批量部署时,耗时会大大增加 不能够适配所有安卓设备或系统,比如我用的测试机器红米Note3 MIUI9就失败了 三、使用Magisk实现 刷入Magisk,刷入方法可以见此文章,如果不需要xposed功能可以不刷EdXposed,本文中我们只将Magisk用于自启动,所....

Frida用于生产部署实践 有更新!

Frida用于生产部署实践----续作(Frida-Inject) 此文为这篇文章的续作,在前文中,生产部署时除了手机外,还要有一台另外的设备用于rpc交互(前文用的是树莓派)。在本文中,我们将使用frida-inject去实现满足生产需要的部署。 一、准备工作 安卓设备 真机或模拟器都可,需要root权限 frida-inject模块 用于hook的 js脚本 目标app 没错,只需要上述资源即可完成,成功部署之后可以完全脱离PC去使用。 二、开始部署 将frida-inject和js脚本推送到手机,例如/data/local/tmp目录中 frida-inject下载地址,注意不要下错了,根据自己设备的cpu架构选择对应的版本,如下图,我的设备是arm64架构的,就是下图圈出来这个。下载完之后先解压,里面的文件才是我们需要的,这一点和frida-server相同,熟悉frida 的朋友应该不会搞错。 接着给frida-inject和js脚本赋予可执行权限,即: //frida inject模块 chmod 777 frida-injetmodule //xxx.js为你的js....

安卓10安装EdXposed步骤

安卓10安装EdXposed步骤 高版本的安卓已经无法安装原生xposed了,但是可以通过面具刷入,本文以MIUI11 稳定版为例,记录一下刷入过程。 一、资料准备 twrp(用于刷入第三方recovery) 本文提供 MIUI机型的 twrp,其他机型请自行寻找: 链接https://pan.baidu.com/s/18VVTLZuDUAp5vA29yjYn4w 提取码:yxbz Magisk Manager管理apk *Magisk 刷机包 *Riru-Core 刷机包 *Riru-EdXposed刷机包 EdXposed Manager 管理apk 注意:部分机型需要先解BL锁。twrp用于刷入第三方recovery和Magisk,*部分表示此部分可以在线安装。 二、刷twrp MIUI 可以用网盘中的一键刷入工具刷入,其他机型需要找到自己对应版本的twrp,然后用fastboot刷入 三、安装 Magisk 有两种方式 1.在线安装 安装 Magisk Manager后,在管理app中在线下载并刷入 2.离线刷入 下载Magisk刷机包(资料3),推送到手机目录,例如s....

Frida用于生产部署实践

树莓派部署Frida实践 一、需求起因 越来越多的APP签名加密算法放在了so层,而逆向so文件拿到算法往往是不容易的,为了满足某些场景下的需求,考虑将Frida用于生产环境。具体的系统结构如下: 由于需要一台7*24小时提供服务的设备来部署python脚本,此处采用了树莓派(Ubuntu 18)。 二、安卓端Frida Server部署 见文章 三、树莓派环境搭建 1.安装adb sudo apt-get install android-tools-adb 2.安装python3、pip 如果已经有了python3环境忽略即可,pip同理 sudo apt-get install python3.8 sudo apt install python3-pip 由于系统默认的python版本是2.7,所以后续使用命令时用python3、pip3代替的python、pip 3.安装frida pip3 install frida-tools pip3 install frida 四、测试frida是否安装成功 frida从14版本之后开始支持amd64架构的linux系统,写此文章....