diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java index efc47159..cd515577 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java @@ -190,22 +190,42 @@ final public class AndrolibResources { mMaxSdkVersion = map.get("maxSdkVersion"); } } + + public void prepPath() throws AndrolibException { + List cmd = new ArrayList(); + + // check for win vs linux + if (System.getProperty("os.name").indexOf("win") >= 0) { + cmd.add("set PATH=%PATH%;" + System.getProperty("user.dir")); + } else { + cmd.add("export PATH=$PATH:" + System.getProperty("user.dir")); + } + + try { + OS.exec(cmd.toArray(new String[0])); + } catch (BrutException ex) { + throw new AndrolibException(ex); + } + } public void aaptPackage(File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include, HashMap flags) throws AndrolibException { + List cmd = new ArrayList(); cmd.add("aapt"); cmd.add("p"); - if (flags.get("verbose")) { + if (flags.get("verbose")) { //output aapt verbose cmd.add("-v"); } - if (flags.get("update")) { cmd.add("-u"); } + if (flags.get("debug")) { //inject debuggable="true" into manifest + cmd.add("--debug-mode"); + } if (mMinSdkVersion != null) { cmd.add("--min-sdk-version"); cmd.add(mMinSdkVersion); @@ -473,6 +493,7 @@ final public class AndrolibResources { entry.setCrc(crc.getValue()); out.putNextEntry(entry); out.write(data); + zip.close(); LOGGER.info("Framework installed to: " + outFile); } catch (ZipException ex) { diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfigFlags.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfigFlags.java index 751564fd..b498a137 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfigFlags.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfigFlags.java @@ -27,6 +27,8 @@ public class ResConfigFlags { public final char[] language; public final char[] country; + + public final short layoutDirection; public final byte orientation; public final byte touchscreen; @@ -57,6 +59,7 @@ public class ResConfigFlags { mnc = 0; language = new char[]{'\00', '\00'}; country = new char[]{'\00', '\00'}; + layoutDirection = SCREENLAYOUT_LAYOUTDIR_ANY; orientation = ORIENTATION_ANY; touchscreen = TOUCHSCREEN_ANY; density = DENSITY_DEFAULT; @@ -76,9 +79,9 @@ public class ResConfigFlags { } public ResConfigFlags(short mcc, short mnc, char[] language, char[] country, - byte orientation, byte touchscreen, short density, byte keyboard, - byte navigation, byte inputFlags, short screenWidth, - short screenHeight, short sdkVersion, byte screenLayout, + short layoutDirection, byte orientation, byte touchscreen, + short density, byte keyboard, byte navigation, byte inputFlags, + short screenWidth, short screenHeight, short sdkVersion, byte screenLayout, byte uiMode, short smallestScreenWidthDp, short screenWidthDp, short screenHeightDp, boolean isInvalid) { if (orientation < 0 || orientation > 3) { @@ -111,6 +114,7 @@ public class ResConfigFlags { this.mnc = mnc; this.language = language; this.country = country; + this.layoutDirection = layoutDirection; this.orientation = orientation; this.touchscreen = touchscreen; this.density = density; @@ -147,6 +151,14 @@ public class ResConfigFlags { ret.append("-r").append(country); } } + switch (screenLayout & MASK_LAYOUTDIR) { + case SCREENLAYOUT_LAYOUTDIR_RTL: + ret.append("-ldrtl"); + break; + case SCREENLAYOUT_LAYOUTDIR_LTR: + ret.append("-ldltr"); + break; + } if (smallestScreenWidthDp != 0) { ret.append("-sw").append(smallestScreenWidthDp).append("dp"); } @@ -385,6 +397,12 @@ public class ResConfigFlags { public final static short DENSITY_XHIGH = 320; public final static short DENSITY_XXHIGH = 480; public final static short DENSITY_NONE = -1; + + public final static short MASK_LAYOUTDIR = 0xc0; + public final static short SCREENLAYOUT_LAYOUTDIR_ANY = 0x00; + public final static short SCREENLAYOUT_LAYOUTDIR_LTR = 0x40; + public final static short SCREENLAYOUT_LAYOUTDIR_RTL = 0x80; + public final static short SCREENLAYOUT_LAYOUTDIR_SHIFT = 0x06; public final static byte KEYBOARD_ANY = 0; public final static byte KEYBOARD_NOKEYS = 1; @@ -414,7 +432,7 @@ public class ResConfigFlags { public final static byte SCREENSIZE_NORMAL = 0x02; public final static byte SCREENSIZE_LARGE = 0x03; public final static byte SCREENSIZE_XLARGE = 0x04; - + public final static byte MASK_SCREENLONG = 0x30; public final static byte SCREENLONG_ANY = 0x00; public final static byte SCREENLONG_NO = 0x10; diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java index cc5bf6dd..72e6ff93 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java @@ -229,7 +229,7 @@ public class ARSCDecoder { int size = mIn.readInt(); if (size < 28) { throw new AndrolibException("Config size < 28"); - } + } boolean isInvalid = false; @@ -240,7 +240,7 @@ public class ARSCDecoder { (char) mIn.readByte(), (char) mIn.readByte()}; char[] country = new char[]{ (char) mIn.readByte(), (char) mIn.readByte()}; - + byte orientation = mIn.readByte(); byte touchscreen = mIn.readByte(); short density = mIn.readShort(); @@ -273,10 +273,11 @@ public class ARSCDecoder { screenHeightDp = mIn.readShort(); } - if (size >= 40) { - // mIn.skipBytes(2); + short layoutDirection = 0; + if (size >= 38 && !this.mPkg.getName().equalsIgnoreCase("com.htc")) { + layoutDirection = mIn.readShort(); } - + int exceedingSize = size - KNOWN_CONFIG_BYTES; if (exceedingSize > 0) { byte[] buf = new byte[exceedingSize]; @@ -295,7 +296,7 @@ public class ARSCDecoder { } } - return new ResConfigFlags(mcc, mnc, language, country, orientation, + return new ResConfigFlags(mcc, mnc, language, country, layoutDirection, orientation, touchscreen, density, keyboard, navigation, inputFlags, screenWidth, screenHeight, sdkVersion, screenLayout, uiMode, smallestScreenWidthDp, screenWidthDp, screenHeightDp, isInvalid); @@ -437,4 +438,4 @@ public class ARSCDecoder { private final FlagsOffset[] mFlagsOffsets; private final ResTable mResTable; } -} +} \ No newline at end of file diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java index c7f21466..76252818 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java @@ -49,6 +49,11 @@ public class XmlPullStreamDecoder implements ResStreamDecoder { int type = pp.getEventType(); if (type == XmlPullParser.START_TAG) { + if ("packages".equalsIgnoreCase(pp.getName())) { + try { + boolean test = parseAttr(pp); + } catch (AndrolibException e) {} + } if ("uses-sdk".equalsIgnoreCase(pp.getName())) { try { hideSdkInfo = parseAttr(pp);