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);
}
}
}
}
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;
}
}
}
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);
}
}
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);
}
}
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);
}
}
Aggregations