Documentation
¶
Overview ¶
Package apkparser parses AndroidManifest.xml and resources.arsc from Android APKs.
Example ¶
package main import ( "encoding/xml" "fmt" "github.com/avast/apkparser" "os" ) func main() { enc := xml.NewEncoder(os.Stdout) enc.Indent("", "\t") zipErr, resErr, manErr := apkparser.ParseApk(os.Args[1], enc) if zipErr != nil { fmt.Fprintf(os.Stderr, "Failed to open the APK: %s", zipErr.Error()) os.Exit(1) return } if resErr != nil { fmt.Fprintf(os.Stderr, "Failed to parse resources: %s", resErr.Error()) } if manErr != nil { fmt.Fprintf(os.Stderr, "Failed to parse AndroidManifest.xml: %s", manErr.Error()) os.Exit(1) return } fmt.Println() }
Output:
Index ¶
- Constants
- Variables
- func ParseApk(path string, encoder ManifestEncoder) (zipErr, resourcesErr, manifestErr error)
- func ParseApkReader(r io.ReadSeeker, encoder ManifestEncoder) (zipErr, resourcesErr, manifestErr error)
- func ParseApkWithZip(zip *ZipReader, encoder ManifestEncoder) (resourcesErr, manifestErr error)
- func ParseManifest(r io.Reader, enc ManifestEncoder, resources *ResourceTable) errordeprecated
- func ParseXml(r io.Reader, enc ManifestEncoder, resources *ResourceTable) error
- type ApkParser
- type AttrType
- type ManifestEncoder
- type ResAttr
- type ResValue
- type ResourceConfigOption
- type ResourceEntry
- type ResourceTable
- func (x *ResourceTable) GetIconPng(resId uint32) (*ResourceEntry, error)
- func (x *ResourceTable) GetResourceEntry(resId uint32) (*ResourceEntry, error)
- func (x *ResourceTable) GetResourceEntryEx(resId uint32, config ResourceConfigOption) (*ResourceEntry, error)
- func (x *ResourceTable) GetResourceName(resId uint32) (string, error)
- type ResourceValue
- type ZipReader
- type ZipReaderFile
Examples ¶
Constants ¶
const ( AttrTypeNull AttrType = 0x00 AttrTypeReference = 0x01 AttrTypeAttribute = 0x02 AttrTypeString = 0x03 AttrTypeFloat = 0x04 AttrTypeIntDec = 0x10 AttrTypeIntHex = 0x11 AttrTypeIntBool = 0x12 AttrTypeIntColorArgb8 = 0x1c AttrTypeIntColorRgb8 = 0x1d AttrTypeIntColorArgb4 = 0x1e AttrTypeIntColorRgb4 = 0x1f )
Variables ¶
var ErrEndParsing = errors.New("end manifest parsing")
Return this error from EncodeToken to tell apkparser to finish parsing, to be used when you found the value you care about and don't need the rest.
var ErrPlainTextManifest = errors.New("xml is in plaintext, binary form expected")
Some samples have manifest in plaintext, this is an error. 2c882a2376034ed401be082a42a21f0ac837689e7d3ab6be0afb82f44ca0b859
var ErrUnknownResourceDataType = errors.New("Unknown resource data type")
Functions ¶
func ParseApk ¶
func ParseApk(path string, encoder ManifestEncoder) (zipErr, resourcesErr, manifestErr error)
Calls ParseApkReader
func ParseApkReader ¶
func ParseApkReader(r io.ReadSeeker, encoder ManifestEncoder) (zipErr, resourcesErr, manifestErr error)
Parse APK's Manifest, including resolving refences to resource values. encoder expects an XML encoder instance, like Encoder from encoding/xml package.
zipErr != nil means the APK couldn't be opened. The manifest will be parsed even when resourcesErr != nil, just without reference resolving.
func ParseApkWithZip ¶
func ParseApkWithZip(zip *ZipReader, encoder ManifestEncoder) (resourcesErr, manifestErr error)
Parse APK's Manifest, including resolving refences to resource values. encoder expects an XML encoder instance, like Encoder from encoding/xml package.
Use this if you already opened the zip with OpenZip or OpenZipReader before. This method will not Close() the zip.
The manifest will be parsed even when resourcesErr != nil, just without reference resolving.
func ParseManifest
deprecated
func ParseManifest(r io.Reader, enc ManifestEncoder, resources *ResourceTable) error
Deprecated: just calls ParseXML
func ParseXml ¶
func ParseXml(r io.Reader, enc ManifestEncoder, resources *ResourceTable) error
Parse the binary Xml format. The resources are optional and can be nil.
Types ¶
type ApkParser ¶
type ApkParser struct {
// contains filtered or unexported fields
}
func NewParser ¶
func NewParser(zip *ZipReader, encoder ManifestEncoder) (parser *ApkParser, resourcesErr error)
Prepare the ApkParser instance, load resources if possible. encoder expects an XML encoder instance, like Encoder from encoding/xml package.
This method will not Close() the zip, you are still the owner.
type ManifestEncoder ¶
Encoder for writing the XML data. For example Encoder from encoding/xml matches this interface.
type ResourceConfigOption ¶
type ResourceConfigOption int
Resource config option to pick from options - when @drawable/icon is referenced, use /res/drawable-xhdpi/icon.png or use /res/drawable-mdpi/icon.png?
This is not fully implemented, so you can pick only first seen or last seen option.
const ( ConfigFirst ResourceConfigOption = iota // Usually the smallest ConfigLast // Usually the biggest // Try to find the biggest png icon, otherwise same as ConfigLast. // // Deprecated: use GetIconPng ConfigPngIcon )
type ResourceEntry ¶
type ResourceEntry struct { ResourceType string Key string Package string // contains filtered or unexported fields }
Describes one resource entry, for example @drawable/icon in the original XML, in one particular config option.
func (*ResourceEntry) GetValue ¶
func (e *ResourceEntry) GetValue() *ResourceValue
Returns the resource value handle
func (*ResourceEntry) IsComplex ¶
func (e *ResourceEntry) IsComplex() bool
Returns true if the resource entry is complex (for example arrays, string plural arrays...).
Complex ResourceEntries are not yet supported.
type ResourceTable ¶
type ResourceTable struct {
// contains filtered or unexported fields
}
Contains parsed resources.arsc file.
func ParseResourceTable ¶
func ParseResourceTable(r io.Reader) (*ResourceTable, error)
Parses the resources.arsc file
func (*ResourceTable) GetIconPng ¶
func (x *ResourceTable) GetIconPng(resId uint32) (*ResourceEntry, error)
Return the biggest last config ending with .png. Falls back to GetResourceEntry() if none found.
func (*ResourceTable) GetResourceEntry ¶
func (x *ResourceTable) GetResourceEntry(resId uint32) (*ResourceEntry, error)
Returns the resource entry for resId and the first configuration option it finds.
func (*ResourceTable) GetResourceEntryEx ¶
func (x *ResourceTable) GetResourceEntryEx(resId uint32, config ResourceConfigOption) (*ResourceEntry, error)
Returns the resource entry for resId and config configuration option.
func (*ResourceTable) GetResourceName ¶
func (x *ResourceTable) GetResourceName(resId uint32) (string, error)
Converts the resource id to readable name including the package name like "@drawable:com.example.app.icon".
type ResourceValue ¶
type ResourceValue struct {
// contains filtered or unexported fields
}
Handle to the resource's actual value.
func (*ResourceValue) Data ¶
func (v *ResourceValue) Data() (interface{}, error)
Returns the data converted to their native type (e.g. AttrTypeString to string).
Returns ErrUnknownResourceDataType if the type is not handled by this library
func (*ResourceValue) RawData ¶
func (v *ResourceValue) RawData() uint32
Returns the raw data of the resource
func (*ResourceValue) String ¶
func (v *ResourceValue) String() (res string, err error)
Returns the data converted to a readable string, to the format it was likely in the original AndroidManifest.xml.
Unknown data types are returned as the string from ErrUnknownResourceDataType.Error().
type ZipReader ¶
type ZipReader struct { File map[string]*ZipReaderFile // Files in the order they were found in the zip. May contain the same ZipReaderFile // multiple times in case of broken/crafted ZIPs FilesOrdered []*ZipReaderFile // contains filtered or unexported fields }
This struct mimics of Reader from archive/zip. It's purpose is to handle even broken archives that Android can read, but archive/zip cannot.
func OpenZipReader ¶
func OpenZipReader(zipReader io.ReadSeeker) (zr *ZipReader, err error)
Attempts to open ZIP for reading. Might Seek the reader to arbitrary positions.
type ZipReaderFile ¶
This struct mimics of File from archive/zip. The main difference is it can represent multiple actual entries in the ZIP file in case it has more than one with the same name.
func (*ZipReaderFile) Close ¶
func (zr *ZipReaderFile) Close() error
Closes this reader and all opened files.
func (*ZipReaderFile) Next ¶
func (zr *ZipReaderFile) Next() bool
Moves this reader to the next file represented under it's Name. Returns false if there are no more to read.
func (*ZipReaderFile) Open ¶
func (zr *ZipReaderFile) Open() error
Opens the file(s) for reading. After calling open, you should iterate through all possible entries that go by that Filename with for f.Next() { f.Read()... }
func (*ZipReaderFile) Read ¶
func (zr *ZipReaderFile) Read(p []byte) (int, error)
Reads data from current opened file. Returns io.EOF at the end of current file, but another file entry might exist. Use Next() to check for that.
func (*ZipReaderFile) ReadAll ¶
func (zr *ZipReaderFile) ReadAll(limit int64) ([]byte, error)
Open, Read all bytes until limit and close the file
func (*ZipReaderFile) ZipHeader ¶
func (zr *ZipReaderFile) ZipHeader() *zip.FileHeader
Get the file header from ZIP (can return nil with broken archives)