【Delphi】AXMLPrinter (Android XML)

找这个的人肯定知道这是干什么的。没错,我花了半天时间将Java代码改写成了Delphi,在D2007下调试通过。

用法很简单,将APK文件改名成.zip,就可以解压缩了。解压以后可以看到很多文件,其中有很多是.xml后缀的。打开发现全是乱码。是的,你现在需要AXMLPrinter了。

比如我们知道,其中的AndroidManifest.XML文件存放了一个APK的包名、版本号、版本代码、权限等信息,你可以使用 TXmlPullParser.ReadAndroidManifestFile 来读取出这些信息。你也可以参考ReadAndroidManifestFile的写法,写出自己的处理代码,获取更多的信息。

甚至你可以配合unZip的模块,直接读取APK中指定XML文件。

{*******************************************************}
{                                                       }
{       AXMLPrinter (Android XML反编译)                 }
{                                                       }
{       版权所有 (C) 2015 YangYxd                       }
{                                                       }
{*******************************************************}

unit YxdAXMLPrinter;

interface

uses
  SysUtils, Classes;
  
const
  CHUNK_TYPE = $1C0001;
  CHUNK_AXML_FILE = 524291;
  CHUNK_RESOURCEIDS = 524672;
  CHUNK_XML_FIRST = 1048832;
  CHUNK_XML_START_NAMESPACE = 1048832;
  CHUNK_XML_END_NAMESPACE = 1048833;
  CHUNK_XML_START_TAG = 1048834;
  CHUNK_XML_END_TAG = 1048835;
  CHUNK_XML_TEXT = 1048836;
  CHUNK_XML_LAST = 1048836;

const
  RADIX_MULTS: array [0..3] of Double = (
	    0.0039063, 3.051758E-005, 1.192093E-007, 4.656613E-010);
	DIMENSION_UNITS: array [0..7] of String = (
	    'px', 'dip', 'sp', 'pt', 'in', 'mm', '', '');
	FRACTION_UNITS: array [0..7] of String = (
	    '%', '%p', '', '', '', '', '', '');

type
  TIntegers = array of Integer;
type
  TIntReader = class(TObject)
  private
    FStream: TStream;
    FBigEndian: Boolean;
    FPosition: Integer;
  protected
  public
    constructor Create; overload;
    constructor Create(AStream: TStream; bigEndian: Boolean); overload;
    constructor Create(const AFileName: string; bigEndian: Boolean); overload;
    destructor Destroy; override;

    procedure reset(AStream: TStream; bigEndian: Boolean);
    procedure Close();

    function readByte(): ShortInt;
    function readShort(): ShortInt;
    function readInt(): Integer; overload;
    function readInt(ALen: Integer): Integer; overload;
    function readIntArray(ALen: Integer): TIntegers; overload;
    procedure readIntArray(var AData: TIntegers); overload;
    procedure readIntArray(var AData: TIntegers; AOffset, ALen: Integer); overload;
    function readByteArray(ALen: Integer): TBytes;
    procedure skip(bytes: Integer);
    procedure skipInt();
    function available(): Integer;

    property Stream: TStream read FStream;
    property IsBigEndian: Boolean read FBigEndian write FBigEndian;
    property Position: Integer read FPosition write FPosition;
  end;

type
  TStringBlock = class
  private
    FStringOffset: TIntegers;
    FStrings: TIntegers;
    function GetCount: Integer;
    function GetString(index: Integer): string;
  protected
    FStyleOffset: TIntegers;
    FStyles: TIntegers;
  public
    constructor Create(); 
    destructor Destroy; override;
    class function read(reader: TIntReader): TStringBlock;
    function find(const str: string): Integer;
    function getShort(const datas: TIntegers; offset: Integer): Integer;
    property Count: Integer read GetCount;
    property Items[index: Integer]: string read GetString;
  end;

