Search in sources :

Example 6 with AndrolibException

use of brut.androlib.AndrolibException in project Apktool by iBotPeaches.

the class AndrolibResources method installFramework.

public void installFramework(File frameFile, String tag) throws AndrolibException {
    InputStream in = null;
    ZipOutputStream out = null;
    try {
        ZipFile zip = new ZipFile(frameFile);
        ZipEntry entry = zip.getEntry("resources.arsc");
        if (entry == null) {
            throw new AndrolibException("Can't find resources.arsc file");
        }
        in = zip.getInputStream(entry);
        byte[] data = IOUtils.toByteArray(in);
        ARSCData arsc = ARSCDecoder.decode(new ByteArrayInputStream(data), true, true);
        publicizeResources(data, arsc.getFlagsOffsets());
        File outFile = new File(getFrameworkDir(), String.valueOf(arsc.getOnePackage().getId()) + (tag == null ? "" : '-' + tag) + ".apk");
        out = new ZipOutputStream(new FileOutputStream(outFile));
        out.setMethod(ZipOutputStream.STORED);
        CRC32 crc = new CRC32();
        crc.update(data);
        entry = new ZipEntry("resources.arsc");
        entry.setSize(data.length);
        entry.setCrc(crc.getValue());
        out.putNextEntry(entry);
        out.write(data);
        out.closeEntry();
        //Write fake AndroidManifest.xml file to support original aapt
        entry = zip.getEntry("AndroidManifest.xml");
        if (entry != null) {
            in = zip.getInputStream(entry);
            byte[] manifest = IOUtils.toByteArray(in);
            CRC32 manifestCrc = new CRC32();
            manifestCrc.update(manifest);
            entry.setSize(manifest.length);
            entry.setCompressedSize(-1);
            entry.setCrc(manifestCrc.getValue());
            out.putNextEntry(entry);
            out.write(manifest);
            out.closeEntry();
        }
        zip.close();
        LOGGER.info("Framework installed to: " + outFile);
    } catch (IOException ex) {
        throw new AndrolibException(ex);
    } finally {
        IOUtils.closeQuietly(in);
        IOUtils.closeQuietly(out);
    }
}
Also used : ZipFile(java.util.zip.ZipFile) ARSCData(brut.androlib.res.decoder.ARSCDecoder.ARSCData) CRC32(java.util.zip.CRC32) ZipOutputStream(java.util.zip.ZipOutputStream) ZipEntry(java.util.zip.ZipEntry) AndrolibException(brut.androlib.AndrolibException) ZipFile(java.util.zip.ZipFile) ExtFile(brut.directory.ExtFile)

Example 7 with AndrolibException

use of brut.androlib.AndrolibException in project Apktool by iBotPeaches.

the class ResSmaliUpdater method updateResIDs.

public void updateResIDs(ResTable resTable, File smaliDir) throws AndrolibException {
    try {
        Directory dir = new FileDirectory(smaliDir);
        for (String fileName : dir.getFiles(true)) {
            Iterator<String> it = IOUtils.readLines(dir.getFileInput(fileName)).iterator();
            PrintWriter out = new PrintWriter(dir.getFileOutput(fileName));
            while (it.hasNext()) {
                String line = it.next();
                out.println(line);
                Matcher m1 = RES_NAME_PATTERN.matcher(line);
                if (!m1.matches()) {
                    continue;
                }
                Matcher m2 = RES_ID_PATTERN.matcher(it.next());
                if (!m2.matches()) {
                    throw new AndrolibException();
                }
                int resID = resTable.getPackage(m1.group(1)).getType(m1.group(2)).getResSpec(m1.group(3)).getId().id;
                if (m2.group(1) != null) {
                    out.println(String.format(RES_ID_FORMAT_FIELD, m2.group(1), resID));
                } else {
                    out.println(String.format(RES_ID_FORMAT_CONST, m2.group(2), resID));
                }
            }
            out.close();
        }
    } catch (IOException ex) {
        throw new AndrolibException("Could not tag res IDs for: " + smaliDir.getAbsolutePath(), ex);
    } catch (DirectoryException ex) {
        throw new AndrolibException("Could not tag res IDs for: " + smaliDir.getAbsolutePath(), ex);
    }
}
Also used : Matcher(java.util.regex.Matcher) FileDirectory(brut.directory.FileDirectory) AndrolibException(brut.androlib.AndrolibException) IOException(java.io.IOException) DirectoryException(brut.directory.DirectoryException) Directory(brut.directory.Directory) FileDirectory(brut.directory.FileDirectory) PrintWriter(java.io.PrintWriter)

