UNPKG

node-apk

Version:

A library to parse Android application manifest and signature

104 lines (102 loc) 4.53 kB
"use strict"; /*Copyright (c) 2019 XdevL. All rights reserved. This work is licensed under the terms of the MIT license. For a copy, see <https://opensource.org/licenses/MIT>.*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.parseResourceValue = exports.StringPool = exports.Chunk = exports.ChunkType = void 0; var ChunkType; (function (ChunkType) { ChunkType[ChunkType["NULL"] = 0] = "NULL"; ChunkType[ChunkType["STRING_POOL"] = 1] = "STRING_POOL"; ChunkType[ChunkType["TABLE"] = 2] = "TABLE"; ChunkType[ChunkType["XML"] = 3] = "XML"; ChunkType[ChunkType["XML_FIRST_CHUNK"] = 256] = "XML_FIRST_CHUNK"; ChunkType[ChunkType["XML_START_NAMESPACE"] = 256] = "XML_START_NAMESPACE"; ChunkType[ChunkType["XML_END_NAMESPACE"] = 257] = "XML_END_NAMESPACE"; ChunkType[ChunkType["XML_START_ELEMENT"] = 258] = "XML_START_ELEMENT"; ChunkType[ChunkType["XML_END_ELEMENT"] = 259] = "XML_END_ELEMENT"; ChunkType[ChunkType["XML_CDATA"] = 260] = "XML_CDATA"; ChunkType[ChunkType["XML_LAST_CHUNK"] = 383] = "XML_LAST_CHUNK"; ChunkType[ChunkType["XML_RESOURCE_MAP"] = 384] = "XML_RESOURCE_MAP"; ChunkType[ChunkType["TABLE_PACKAGE"] = 512] = "TABLE_PACKAGE"; ChunkType[ChunkType["TABLE_TYPE"] = 513] = "TABLE_TYPE"; ChunkType[ChunkType["TABLE_TYPE_SPEC"] = 514] = "TABLE_TYPE_SPEC"; ChunkType[ChunkType["TABLE_LIBRARY"] = 515] = "TABLE_LIBRARY"; })(ChunkType = exports.ChunkType || (exports.ChunkType = {})); var Chunk = /** @class */ (function () { function Chunk(source, chunkType) { this.type = source.readUShort(); if (!chunkType || this.type === chunkType) { this.headerSize = source.readUShort(); this.chunkSize = source.readUInt(); this.headerSource = source.source(this.headerSize - 8); this.chunkSource = source.source(this.chunkSize - this.headerSize); } else { throw Error("Found incorrect chunk type: ".concat(this.type, ", expected: ").concat(chunkType)); } } return Chunk; }()); exports.Chunk = Chunk; var StringPool = /** @class */ (function () { function StringPool(chunk) { this.stringCount = chunk.headerSource.readUInt(); this.styleCount = chunk.headerSource.readUInt(); this.flags = chunk.headerSource.readUInt(); this.stringsStart = chunk.headerSource.readUInt(); this.stylesStart = chunk.headerSource.readUInt(); this.values = []; var indexes = []; for (var i = 0; i < this.stringCount; ++i) { indexes.push(chunk.chunkSource.readUInt()); } // TODO: make sure indexes are sorted for (var _i = 0, indexes_1 = indexes; _i < indexes_1.length; _i++) { var index = indexes_1[_i]; chunk.chunkSource.moveAt(this.stringsStart - chunk.headerSize + index); if (this.flags & 256) { this.values.push(StringPool.readUtf8String(chunk.chunkSource)); } else { this.values.push(StringPool.readUtf16String(chunk.chunkSource)); } } } StringPool.readUtf8String = function (source) { source.getCursorAndMove(1); // skip char length return source.readUtf8String(source.readUByte()); }; StringPool.readUtf16String = function (source) { return source.readUtf16String(source.readUShort() * 2); }; return StringPool; }()); exports.StringPool = StringPool; var ResourceType; (function (ResourceType) { ResourceType[ResourceType["NULL"] = 0] = "NULL"; ResourceType[ResourceType["REFERENCE"] = 1] = "REFERENCE"; ResourceType[ResourceType["STRING"] = 3] = "STRING"; ResourceType[ResourceType["INT_DEC"] = 16] = "INT_DEC"; ResourceType[ResourceType["INT_BOOLEAN"] = 18] = "INT_BOOLEAN"; })(ResourceType || (ResourceType = {})); function parseResourceValue(source, stringPool) { source.getCursorAndMove(3); // size + res0 var type = source.readUByte(); switch (type) { case ResourceType.REFERENCE: return source.readInt(); case ResourceType.STRING: { var index = source.readInt(); return index >= 0 ? stringPool.values[index] : null; } case ResourceType.INT_DEC: return source.readInt(); case ResourceType.INT_BOOLEAN: return source.readInt() === 0 ? false : true; default: return null; } } exports.parseResourceValue = parseResourceValue;