type
  TNamespaceStack = class;
  TXmlPullParser = class(TObject)
  private
    m_operational: Boolean;
    m_strings: TStringBlock;
    m_reader: TIntReader;
    m_resourceIDs: TIntegers;
    m_namespaces: TNamespaceStack;
    m_decreaseDepth: Boolean;
    m_event: Integer;
    m_lineNumber: Integer;
    m_name: Integer;
    m_namespaceUri: Integer;
    m_attributes: TIntegers;
    m_idAttribute: Integer;
    m_classAttribute: Integer;
    m_styleAttribute: Integer;

    procedure doNext();
  protected
  public
    constructor Create; virtual;
    destructor Destroy; override;

    procedure Open(AStream: TStream); overload;
    procedure Open(const AFileName: string); overload;
    procedure Close();

    class function getPackage(id: Integer): string;
    class function complexToFloat(complex: Integer): Double;

    // 读取 APK 文件中zip解压后的 AndroidManifest.xml 文件获取基本
    // 信息 (包名、版本名称、版本代码)
    class function ReadAndroidManifestFile(const AFileName: string;
      var packageName, versionName: string; var versionCode: Integer): Boolean; overload;
    // 读取 APK 文件中zip解压后的 AndroidManifest.xml 文件获取基本
    // 信息 (包名、版本名称、版本代码)
    class function ReadAndroidManifestFile(AStream: TStream;
      var packageName, versionName: string; var versionCode: Integer): Boolean; overload;

    function next(): Integer;
    function nextToken(): Integer;
    function nextTag(): Integer;
    function nextText(): string;
    procedure require(atype: Integer; const namespace, name: string);
    function getDepth(): Integer;
    function getEventType(): Integer;
    function getLineNumber(): Integer;
    function getName(): string;
    function getText(): string;
    function getNamespace(): string;
    function getPrefix(): string;
    function getPositionDescription(): string;
    function getNamespaceCount(depth: Integer): Integer;
    function getNamespacePrefix(apos: Integer): string;
    function getNamespaceUri(apos: Integer): string;
    function getClassAttribute(): string;
    function getIdAttribute(): string;
    function getIdAttributeResourceValue(defaultValue: Integer = 0): Integer;
    function getStyleAttribute(): Integer;
    function getAttributeCount(): Integer;
    function getAttributeNamespace(index: Integer): string;
    function getAttributePrefix(index: Integer): string;
    function getAttributeName(index: Integer): string;
    function getAttributeNameResource(index: Integer) :Integer;
    function getAttributeValueType(index: Integer): Integer;
    function getAttributeValueData(index: Integer): Integer;
    function getAttributeValue(index: Integer): string; overload;
    function getAttributeBooleanValue(index: Integer; defaultValue: Boolean = false): Boolean; overload;
    function getAttributeFloatValue(index: Integer; defaultValue: Double = 0): Double; overload;
    function getAttributeIntValue(index: Integer; defaultValue: Integer = 0): Integer; overload;
    function getAttributeUnsignedIntValue(index: Integer; defaultValue: Cardinal = 0): Cardinal; overload;
    function getAttributeResourceValue(index: Integer; defaultValue: Integer = 0): Integer; overload;
    function getAttributeValue(const namespace, attribute: string): string; overload;
    function getAttributeBooleanValue(const namespace, attribute: string; defaultValue: Boolean = False): Boolean; overload;
    function getAttributeFloatValue(const namespace, attribute: string; defaultValue: Double = 0): Double; overload;
    function getAttributeIntValue(const namespace, attribute: string; defaultValue: Integer = 0): Integer; overload;
    function getAttributeUnsignedIntValue(const namespace, attribute: string; defaultValue: Cardinal = 0): Cardinal; overload;
    function getAttributeResourceValue(const namespace, attribute: string; defaultValue: Integer = 0): Integer; overload;
    function getAttributeListValue(index: Integer; options: array of string; defaultValue: Integer = 0): Integer; overload;
    function getAttributeListValue(const namespace, attribute: string; options: array of string; defaultValue: Integer = 0): Integer; overload;
    function getAttributeType(index: Integer): string;
    function isAttributeDefault(index: Integer): Boolean;
    function getInputEncoding(): string;
    function getColumnNumber(): Integer;
    function isEmptyElementTag(): Boolean;
    function isWhitespace(): Boolean;
    function getProperty(const name: string): TObject;
    function getFeature(const feature: string): Boolean;
    function getStrings(): TStringBlock;
    function getAttributeOffset(index: Integer): Integer;
    function findAttribute(const namespace, attribute: string): Integer;
    function getAttributeValueEx(index: Integer): string;

    procedure resetEventInfo();
  end;

完整代码请点击下面的下载链接,或加入QDAC官方群(250530692)索取。

下载地址http://pan.baidu.com/s/1sjK895r 密码: aq7c

如发现有Bug,请在这里留言告诉我。

 

分享到: