首页 > 其他分享 >Android修改应用列表的失败学习

Android修改应用列表的失败学习

时间:2024-04-15 19:45:36浏览次数:28  
标签:XPosed zygote 列表 修改 adb Android root Magisk native

没什么实用价值,一种记叙文和学习笔记的结合体。


 0.

回老家收到新需求:能不能处理一下这台旧手机,让我在家打上单位的钉钉打卡?

旧手机型号华为荣耀7i,安卓版本4.0.3。看到华为两个字,我仿佛看到了我失败的未来。

1. 

首先想到的必然是虚拟定位。但钉钉显然会防范这种方法。搜索资料得钉钉似乎会扫描应用列表检测相关软件;如果禁止它读取应用列表,它也会不让你打卡。接下来的问题是如何返回给它一份假的应用列表。

第二个方法是安装远程操控,但钉钉也会检测远程操控软件比如向日葵。以及远程操控手机不如远程操控同事,下一个。

第三个方法是定时任务。写一个或者下一个定时任务程序,每天到点进入钉钉打个卡。听上去不太保险。或许可以和第二个结合一下,远程发送一条命令然后自动打卡,但回家这几天显然不够我从零写一个程序装上。

2.

于是开始研究第一个方案。既然要返回给它一份假的应用列表,那么应该要涉及到hook和root。一个广泛能搜到的方案是Magisk+LPosed+Hide My AppList。于是开始研究第一步,怎么装Magisk。事实上LPosed已经要求安卓版本8.1+,但当时没有发现。版本的阴影将伴随接下来几个小时。

打开Magisk官网的安装教程,很详细,大喜。阅读一番决定先装一个adb。遥想上次用adb还是上次。adb装起来很容易,先adb devices看看设备有没有连接上,没找到。于是点七次版本号打开开发者模式,打开usb调试,好连上了。adb push一个文件,好这根诺基亚的数据线和华为还挺适配,还有传数据功能,继续下一步,找.img文件。

这里找到了对应版本的卡刷包,虽然要三块钱,就当交学费了。然后下了HuaweiUpdateExtractor把UPDATE.APP里面的BOOT.img提取出来。把Magisk安装包和boot一起adb push到手机里,修复boot,然后adb pull把修复好的文件下载回电脑,开始fastboot。

fastboot flash boot $path_to _boot.img

