コード例 #1
0
        /// <summary>Create instance AndroidManifest.xml</summary>
        /// <param name="axml">AXML file decoder</param>
        /// <param name="resources">ARSC file decoder</param>
        /// <returns>AndroidManifest object</returns>
        public static AndroidManifest Load(AxmlFile axml, ArscFile resources)
        {
            if (axml == null || resources == null)
            {
                return(null);
            }

            if (!axml.Header.IsValid || !resources.Header.IsValid)
            {
                return(null);
            }

            return(new AndroidManifest(axml.RootNode, resources));
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: DKorablin/ApkReader
        static void ReadResource(String filePath)
        {
            Byte[]   resourceBytes = File.ReadAllBytes(filePath);
            ArscFile resources     = new ArscFile(resourceBytes);

            foreach (var item in resources.ResourceMap)
            {
                Console.WriteLine(item.Key + "\t\t\t" + String.Join("; ", item.Value.Select(p => p.Value).ToArray()));
            }

            //OldResourceFile resources2 = new OldResourceFile(resourceBytes);
            //var table2 = resources2.ResourceMap;
            foreach (var item in resources.ResourceMap)
            {
                String key    = "@" + item.Key.ToString("X4");
                String value1 = String.Join(";", item.Value.Select(p => p.Value).ToArray());
                //String value2 = String.Join(";", table2[key].ToArray());
                //if(!String.Equals(value1, value2))
                //	throw new Exception("Not equal");
            }
        }
コード例 #3
0
ファイル: Program.cs プロジェクト: DKorablin/ApkReader
        static void ReadApkManifest(String manifestPath, String resourcesPath)
        {
            AxmlFile axml      = new AxmlFile(StreamLoader.FromFile(manifestPath));
            ArscFile resources = new ArscFile(File.ReadAllBytes(resourcesPath));

            if (!axml.Header.IsValid || !resources.Header.IsValid)
            {
                throw new InvalidOperationException();
            }

            AndroidManifest apk = AndroidManifest.Load(axml, resources);

            Console.WriteLine("Label: " + apk.Application.Label);
            Console.WriteLine("Package: " + apk.Package);
            Console.WriteLine("Icon: " + apk.Application.Icon);
            Console.WriteLine("Permissions: " + String.Join(", ", apk.UsesPermission.Select(p => p.Name)));
            Console.WriteLine("Services: " + String.Join(", ", apk.Application.Service));
            Console.WriteLine("Activities: " + String.Join(", ", apk.Application.Activity));
            Console.WriteLine("Reciever: " + String.Join(", ", apk.Application.Reciever));
            Console.WriteLine("Features: " + String.Join(", ", apk.UsesFeature));
            Console.WriteLine("Uses Libraries: " + String.Join(", ", apk.Application.UsesLibrary.Select(p => p.Name)));
        }
コード例 #4
0
 /// <summary>Create ApplicationManifest object</summary>
 /// <param name="node">ApplicationManifest.xml root node</param>
 /// <param name="resource">resource.arsc object</param>
 private AndroidManifest(XmlNode node, ArscFile resource)
     : base(node, resource.ResourceMap)
 {
 }
コード例 #5
0
ファイル: ArscReader.cs プロジェクト: studentutu/apk-reader
        public static ArscFile Read(Stream stream)
        {
            var file = new ArscFile();

            using (var reader = new ResReader(stream))
            {
                var chunkHeader = reader.ReadResChunk_header();
                if (chunkHeader.Type != ResourceType.RES_TABLE_TYPE)
                {
                    throw new ApkReaderException("No RES_TABLE_TYPE found!");
                }
                if (chunkHeader.Size != stream.Length)
                {
                    throw new ApkReaderException("The buffer size not matches to the resource table size.");
                }
                file.Length = chunkHeader.Size;
                var resTable = reader.ReadResTable_header(chunkHeader);
                var globalStringPoolHeader = reader.ReadResStringPool_header(reader.ReadResChunk_header());
                var globalStringPool       = reader.ReadResStringPool(globalStringPoolHeader);
                file.GlobalStringPool = globalStringPool;
                for (var packageIndex = 0; packageIndex < resTable.PackageCount; packageIndex++)
                {
                    var package = new ArscPackage();
                    file.Packages.Add(package);
                    chunkHeader = reader.ReadResChunk_header();
                    var endPosition = stream.Position - 8 + chunkHeader.Size;
                    if (chunkHeader.Type != ResourceType.RES_TABLE_PACKAGE_TYPE)
                    {
                        throw new ApkReaderException();
                    }
                    var packageHeader = reader.ReadResTable_package(chunkHeader);
                    package.Id   = packageHeader.Id;
                    package.Name = packageHeader.Name.TrimEnd('\0');
                    chunkHeader  = reader.ReadResChunk_header();
                    if (chunkHeader.Type != ResourceType.RES_STRING_POOL_TYPE)
                    {
                        throw new ApkReaderException();
                    }
                    package.TypeStringPool = reader.ReadResStringPool(reader.ReadResStringPool_header(chunkHeader));
                    chunkHeader            = reader.ReadResChunk_header();
                    if (chunkHeader.Type != ResourceType.RES_STRING_POOL_TYPE)
                    {
                        throw new ApkReaderException();
                    }
                    package.KeyStringPool = reader.ReadResStringPool(reader.ReadResStringPool_header(chunkHeader));
                    do
                    {
                        chunkHeader = reader.ReadResChunk_header();
                        switch (chunkHeader.Type)
                        {
                        case ResourceType.RES_TABLE_TYPE_SPEC_TYPE:
                            var th = reader.ReadResTable_typeSpec(chunkHeader);
                            package.TypeSpecsData = new uint[th.EntryCount];
                            for (var i = 0; i < th.EntryCount; i++)
                            {
                                package.TypeSpecsData[i] = reader.ReadUInt32();
                            }
                            break;

                        case ResourceType.RES_TABLE_TYPE_TYPE:
                            var table     = reader.ReadResTable_type(chunkHeader);
                            var arscTable = new ArscTable
                            {
                                Config = table.Config
                            };
                            package.Tables.Add(arscTable);
                            var entryIndices = new int[table.EntryCount];
                            for (var i = 0; i < table.EntryCount; i++)
                            {
                                entryIndices[i] = reader.ReadInt32();
                            }
                            var entries = new ResTable_entry[table.EntryCount];
                            for (var i = 0; i < table.EntryCount; i++)
                            {
                                if (entryIndices[i] == -1)
                                {
                                    continue;
                                }
                                var resourceId = (packageHeader.Id << 24) | (table.RawID << 16) | i;
                                var entry      = reader.ReadResTable_entry();
                                entries[i] = entry;
                                if ((entry.Flags & EntryFlags.FLAG_COMPLEX) == 0)
                                {
                                    var value = reader.ReadRes_value();
                                    arscTable.Values[Convert.ToUInt32(resourceId)] = value;
                                }
                                else
                                {
                                    var parent = reader.ReadInt32();
                                    var count  = reader.ReadInt32();
                                    for (var x = 0; x < count; x++)
                                    {
                                        var refName = reader.ReadUInt32();
                                        var value   = reader.ReadRes_value();
                                    }
                                }
                            }
                            break;

                        default:
                            throw new ApkReaderException($"Unknow Data Type : {chunkHeader.Type}");
                        }
                    } while (stream.Position < endPosition);
                }
            }
            return(file);
        }
コード例 #6
0
        public void Execute(XmlDocument androidManifest, ArscFile resources, ApkInfo apkInfo)
        {
            var manifest = androidManifest.DocumentElement;

            if (manifest == null)
            {
                throw new ApkReaderException("AndroidManifest.xml is empty");
            }
            if (manifest.Name != "manifest")
            {
                throw new ApkReaderException("manifest is not root element.");
            }
            foreach (var package in resources.Packages)
            {
                foreach (var table in package.Tables)
                {
                    var config = table.Config;
                    var local  = config.GetLocal();
                    if (!String.IsNullOrEmpty(local) && !apkInfo.Locales.Contains(local))
                    {
                        apkInfo.Locales.Add(local);
                    }
                    if (config.ScreenTypeDensity != ConfigDensity.DENSITY_NONE &&
                        config.ScreenTypeDensity != ConfigDensity.DENSITY_DEFAULT)
                    {
                        var dpi = config.ScreenTypeDensity.ToString("D");
                        if (!apkInfo.Densities.Contains(dpi))
                        {
                            apkInfo.Densities.Add(dpi);
                        }
                    }
                }
            }
            foreach (XmlAttribute attribute in manifest.Attributes)
            {
                switch (attribute.LocalName)
                {
                case "versionCode":
                    apkInfo.VersionCode = attribute.Value;
                    break;

                case "versionName":
                    apkInfo.VersionName = attribute.Value;
                    break;

                case "package":
                    apkInfo.PackageName = attribute.Value;
                    break;
                }
            }
            foreach (XmlNode node in manifest.ChildNodes)
            {
                switch (node.LocalName)
                {
                case "uses-sdk":
                    if (node.Attributes != null)
                    {
                        foreach (XmlAttribute attribute in node.Attributes)
                        {
                            switch (attribute.LocalName)
                            {
                            case "minSdkVersion":
                                apkInfo.MinSdkVersion = attribute.Value;
                                break;

                            case "targetSdkVersion":
                                apkInfo.TargetSdkVersion = attribute.Value;
                                break;
                            }
                        }
                    }
                    break;

                case "uses-permission":
                    if (node.Attributes != null)
                    {
                        foreach (XmlAttribute attribute in node.Attributes)
                        {
                            if (attribute.LocalName == "name")
                            {
                                apkInfo.Permissions.Add(attribute.Value);
                            }
                        }
                    }
                    break;

                case "application":
                    if (node.Attributes != null)
                    {
                        foreach (XmlAttribute attribute in node.Attributes)
                        {
                            switch (attribute.LocalName)
                            {
                            case "label":
                            case "icon":
                            {
                                var id = Convert.ToUInt32(attribute.Value.TrimStart('@'), 16);
                                foreach (var package in resources.Packages)
                                {
                                    foreach (var table in package.Tables)
                                    {
                                        if (table.Values.ContainsKey(id))
                                        {
                                            var value = table.Values[id];
                                            var str   = resources.GlobalStringPool.GetString(value.StringValue);
                                            switch (attribute.LocalName)
                                            {
                                            case "label":
                                                var local = table.Config.GetLocal();
                                                if (string.IsNullOrEmpty(local))
                                                {
                                                    apkInfo.Label = str;
                                                }
                                                else
                                                {
                                                    apkInfo.Labels[local] = str;
                                                }
                                                break;

                                            case "icon":
                                                var dpi = table.Config.ScreenTypeDensity;
                                                switch (dpi)
                                                {
                                                case ConfigDensity.DENSITY_DEFAULT:
                                                case ConfigDensity.DENSITY_NONE:
                                                    apkInfo.Icon = str;
                                                    break;

                                                default:
                                                    if (String.IsNullOrEmpty(apkInfo.Icon))
                                                    {
                                                        apkInfo.Icon = str;
                                                    }
                                                    apkInfo.Icons[dpi.ToString("D")] = str;
                                                    break;
                                                }
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                            break;
                            }
                        }
                    }
                    var xnames = new List <String>();
                    var ynames = new List <String>();
                    foreach (XmlNode innerNode in node.ChildNodes)
                    {
                        switch (innerNode.LocalName)
                        {
                        case "activity":
                            var activityName = String.Empty;
                            if (innerNode.Attributes != null)
                            {
                                foreach (XmlAttribute innerNodeAttribute in innerNode.Attributes)
                                {
                                    if (innerNodeAttribute.LocalName == "name")
                                    {
                                        activityName = innerNodeAttribute.Value;
                                    }
                                }
                            }
                            if (!String.IsNullOrEmpty(activityName))
                            {
                                foreach (XmlNode intentFilterNode in innerNode.ChildNodes)
                                {
                                    foreach (XmlNode endNode in intentFilterNode.ChildNodes)
                                    {
                                        if (endNode.Attributes != null)
                                        {
                                            foreach (XmlAttribute endNodeAttribute in endNode.Attributes)
                                            {
                                                if (endNodeAttribute.LocalName == "name")
                                                {
                                                    switch (endNodeAttribute.Value)
                                                    {
                                                    case "android.intent.action.MAIN":
                                                        xnames.Add(activityName);
                                                        break;

                                                    case "android.intent.category.LAUNCHER":
                                                        ynames.Add(activityName);
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    }
                    var znames = new List <String>();
                    foreach (var xname in xnames)
                    {
                        if (ynames.Contains(xname))
                        {
                            znames.Add(xname);
                        }
                    }
                    if (znames.Count > 0)
                    {
                        apkInfo.LaunchableActivity = znames[0];
                    }
                    break;
                }
            }
        }