Search in sources :

Example 1 with AndrolibException

use of com.tencent.mm.androlib.AndrolibException in project AndResGuard by shwenzhang.

the class ARSCDecoder method readValue.

private void readValue(boolean flags, int specNamesId) throws IOException, AndrolibException {
    /* size */
    mIn.skipCheckShort((short) 8);
    /* zero */
    mIn.skipCheckByte((byte) 0);
    byte type = mIn.readByte();
    int data = mIn.readInt();
    //这里面有几个限制,一对于string ,id, array我们是知道肯定不用改的,第二看要那个type是否对应有文件路径
    if (mPkg.isCanProguard() && flags && type == TypedValue.TYPE_STRING && mShouldProguardForType && mShouldProguardTypeSet.contains(mType.getName())) {
        if (mTableStringsProguard.get(data) == null) {
            String raw = mTableStrings.get(data).toString();
            if (StringUtil.isBlank(raw))
                return;
            String proguard = mPkg.getSpecRepplace(mResId);
            //这个要写死这个,因为resources.arsc里面就是用这个
            int secondSlash = raw.lastIndexOf("/");
            if (secondSlash == -1) {
                throw new AndrolibException(String.format("can not find \\ or raw string in res path=%s", raw));
            }
            String newFilePath = raw.substring(0, secondSlash);
            if (!mApkDecoder.getConfig().mKeepRoot) {
                newFilePath = mOldFileName.get(raw.substring(0, secondSlash));
            }
            if (newFilePath == null) {
                System.err.printf("can not found new res path, raw=%s\n", raw);
                return;
            }
            //同理这里不能用File.separator,因为resources.arsc里面就是用这个
            String result = newFilePath + "/" + proguard;
            int firstDot = raw.indexOf(".");
            if (firstDot != -1) {
                result += raw.substring(firstDot);
            }
            String compatibaleraw = new String(raw);
            String compatibaleresult = new String(result);
            //为了适配window要做一次转换
            if (!File.separator.contains("/")) {
                compatibaleresult = compatibaleresult.replace("/", File.separator);
                compatibaleraw = compatibaleraw.replace("/", File.separator);
            }
            File resRawFile = new File(mApkDecoder.getOutTempDir().getAbsolutePath() + File.separator + compatibaleraw);
            File resDestFile = new File(mApkDecoder.getOutDir().getAbsolutePath() + File.separator + compatibaleresult);
            //这里用的是linux的分隔符
            HashMap<String, Integer> compressData = mApkDecoder.getCompressData();
            if (compressData.containsKey(raw)) {
                compressData.put(result, compressData.get(raw));
            } else {
                System.err.printf("can not find the compress dataresFile=%s\n", raw);
            }
            if (!resRawFile.exists()) {
                System.err.printf("can not find res file, you delete it? path: resFile=%s\n", resRawFile.getAbsolutePath());
                return;
            } else {
                if (resDestFile.exists()) {
                    throw new AndrolibException(String.format("res dest file is already  found: destFile=%s", resDestFile.getAbsolutePath()));
                }
                FileOperation.copyFileUsingStream(resRawFile, resDestFile);
                //already copied
                mApkDecoder.removeCopiedResFile(resRawFile.toPath());
                mTableStringsProguard.put(data, result);
            }
        }
    }
}
Also used : BigInteger(java.math.BigInteger) AndrolibException(com.tencent.mm.androlib.AndrolibException) File(java.io.File)

Example 2 with AndrolibException

use of com.tencent.mm.androlib.AndrolibException in project AndResGuard by shwenzhang.

the class ARSCDecoder method readConfigFlags.

private void 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 = new char[] { (char) mIn.readByte(), (char) mIn.readByte() };
    char[] country = new char[] { (char) mIn.readByte(), (char) mIn.readByte() };
    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. Exceeding bytes: 0x%X.", KNOWN_CONFIG_BYTES, exceedingBI));
            isInvalid = true;
        }
    }
}
Also used : AndrolibException(com.tencent.mm.androlib.AndrolibException) BigInteger(java.math.BigInteger)

Example 3 with AndrolibException

use of com.tencent.mm.androlib.AndrolibException in project AndResGuard by shwenzhang.

the class ARSCDecoder method write.

public static void write(InputStream arscStream, ApkDecoder decoder, ResPackage[] pkgs) throws AndrolibException {
    try {
        ARSCDecoder writer = new ARSCDecoder(arscStream, decoder, pkgs);
        writer.writeTable();
    } catch (IOException ex) {
        throw new AndrolibException("Could not decode arsc file", ex);
    }
}
Also used : AndrolibException(com.tencent.mm.androlib.AndrolibException) IOException(java.io.IOException)

Example 4 with AndrolibException

use of com.tencent.mm.androlib.AndrolibException in project AndResGuard by shwenzhang.

the class ARSCDecoder method decode.