失败了。想起手机的bl锁还没解。华为解bl锁要解锁码,但解锁码17还是18年官方就不再提供了。如果绕过解锁码需要root,但我root需要解锁码(bushi

安卓在5.0进行了一次大更新,修复了很多漏洞。所以这个4.0的手机理论上可以尝试各种root工具。但是要回退各种版本各种试,为什么不试试万能的某宝呢。打开橘色软件,问第一家做不了,第二家能搞,装了远程控制软件,大喜,准备观察学习。店家接管电脑后又装了个usb redirector,直接导过去,啥都看不到,败兴而归。过了一会把解锁码发过来了,收费五元,也行吧。

然后继续刷机,很快啊,嗡的一下,重启了。Magisk还是没装好。又试了一次,感觉不太对劲,一看Magisk 24.0有点太先进了,只能装22.0。于是装了22.0,发现Lposed刷不进去,寄。

3.

虽然已经失败了但决定学习一下,一会Magisk一会Lposed一会riru有点晕,闲着没事就是除了毕设什么都可以学一学。先从最开始的hook技术看吧。

4.

hook,就是执行过程中拦截将要执行的函数,让它运行自己写的函数。有点像override。学了一点点,大概是在程序运行前加载自己的程序进行替换,比如利用java反射,JNI重定向达到这个目的。

盘点Android常用Hook技术

这里提到了XPosed,XPosed已经停止维护了。LPosed是基于XPosed的一个分支,可以用在后面的系统上。XPosed通过修改zygote进程,也就是fork所有进程的进程,来在程序运行前执行自己的插件。fork出来的进程具备父进程的资源,也就包含了XPosed的修改。

在Android使用Dalvik虚拟机的时候,因为采用JIT即时编译,所以方案是将hook目标方法设定为一个native方法,然后绑定自己的方法上去。到了ART也就是Android5.0之后,因为JIT太慢,ART选择了预编译,意味着等到创建新进程出来再动手脚已经太晚了,XPosed选择重新编译 libart.so,ART的动态库,使得我们可以直接修改一个方法对应的汇编地址,然后跳转执行自己的方法。

可以看出XPosed会平等地在每个进程都进行注入,让应用启动变慢。LPosed可以指定目标app,改良了这一点。

5. 

既然要修改zygote,那么接下来研究一下zygisk或者riru是怎么做到的。由于Magisk先用的riru,那么就先看riru。一开始riru选择替换了一个zygote会用到的系统库。刚看到的时候没理解,因为一直在想改zygote代码的事。但注入讲究一个不能改别人的的东西,所以只能对它会用到的资源下手了。后来riru发现除了zygote也有别的进程会用到这个库,从而导致一些错误,于是在riru22中换了“原生桥接”的方法,源于通过系统的native bridge实现注入zygote

这个方法里提到了so库,.so类似Windows下的.dll,但要适配不同的手机CPU架构,不同架构生成不同.so文件。而native bridge可以把一种架构下的代码换成另一种。在加载zygote对应的可执行文件app_process的时候又会用到native bridge,而native bridge有什么特点呢,它会调用dlopen,dlopen将打开一个新库,并把它装入内存,我猜dlopen意思就是dll open。接下来的事虽然没有看懂但原文说得很明白:

dlopen会执行目标库的.init_array中的所有函数,而让自己的函数进入.init_array实际上只需要声明__attribute__((constructor))就好了,完全没有难度啊!

总之是一些C或者C++的一些特性。现在我们应该找到它dlopen的库,也就是runtime_options.ReleaseOrDefault(Opt::NativeBridge),然后把自己的代码放进去。这个库叫ro.dalvik.vm.native.bridge,好现在编译一个自己的函数,加上__attribute__((constructor)),把名字改成ro.dalvik.vm.native.bridge放进去,目标达到了。虽然会产生一些问题但接下来看原文就好了,作者不仅很牛能想到这些办法,文章还写得非常丝滑,喜欢!

6.

接下来应该看看zygisk的,但zygisk的意思是Magisk注入zygote的方案。所以先看看Magisk。

Magisk的用处是获取root权限。先了解一下一般如何获取root权限。假设这是一个普通的linux系统,我们输入su和密码,就可以拿到root权限。如果我们试图对Android做同样的事情,会显示没有su这个文件。实际上Android里也是有这个命令的,但它不对手机用户开放,怕你把手机整成砖。那么接下来就是找到su程序,把它的路径放到环境变量里。

之前装Magisk的时候是下载了一个boot.img修复完刷进去。Magisk通过处理boot.img,替换系统init过程为自己的magiskinit,在里面加载修改系统的各种模块,更具体的过程可以看这里;同时,Magisk可以看作一个文件系统挂载在/sbin上,这里面有su,也就能root了。之前看说systemless的意思是不修改system分区而达到root的目的,困惑了半天,后来发现mount --bind a b的意思是,操作后访问b,访问到的实际上是a。那确实是没改变system哈。

突然发现上面两个链接是同一个作者的,膜了。

那么zygisk也可以同理类比得它是替换了app_process实现的劫持zygote。

7.

最终成果:吃了三天家里好吃的饭,香!

标签:XPosed,zygote,列表,修改,adb,Android,root,Magisk,native
From: https://www.cnblogs.com/capterlliar/p/18111497

相关文章

  • Android Studio制作简单登录界面
    实现目标应用线性布局设计登录界面,要求点击输入学号时弹出数字键盘界面,点击输入密码时弹出字母键盘,出现的文字、数字、尺寸等全部在values文件夹下相应.xml文件中设置好,使用时直接引用。当用户名或密码为空,显示一个提示信息“用户名与密码不能为空!”,当用户名和密码匹配,显示“登录......
  • 浏览器 自带打印调用以及样式修改与调试
    1.代码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>print</title></......
  • Android 11--设置第三方Launcher并默认 与 如何预置apk
    1.0Ver/frameworks/base/core/java/com/android/internal/app/ResolverActivity.java+privatevoidsetDefaultLauncher(){+try{+finalPackageManagerpm=getPackageManager();++//StringdefPackageName="com.android......
  • day 06-2 数据类型(列表)
    1.3公共功能1.相加,两个列表相加获取一个新的列表data=["张译","冯绍峰"]+["赵又廷","林更新"]print(data)#['张译','冯绍峰','赵又廷','林更新']v1=["赵又廷","林更新"]v2=["张译","冯......
  • day 06-3 数据类型(列表)
    1.6阶段作业1.写代码,有如下列表,按照要求实现每一个功能li=["linzai",'asff','wftthyy','kihfng',"张三四"]#计算列表的长度并输出data=len(li)#print(len(li))print(data)#5#列表中追加元素"seven"#列表中追加元素"seven",并输出添......
  • IDEA中Maven项目修改JSP后通过配置Tomcat实现立即生效
    参考:IDEA中Facets和Artifacts配置说明idea中artifacts、facets、modulesIntelliJIDEA部署Web项目,终于搞懂了传统SpringMvc项目目录和对应tomcat配置如下:在日常开发过程中,我们修改完java代码后,接着就点击Build编译,然后就可以去验证代码了(前提是On'Update'Action选......
  • ansible 修改密码
    hosts[centos-root]192.168.174.129ansible_ssh_port=22192.168.174.130ansible_ssh_port=22192.168.174.131ansible_ssh_port=22AnsibleVault文件创建AnsibleVault文件#ansible-vaultcreatepasswords.ymlNewVaultpassword:#123456......
  • android http post
    android httppost  privatevoidsendLocationToServer(doublelatitude,doublelongitude){StringtagID="xcvxczvxzvcxz";Stringname="";Stringbiaoduan="";Stringtype1="";......
  • Android 11 导航栏添加一个虚拟按钮--问题合集
    导航栏添加一个虚拟按钮按钮功能:显示隐藏导航栏1.frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.javaprotectedStringgetDefaultLayout(){finalintdefaultResource=QuickStepContract.isGesturalMode(mN......
  • 主页修改前存档
    1.html:<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>AI服务平台</title><l......