Pure Swift library for parsing binary XML files such as found in Android apk files.
Written from scratch and closely following the original C++ source code (ResourceTypes.h, ResourceTypes.cpp).
Names have been adapted to a more Swiftly syntax.
Import of Foundation is optional which should makes the library cross-platform compatible (though I have not tested other than macOS).
Since the AXML format is not documented anywhere – apart from the source code – you cannot rely on the structure to work forever.
Especially, pay attention to other binary XML formats which have been spotted on Android.
I do not think ABX is currently used for .apk files, only system files.
However, If that should change I would need to make some adjustments to this library.
let parser = try AndroidXML(path: "some/AndroidManifest.xml").parseXml()
print(try parser.xmlString())let xml = try! AndroidXML(data: [...]).parseXml()
try xml.iterElements({ startTag, attributes in
print("<\(startTag)>")
for (name, val) in try? attributes.asList() {
print("\t", name, "=", val.resolve(xml.stringPool))
}
}) { endTag in
print("</\(endTag)>")
}let lookupId = 0x7F100000
let xml = try! AndroidXML(path: "some/resources.arsc").parseTable()
let res = try! xml.getResource(TblTableRef(lookupId))!
let pkgPool = res.package.stringPool(for: .Keys)!
for x in res.entries {
let val = x.entry.value!
print(pkgPool.getString(x.entry.key), val.resolve(xml.stringPool), x.config.screenType.density)
}let xml = try AndroidXML(path: "some/resources.arsc").parseTable()
for pkg in try xml.getPackages() {
let pool = pkg.stringPool(for: .Keys)!
try pkg.iterTypes { spec, types in
//print("----- \(spec.id) ------")
for type in types {
try type.iterValues { idx, entry in
if entry.isComplex {
//print("::.::.complex", pool.getString(entry.key), entry.valueMap!.parent.asHex)
for x in entry.valueMap!.entries {
let _ = x.name.asHex
let _ = x.value.resolve(xml.stringPool)
}
} else {
let _ = pool.getString(entry.key)
let _ = entry.value!.resolve(xml.stringPool)
}
}
}
}
}There are a few places I could not properly test becaues none of my test files triggered the condition.
For example, handling dynamic attributes and dynamic references.
I've added some assert (ignored in release builds) to trigger as soon as a specific condition is met.
If you encounter a file, which triggers such a condition, reach out so I can finalize the library.