安卓xml乱码/加密转换:abx2xml和xml2abx使用及源码介绍
背景:
上一篇文章
android系统中data下的xml乱码无法查看问题剖析及解决方法
发布后,想要寻找一个可以直接把二进制xml和普通xml进行相互转换的,当时还写了相关的方案,但是当时没有找到现成的开源工具,后来经过相关粉丝提醒找到了和方法2一模一样思路的开源工具那就是abx2xml和xml2abx。
转化命令使用介绍abx2xml和xml2abx
转换前
属于二进制乱码
使用命令转换,命令:
abx2xml ./system/users/0/appwidgets.xml ./system/users/0/appwidgets-read.xml
转化后的./system/users/0/appwidgets-read.xml变成我们常见的普通xml
同样普通xml也可以转成二进制xml,转化命令
xml2abx ./system/users/0/appwidgets-read.xml ./system/users/0/appwidgets-binary.xml
然后看看./system/users/0/appwidgets-binary.xml是不是变得二进制不可读了
abx2xml和xml2abx命令解析
abx2xml和xml2abx其实代码都是一样的,本质就是个sh脚本而已,运行的
#!/system/bin/sh
export CLASSPATH=/system/framework/abx.jar
exec app_process /system/bin com.android.commands.abx.Abx "$0" "$@"
可以看出本质上都是调用到了Abx这个java类,参数就是一个$0,这个代表命令本身,比如使用使用是:
abx2xml input.xml output.xml
那么这里的 0 就是 a b x 2 x m l ,后面 i n p u t . x m l o u t p u t . x m l 就是 0就是abx2xml,后面input.xml output.xml就是 0就是abx2xml,后面input.xmloutput.xml就是@
源码剖析Abx类
public class Abx {private static final String USAGE = "" +"usage: abx2xml [-i] input [output]\n" +"usage: xml2abx [-i] input [output]\n\n" +"Converts between human-readable XML and Android Binary XML.\n\n" +"When invoked with the '-i' argument, the output of a successful conversion\n" +"will overwrite the original input file. Input can be '-' to use stdin, and\n" +"output can be '-' to use stdout.\n";private static InputStream openInput(String arg) throws IOException {if ("-".equals(arg)) {return System.in;} else {return new FileInputStream(arg);}}private static OutputStream openOutput(String arg) throws IOException {if ("-".equals(arg)) {return System.out;} else {return new FileOutputStream(arg);}}private static void mainInternal(String[] args) {if (args.length < 2) {throw new IllegalArgumentException("Missing arguments");}final XmlPullParser in;final XmlSerializer out;if (args[0].endsWith("abx2xml")) {//这里根据传递近来参数看看是否要二进制xml转普通还是逆过来转in = Xml.newBinaryPullParser(); //二进制转普通,那么输入就是BinaryPullParser,输出就是普通的out = Xml.newSerializer();} else if (args[0].endsWith("xml2abx")) {in = Xml.newPullParser();//普通转二进制,那么输入就是普通的,输出就是newBinarySerializerout = Xml.newBinarySerializer();} else {throw new IllegalArgumentException("Unsupported conversion");}final boolean inPlace = "-i".equals(args[1]);final String inputArg = inPlace ? args[2] : args[1];final String outputArg = inPlace ? args[2] + ".tmp" : args[2];try (InputStream is = openInput(inputArg);OutputStream os = openOutput(outputArg)) {in.setInput(is, StandardCharsets.UTF_8.name());//输入设置对应的流InputStreamout.setOutput(os, StandardCharsets.UTF_8.name());//输出设置对应的流OutputStreamout.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);Xml.copy(in, out);//再调用 Xml.copy,重点就是在这out.flush();} catch (Exception e) {// Clean up failed output before throwingif (inPlace) {new File(outputArg).delete();}throw new IllegalStateException(e);}// Successful in-place conversion of a file requires a renameif (inPlace) {if (!new File(outputArg).renameTo(new File(inputArg))) {throw new IllegalStateException("Failed rename");}}}public static void main(String[] args) {try {mainInternal(args);System.exit(0);} catch (Exception e) {System.err.println(e.toString());System.err.println();System.err.println(USAGE);System.exit(1);}}
}
上面代码核心部分有注释,其实整体算比较简单,核心方法就剩下一个Xml.copy方法
XML的相关copy方法如下:
/*** Copy the first XML document into the second document.* <p>* Implemented by reading all events from the given {@link XmlPullParser}* and writing them directly to the given {@link XmlSerializer}. This can be* useful for transparently converting between underlying wire protocols.** @hide*/public static void copy(@NonNull XmlPullParser in, @NonNull XmlSerializer out)throws XmlPullParserException, IOException {// Some parsers may have already consumed the event that starts the// document, so we manually emit that event here for consistencyif (in.getEventType() == XmlPullParser.START_DOCUMENT) {out.startDocument(in.getInputEncoding(), true);}while (true) {final int token = in.nextToken();//不断循环xml的内容节点等,简单说就是in读出什么就往out中写什么switch (token) {case XmlPullParser.START_DOCUMENT:out.startDocument(in.getInputEncoding(), true);break;case XmlPullParser.END_DOCUMENT:out.endDocument();return;case XmlPullParser.START_TAG:out.startTag(normalizeNamespace(in.getNamespace()), in.getName());for (int i = 0; i < in.getAttributeCount(); i++) {out.attribute(normalizeNamespace(in.getAttributeNamespace(i)),in.getAttributeName(i), in.getAttributeValue(i));}break;case XmlPullParser.END_TAG:out.endTag(normalizeNamespace(in.getNamespace()), in.getName());break;case XmlPullParser.TEXT:out.text(in.getText());break;case XmlPullParser.CDSECT:out.cdsect(in.getText());break;case XmlPullParser.ENTITY_REF:out.entityRef(in.getName());break;case XmlPullParser.IGNORABLE_WHITESPACE:out.ignorableWhitespace(in.getText());break;case XmlPullParser.PROCESSING_INSTRUCTION:out.processingInstruction(in.getText());break;case XmlPullParser.COMMENT:out.comment(in.getText());break;case XmlPullParser.DOCDECL:out.docdecl(in.getText());break;default:throw new IllegalStateException("Unknown token " + token);}}}
更多framework详细代码和资料参考如下链接
hal+perfetto+surfaceflinger
https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
其他课程七件套专题:
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw
视频试看:
https://www.bilibili.com/video/BV1wc41117L4/
更多framework假威风耗:androidframework007
相关文章:

安卓xml乱码/加密转换:abx2xml和xml2abx使用及源码介绍
背景: 上一篇文章 android系统中data下的xml乱码无法查看问题剖析及解决方法 发布后,想要寻找一个可以直接把二进制xml和普通xml进行相互转换的,当时还写了相关的方案,但是当时没有找到现成的开源工具,后来经过相关粉…...
slice 截取
JavaScript中的一个数组方法。然而,在Vue 3的应用开发中,slice 方法经常被用于处理数组数据,特别是在需要实现分页、数据截取或数据展示等场景时。 slice 方法的基本用法 slice() 方法返回一个新的数组对象,这一对象是一个由 be…...
XReparentWindow踩坑分析
X11是Linux发行系统中广泛采用的显示协议,各个系统基本上都支持XLib库,作为底层接口,XReparentWindow接口的功能就是重新设置父窗口,注意这个可以跨进程设置父窗口,例如将已经运行的进程的父窗口设置自己的程序Wid&…...
OpenAI动荡,将走向何方、GPT5或许将近、毒舌AI轻松破防网友、最新版 GPT-4o AI 模型得满分 | AGI视界周刊第 4 期
AI 视界周刊由战场小包维护,每周一更新,包含热点聚焦、应用破局、学术前沿、社区热议、智见交锋、跨界 AI、企业动态和争议 AI 八大板块,后续板块划分和内容撰写在周刊迭代过程中持续优化,欢迎大家提出建议。 欢迎大家来到《AI 视…...

RCE---无字母数字webshell
<?php if(isset($_GET[code])){$code $_GET[code];if(strlen($code)>35){die("Long.");}if(preg_match("/[A-Za-z0-9_$]/",$code)){die("NO.");}eval($code); }else{highlight_file(__FILE__); } 分析代码:传参不大于35&…...

有意思的漏洞复现与分析一
目录 一、Linux命令长度限制突破方法 1.在二进制漏洞利用中,某师傅遇到可控数据只有8字节的情况,去掉字符 串尾的\0,限制在7个字符。 一、Linux命令长度限制突破方法 1.在二进制漏洞利用中,某师傅遇到可控数据只有8字节的情况&a…...
力扣题解(按身高排序)
2418. 按身高排序 给你一个字符串数组 names ,和一个由 互不相同 的正整数组成的数组 heights 。两个数组的长度均为 n 。 对于每个下标 i,names[i] 和 heights[i] 表示第 i 个人的名字和身高。 请按身高 降序 顺序返回对应的名字数组 names 。 思路&…...
Redis的六种淘汰策略详解
Redis作为一种高性能的键值对存储系统,其数据全部存储在内存中,因此内存管理对Redis的性能至关重要。当Redis的内存使用达到上限时,就需要通过淘汰策略来释放内存空间,以便存储新的数据。Redis提供了六种不同的淘汰策略࿰…...

vue3中 ref 和 reactive 的区别
相同:均是声明响应式对象。且声明的响应式对象是深层的 1. 数据类型不同:ref用于包装JavaScript基本类型的数据(如字符串、数字、布尔值等),而reactive可以用于包装JavaScript对象和数组等复杂类型的数据。 2.访问方式…...
《单例模式的深度解读:实现方式、破坏情况与利弊权衡》
单例模式 一、单例模式的定义 单例模式(Singleton Pattern)是一种常见的软件设计模式,确保一个类只有一个实例存在,并提供一个全局访问点来获取该实例。 二、单例模式的实现方式 1.懒汉式单例 public class LazySingle…...

010607电压源和电流源受控源
电源的理论部分 1.6电压源和电流源1.理想电压源: 1.6电压源和电流源 1.理想电压源: 其两端电压总能保持定值或一定的时间函数,其值与流过它的电流i无关的元件叫理想电压源。 电路符号:中间与导线直通的圆圈 电压源:…...

快乐数求解
编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1,…...
运维高级内容--为端口做标记、制定调度规则
rs: yum install mod_ssl -y #安装mod_ssl模块 让rs支持https systemctl restart http lvs: cd /boot/ ls less config-5.14.0-427.13.1.el9_4.x86_64 ipvsadm -A -t 192.168.0.200:80 -s rr ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10:80 -g -w 1 #轮询调度一次…...

后端Web之HTTP协议基础介绍
目录 1.HTTP概念 2.HTTP请求协议 3.HTTP响应协议 4.HTTP协议解析 1.HTTP概念 HTTP(HyperText Transfer Protocol,超文本传输协议)是一种用于分布式、协作式和超媒体信息系统的应用层协议。它是万维网数据通信的基础,允许将超…...

深入解析Nginx限流策略:如何高效控制访问频率
摘要:本文将详细介绍Nginx限流模块的使用方法,包括基于IP地址的限流、基于并发连接的限流以及如何应对突发流量。通过实际案例,帮助读者掌握Nginx限流策略,确保服务器在高并发场景下的稳定运行。 一、引言 在高并发场景下&#x…...

锂电池剩余寿命预测 | Matlab基于Transformer-GRU的锂电池剩余寿命预测
目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab基于Transformer-GRU的锂电池剩余寿命预测,Transformer结合门控循环单元。 Matlab基于Transformer-GRU的锂电池剩余寿命预测(单变量) 运行环境Matlab2023b及以上。 首先从…...
深入理解Spring的IOC容器与依赖注入
深入理解Spring的IOC容器与依赖注入 引言 Spring框架的核心功能之一就是它的IOC容器,它为开发人员提供了强大的依赖管理和控制反转的能力。本文将详细介绍Spring的IOC容器以及依赖注入的基本概念和实现方式,并通过示例展示如何在实际项目中应用这些技术…...
Qt读写sysfs
本文介绍Qt读写sysfs。 在嵌入式Linux系统上开发Qt应用程序,经常会涉及到外设的控制,比如GPIO,PWM的控制,Linux环境下可以像操作文件一样操作它们,这通常会涉及到sysfs的读写。本文以读写GPIO为例,简要介绍…...

实景三维:解锁地理信息新维度,引领未来城市智慧之钥
在这个信息爆炸与科技日新月异的时代,地理信息与遥感技术正以前所未有的速度改变我们认知世界的方式。在推动“实景三维平台”这一前沿科技的构建上,它不仅是地理信息的立体呈现,更是智慧城市的基石,打开了通往未来城市规划、管理…...

汽车免拆诊断案例 | 2010款劳斯莱斯古斯特车中央信息显示屏提示传动系统故障
故障现象 一辆2010款劳斯莱斯古斯特车,搭载N74发动机,累计行驶里程约为11万km。车主反映,起动发动机后组合仪表和中央信息显示屏均提示传动系统故障。用故障检测仪检测,发现发动机控制模块2(DME2)中存储…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
JS红宝书笔记 - 3.3 变量
要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...