安卓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)中存储…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