public static ResPackage[] decode(InputStream arscStream, ApkDecoder apkDecoder) throws AndrolibException {
    try {
        ARSCDecoder decoder = new ARSCDecoder(arscStream, apkDecoder);
        ResPackage[] pkgs = decoder.readTable();
        return pkgs;
    } catch (IOException ex) {
        throw new AndrolibException("Could not decode arsc file", ex);
    }
}
Also used : AndrolibException(com.tencent.mm.androlib.AndrolibException) IOException(java.io.IOException) ResPackage(com.tencent.mm.androlib.res.data.ResPackage)

Example 5 with AndrolibException

use of com.tencent.mm.androlib.AndrolibException in project AndResGuard by shwenzhang.

the class ARSCDecoder method readEntry.

/**
     * 需要防止由于某些非常恶心的白名单,导致出现重复id
     *
     * @throws IOException
     * @throws AndrolibException
     */
private void readEntry() throws IOException, AndrolibException {
    mIn.skipBytes(2);
    short flags = mIn.readShort();
    int specNamesId = mIn.readInt();
    if (mPkg.isCanProguard()) {
        //混效过,或者已经添加到白名单的都不需要再处理了
        if (!mProguardBuilder.isReplaced(mCurEntryID) && !mProguardBuilder.isInWhiteList(mCurEntryID)) {
            Configuration config = mApkDecoder.getConfig();
            boolean isWhiteList = false;
            if (config.mUseWhiteList) {
                //判断是否走whitelist
                HashMap<String, HashMap<String, HashSet<Pattern>>> whiteList = config.mWhiteList;
                String packName = mPkg.getName();
                if (whiteList.containsKey(packName)) {
                    HashMap<String, HashSet<Pattern>> typeMaps = whiteList.get(packName);
                    String typeName = mType.getName();
                    if (typeMaps.containsKey(typeName)) {
                        String specName = mSpecNames.get(specNamesId).toString();
                        HashSet<Pattern> patterns = typeMaps.get(typeName);
                        for (Iterator<Pattern> it = patterns.iterator(); it.hasNext(); ) {
                            Pattern p = it.next();
                            if (p.matcher(specName).matches()) {
                                mPkg.putSpecNamesReplace(mResId, specName);
                                mPkg.putSpecNamesblock(specName);
                                mProguardBuilder.setInWhiteList(mCurEntryID, true);
                                mType.putSpecProguardName(specName);
                                isWhiteList = true;
                                break;
                            }
                        }
                    }
                }
            }
            String replaceString = null;
            if (!isWhiteList) {
                boolean keepMapping = false;
                if (config.mUseKeepMapping) {
                    HashMap<String, HashMap<String, HashMap<String, String>>> resMapping = config.mOldResMapping;
                    String packName = mPkg.getName();
                    if (resMapping.containsKey(packName)) {
                        HashMap<String, HashMap<String, String>> typeMaps = resMapping.get(packName);
                        String typeName = mType.getName();
                        if (typeMaps.containsKey(typeName)) {
                            //这里面的东东已经提前去掉,请放心使用
                            HashMap<String, String> proguard = typeMaps.get(typeName);
                            String specName = mSpecNames.get(specNamesId).toString();
                            if (proguard.containsKey(specName)) {
                                keepMapping = true;
                                replaceString = proguard.get(specName);
                            }
                        }
                    }
                }
                if (!keepMapping) {
                    replaceString = mProguardBuilder.getReplaceString();
                }
                mProguardBuilder.setInReplaceList(mCurEntryID, true);
                if (replaceString == null) {
                    throw new AndrolibException("readEntry replaceString == null");
                }
                generalResIDMapping(mPkg.getName(), mType.getName(), mSpecNames.get(specNamesId).toString(), replaceString);
                mPkg.putSpecNamesReplace(mResId, replaceString);
                mPkg.putSpecNamesblock(replaceString);
                mType.putSpecProguardName(replaceString);
            }
        }
    }
    boolean readDirect;
    if ((flags & ENTRY_FLAG_COMPLEX) == 0) {
        readDirect = true;
        readValue(readDirect, specNamesId);
    } else {
        readDirect = false;
        readComplexEntry(readDirect, specNamesId);
    }
}
Also used : Pattern(java.util.regex.Pattern) Configuration(com.tencent.mm.resourceproguard.Configuration) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) AndrolibException(com.tencent.mm.androlib.AndrolibException) HashSet(java.util.HashSet)

Aggregations

AndrolibException (com.tencent.mm.androlib.AndrolibException)9 IOException (java.io.IOException)4 ResPackage (com.tencent.mm.androlib.res.data.ResPackage)3 BigInteger (java.math.BigInteger)3 Configuration (com.tencent.mm.resourceproguard.Configuration)1 File (java.io.File)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 Pattern (java.util.regex.Pattern)1