Example 8 with AndrolibException

use of brut.androlib.AndrolibException in project Apktool by iBotPeaches.

the class ARSCDecoder method decode.

public static ARSCData decode(InputStream arscStream, boolean findFlagsOffsets, boolean keepBroken, ResTable resTable) throws AndrolibException {
    try {
        ARSCDecoder decoder = new ARSCDecoder(arscStream, resTable, findFlagsOffsets, keepBroken);
        ResPackage[] pkgs = decoder.readTableHeader();
        return new ARSCData(pkgs, decoder.mFlagsOffsets == null ? null : decoder.mFlagsOffsets.toArray(new FlagsOffset[0]), resTable);
    } catch (IOException ex) {
        throw new AndrolibException("Could not decode arsc file", ex);
    }
}
Also used : AndrolibException(brut.androlib.AndrolibException)

Example 9 with AndrolibException

use of brut.androlib.AndrolibException in project Apktool by iBotPeaches.

the class ARSCDecoder method readConfigFlags.

private ResConfigFlags readConfigFlags() throws IOException, AndrolibException {
    int size = mIn.readInt();
    int read = 28;
    if (size < 28) {
        throw new AndrolibException("Config size < 28");
    }
    boolean isInvalid = false;
    short mcc = mIn.readShort();
    short mnc = mIn.readShort();
    char[] language = this.unpackLanguageOrRegion(mIn.readByte(), mIn.readByte(), 'a');
    char[] country = this.unpackLanguageOrRegion(mIn.readByte(), mIn.readByte(), '0');
    byte orientation = mIn.readByte();
    byte touchscreen = mIn.readByte();
    int density = mIn.readUnsignedShort();
    byte keyboard = mIn.readByte();
    byte navigation = mIn.readByte();
    byte inputFlags = mIn.readByte();
    /* inputPad0 */
    mIn.skipBytes(1);
    short screenWidth = mIn.readShort();
    short screenHeight = mIn.readShort();
    short sdkVersion = mIn.readShort();
    /* minorVersion, now must always be 0 */
    mIn.skipBytes(2);
    byte screenLayout = 0;
    byte uiMode = 0;
    short smallestScreenWidthDp = 0;
    if (size >= 32) {
        screenLayout = mIn.readByte();
        uiMode = mIn.readByte();
        smallestScreenWidthDp = mIn.readShort();
        read = 32;
    }
    short screenWidthDp = 0;
    short screenHeightDp = 0;
    if (size >= 36) {
        screenWidthDp = mIn.readShort();
        screenHeightDp = mIn.readShort();
        read = 36;
    }
    char[] localeScript = null;
    char[] localeVariant = null;
    if (size >= 48) {
        localeScript = readScriptOrVariantChar(4).toCharArray();
        localeVariant = readScriptOrVariantChar(8).toCharArray();
        read = 48;
    }
    byte screenLayout2 = 0;
    if (size >= 52) {
        screenLayout2 = mIn.readByte();
        // reserved padding
        mIn.skipBytes(3);
        read = 52;
    }
    if (size >= 56) {
        mIn.skipBytes(4);
        read = 56;
    }
    int exceedingSize = size - KNOWN_CONFIG_BYTES;
    if (exceedingSize > 0) {
        byte[] buf = new byte[exceedingSize];
        read += exceedingSize;
        mIn.readFully(buf);
        BigInteger exceedingBI = new BigInteger(1, buf);
        if (exceedingBI.equals(BigInteger.ZERO)) {
            LOGGER.fine(String.format("Config flags size > %d, but exceeding bytes are all zero, so it should be ok.", KNOWN_CONFIG_BYTES));
        } else {
            LOGGER.warning(String.format("Config flags size > %d. Size = %d. Exceeding bytes: 0x%X.", KNOWN_CONFIG_BYTES, size, exceedingBI));
            isInvalid = true;
        }
    }
    int remainingSize = size - read;
    if (remainingSize > 0) {
        mIn.skipBytes(remainingSize);
    }
    return new ResConfigFlags(mcc, mnc, language, country, orientation, touchscreen, density, keyboard, navigation, inputFlags, screenWidth, screenHeight, sdkVersion, screenLayout, uiMode, smallestScreenWidthDp, screenWidthDp, screenHeightDp, localeScript, localeVariant, screenLayout2, isInvalid, size);
}
Also used : AndrolibException(brut.androlib.AndrolibException) BigInteger(java.math.BigInteger)

Example 10 with AndrolibException

use of brut.androlib.AndrolibException in project Apktool by iBotPeaches.

the class ResFileDecoder method decode.

public void decode(ResResource res, Directory inDir, Directory outDir) throws AndrolibException {
    ResFileValue fileValue = (ResFileValue) res.getValue();
    String inFileName = fileValue.getStrippedPath();
    String outResName = res.getFilePath();
    String typeName = res.getResSpec().getType().getName();
    String ext = null;
    String outFileName;
    int extPos = inFileName.lastIndexOf(".");
    if (extPos == -1) {
        outFileName = outResName;
    } else {
        ext = inFileName.substring(extPos).toLowerCase();
        outFileName = outResName + ext;
    }
    try {
        if (typeName.equals("raw")) {
            decode(inDir, inFileName, outDir, outFileName, "raw");
            return;
        }
        if (typeName.equals("drawable") || typeName.equals("mipmap")) {
            if (inFileName.toLowerCase().endsWith(".9" + ext)) {
                outFileName = outResName + ".9" + ext;
                // check for htc .r.9.png
                if (inFileName.toLowerCase().endsWith(".r.9" + ext)) {
                    outFileName = outResName + ".r.9" + ext;
                }
                // check for samsung qmg & spi
                if (inFileName.toLowerCase().endsWith(".qmg") || inFileName.toLowerCase().endsWith(".spi")) {
                    copyRaw(inDir, outDir, outFileName);
                    return;
                }
                // check for xml 9 patches which are just xml files
                if (inFileName.toLowerCase().endsWith(".xml")) {
                    decode(inDir, inFileName, outDir, outFileName, "xml");
                    return;
                }
                try {
                    decode(inDir, inFileName, outDir, outFileName, "9patch");
                    return;
                } catch (CantFind9PatchChunk ex) {
                    LOGGER.log(Level.WARNING, String.format("Cant find 9patch chunk in file: \"%s\". Renaming it to *.png.", inFileName), ex);
                    outDir.removeFile(outFileName);
                    outFileName = outResName + ext;
                }
            }
            if (!".xml".equals(ext)) {
                decode(inDir, inFileName, outDir, outFileName, "raw");
                return;
            }
        }
        decode(inDir, inFileName, outDir, outFileName, "xml");
    } catch (AndrolibException ex) {
        LOGGER.log(Level.SEVERE, String.format("Could not decode file, replacing by FALSE value: %s", inFileName), ex);
        res.replace(new ResBoolValue(false, 0, null));
    }
}
Also used : ResFileValue(brut.androlib.res.data.value.ResFileValue) CantFind9PatchChunk(brut.androlib.err.CantFind9PatchChunk) AndrolibException(brut.androlib.AndrolibException) ResBoolValue(brut.androlib.res.data.value.ResBoolValue)

Aggregations

AndrolibException (brut.androlib.AndrolibException)23 ExtFile (brut.directory.ExtFile)11 ZipFile (java.util.zip.ZipFile)9 DirectoryException (brut.directory.DirectoryException)7 ZipOutputStream (java.util.zip.ZipOutputStream)5 Directory (brut.directory.Directory)4 FileDirectory (brut.directory.FileDirectory)4 IOException (java.io.IOException)3 BrutException (brut.common.BrutException)2 CantFind9PatchChunk (brut.androlib.err.CantFind9PatchChunk)1 CantFindFrameworkResException (brut.androlib.err.CantFindFrameworkResException)1 ResTable (brut.androlib.res.data.ResTable)1 ResBoolValue (brut.androlib.res.data.value.ResBoolValue)1 ResFileValue (brut.androlib.res.data.value.ResFileValue)1 ARSCData (brut.androlib.res.decoder.ARSCDecoder.ARSCData)1 ExtMXSerializer (brut.androlib.res.util.ExtMXSerializer)1 ResValuesXmlSerializable (brut.androlib.res.xml.ResValuesXmlSerializable)1 BufferedImage (java.awt.image.BufferedImage)1 PrintWriter (java.io.PrintWriter)1 BigInteger (java.math.BigInteger)1