Skip to content

refactor: ExtDataInput rework, source layout and formatting #3738

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 17 additions & 38 deletions brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@
* Main entry point of the apktool.
*/
public class Main {
private enum Verbosity { NORMAL, VERBOSE, QUIET }

private static final Options normalOptions = new Options();
private static final Options decodeOptions = new Options();
private static final Options buildOptions = new Options();
private static final Options frameOptions = new Options();
private static final Options allOptions = new Options();
private static final Options emptyOptions = new Options();
private static final Options emptyFrameworkOptions = new Options();
private static final Options listFrameworkOptions = new Options();

private static boolean advanceMode = false;

public static void main(String[] args) throws BrutException {

// headless
Expand Down Expand Up @@ -239,7 +252,7 @@ private static void cmdDecode(CommandLine cli, Config config) throws AndrolibExc
System.exit(1);
} catch (CantFindFrameworkResException ex) {
System.err
.println("Can't find framework resources for package of id: "
.println("Could not find framework resources for package of id: "
+ ex.getPkgId()
+ ". You must install proper "
+ "framework files, see project website for more info.");
Expand Down Expand Up @@ -271,15 +284,8 @@ private static void cmdBuild(CommandLine cli, Config config) throws AndrolibExce
}

try {
String aaptPath = cli.getOptionValue("a");
int aaptVersion = AaptManager.getAaptVersion(aaptPath);
if (aaptVersion < AaptManager.AAPT_VERSION_MIN && aaptVersion > AaptManager.AAPT_VERSION_MAX) {
System.err.println("AAPT version " + aaptVersion + " is not supported");
System.exit(1);
}

config.aaptPath = aaptPath;
config.aaptVersion = aaptVersion;
config.aaptBinary = new File(cli.getOptionValue("a"));
config.aaptVersion = AaptManager.getAaptVersion(config.aaptBinary);
} catch (BrutException ex) {
System.err.println(ex.getMessage());
System.exit(1);
Expand Down Expand Up @@ -310,7 +316,7 @@ private static void cmdBuild(CommandLine cli, Config config) throws AndrolibExce
}

if (config.netSecConf && config.aaptVersion == 1) {
System.err.println("-n / --net-sec-conf is not supported with legacy AAPT.");
System.err.println("-n / --net-sec-conf is not supported with legacy aapt.");
System.exit(1);
}

Expand Down Expand Up @@ -724,31 +730,4 @@ private static boolean isAdvanceMode() {
private static void setAdvanceMode() {
Main.advanceMode = true;
}

private enum Verbosity {
NORMAL, VERBOSE, QUIET
}

private static boolean advanceMode = false;

private final static Options normalOptions;
private final static Options decodeOptions;
private final static Options buildOptions;
private final static Options frameOptions;
private final static Options allOptions;
private final static Options emptyOptions;
private final static Options emptyFrameworkOptions;
private final static Options listFrameworkOptions;

static {
//normal and advance usage output
normalOptions = new Options();
buildOptions = new Options();
decodeOptions = new Options();
frameOptions = new Options();
allOptions = new Options();
emptyOptions = new Options();
emptyFrameworkOptions = new Options();
listFrameworkOptions = new Options();
}
}
5 changes: 2 additions & 3 deletions brut.apktool/apktool-lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ val apktoolVersion: String by rootProject.extra

tasks {
processResources {
from("src/main/resources/properties") {
include("**/*.properties")
into("properties")
from("src/main/resources") {
include("apktool.properties")
expand("version" to apktoolVersion, "gitrev" to gitRevision)
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
public interface XmlResourceParser extends XmlPullParser, AttributeSet {
/**
* Close this interface to the resource. Calls on the interface are no
* longer value after this call.
* longer valid after this call.
*/
void close();
}
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ public class TypedValue {
public int type;

private static final float MANTISSA_MULT = 1.0f / (1 << TypedValue.COMPLEX_MANTISSA_SHIFT);
private static final float[] RADIX_MULTS = new float[] {
private static final float[] RADIX_MULTS = {
MANTISSA_MULT, 1.0f / (1 << 7) * MANTISSA_MULT,
1.0f / (1 << 15) * MANTISSA_MULT, 1.0f / (1 << 23) * MANTISSA_MULT };

Expand All @@ -237,9 +237,10 @@ public static float complexToFloat(int complex) {
& TypedValue.COMPLEX_RADIX_MASK];
}

private static final String[] DIMENSION_UNIT_STRS = new String[] { "px",
"dip", "sp", "pt", "in", "mm" };
private static final String[] FRACTION_UNIT_STRS = new String[] { "%", "%p" };
private static final String[] DIMENSION_UNIT_STRS = {
"px", "dip", "sp", "pt", "in", "mm"
};
private static final String[] FRACTION_UNIT_STRS = { "%", "%p" };

/**
* Perform type conversion as per coerceToString on an explicitly
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,44 +27,40 @@
import java.util.logging.Logger;

public class AaptInvoker {
private static final Logger LOGGER = Logger.getLogger(AaptInvoker.class.getName());

private final Config mConfig;
private final ApkInfo mApkInfo;

private final static Logger LOGGER = Logger.getLogger(AaptInvoker.class.getName());

public AaptInvoker(Config config, ApkInfo apkInfo) {
mConfig = config;
mApkInfo = apkInfo;
}

private File getAaptBinaryFile() throws AndrolibException {
try {
switch (mConfig.aaptVersion) {
case 2:
return AaptManager.getAapt2();
default:
return AaptManager.getAapt1();
}
} catch (BrutException ex) {
throw new AndrolibException(ex);
}
}

public void invoke(File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include)
throws AndrolibException {
File aaptBinary = mConfig.aaptBinary;

String aaptPath = mConfig.aaptPath;
boolean customAapt = !aaptPath.isEmpty();
List<String> cmd = new ArrayList<>();
String aaptPath;
boolean customAapt;

try {
String aaptCommand = AaptManager.getAaptExecutionCommand(aaptPath, getAaptBinaryFile());
cmd.add(aaptCommand);
} catch (BrutException ex) {
LOGGER.warning("aapt: " + ex.getMessage() + " (defaulting to $PATH binary)");
cmd.add(AaptManager.getAaptBinaryName(mConfig.aaptVersion));
if (mConfig.aaptBinary != null) {
aaptPath = mConfig.aaptBinary.getPath();
customAapt = true;
} else {
try {
aaptPath = AaptManager.getAaptBinary(mConfig.aaptVersion).getPath();
customAapt = false;
} catch (BrutException ex) {
aaptPath = AaptManager.getAaptName(mConfig.aaptVersion);
customAapt = true;
LOGGER.warning(aaptPath + ": " + ex.getMessage() + " (defaulting to $PATH binary)");
}
}

cmd.add(aaptPath);

switch (mConfig.aaptVersion) {
case 2:
invokeAapt2(apkFile, manifest, resDir, rawDir, assetDir, include, cmd, customAapt);
Expand All @@ -77,7 +73,6 @@ public void invoke(File apkFile, File manifest, File resDir, File rawDir, File a

private void invokeAapt2(File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include,
List<String> cmd, boolean customAapt) throws AndrolibException {

List<String> compileCommand = new ArrayList<>(cmd);
File resourcesZip = null;

Expand All @@ -87,7 +82,6 @@ private void invokeAapt2(File apkFile, File manifest, File resDir, File rawDir,
}

if (resDir != null && !resourcesZip.exists()) {

// Compile the files into flat arsc files
cmd.add("compile");

Expand Down Expand Up @@ -241,7 +235,6 @@ private void invokeAapt2(File apkFile, File manifest, File resDir, File rawDir,

private void invokeAapt1(File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include,
List<String> cmd, boolean customAapt) throws AndrolibException {

cmd.add("p");

if (mConfig.verbose) { // output aapt verbose
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import brut.androlib.apk.UsesFramework;
import brut.androlib.res.Framework;
import brut.androlib.res.data.ResConfigFlags;
import brut.androlib.res.xml.ResXmlPatcher;
import brut.androlib.res.xml.ResXmlUtils;
import brut.androlib.src.SmaliBuilder;
import brut.common.BrutException;
import brut.common.InvalidUnknownFileException;
Expand All @@ -47,14 +47,15 @@
import java.util.zip.ZipOutputStream;

public class ApkBuilder {
private final static Logger LOGGER = Logger.getLogger(ApkBuilder.class.getName());
private static final Logger LOGGER = Logger.getLogger(ApkBuilder.class.getName());

private final ExtFile mApkDir;
private final Config mConfig;
private final AtomicReference<AndrolibException> mBuildError;

private ApkInfo mApkInfo;
private int mMinSdkVersion = 0;
private int mMinSdkVersion;
private BackgroundWorker mWorker;
private final AtomicReference<AndrolibException> mBuildError = new AtomicReference<>(null);

public ApkBuilder(ExtFile apkDir) {
this(apkDir, Config.getDefaultConfig());
Expand All @@ -63,6 +64,7 @@ public ApkBuilder(ExtFile apkDir) {
public ApkBuilder(ExtFile apkDir, Config config) {
mApkDir = apkDir;
mConfig = config;
mBuildError = new AtomicReference<>(null);
}

public void build(File outApk) throws AndrolibException {
Expand Down Expand Up @@ -122,19 +124,19 @@ public void build(File outApk) throws AndrolibException {

LOGGER.info("Building apk file...");

try (ZipOutputStream outStream = new ZipOutputStream(Files.newOutputStream(outApk.toPath()))) {
try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(outApk.toPath()))) {
// zip aapt output files
try {
ZipUtils.zipDir(outDir, outStream, mApkInfo.doNotCompress);
ZipUtils.zipDir(outDir, out, mApkInfo.doNotCompress);
} catch (IOException ex) {
throw new AndrolibException(ex);
}

// zip remaining standard files
importRawFiles(outStream);
importRawFiles(out);

// zip unknown files
importUnknownFiles(outStream);
importUnknownFiles(out);
} catch (IOException ex) {
throw new AndrolibException(ex);
}
Expand Down Expand Up @@ -242,10 +244,10 @@ private void buildSourcesSmaliJob(File outDir, String dirName, String fileName)
//noinspection ResultOfMethodCallIgnored
dex.delete();

int apiLevel = mConfig.apiLevel > 0 ? mConfig.apiLevel : mMinSdkVersion;

LOGGER.info("Smaling " + dirName + " folder into " + fileName + "...");
SmaliBuilder.build(smaliDir, dex, apiLevel);
int apiLevel = mConfig.apiLevel > 0 ? mConfig.apiLevel : mMinSdkVersion;
SmaliBuilder builder = new SmaliBuilder(smaliDir, apiLevel);
builder.build(dex);
}

private void backupManifestFile(File manifest, File manifestOrig) throws AndrolibException {
Expand All @@ -265,7 +267,7 @@ private void backupManifestFile(File manifest, File manifestOrig) throws Androli

try {
FileUtils.copyFile(manifest, manifestOrig);
ResXmlPatcher.fixingPublicAttrsInProviderAttributes(manifest);
ResXmlUtils.fixingPublicAttrsInProviderAttributes(manifest);
} catch (IOException ex) {
throw new AndrolibException(ex);
}
Expand Down Expand Up @@ -327,10 +329,10 @@ private void buildResourcesFull(File outDir, File manifest) throws AndrolibExcep
try {
if (mConfig.debugMode) {
if (mConfig.aaptVersion == 2) {
LOGGER.info("Using aapt2 - setting 'debuggable' attribute to 'true' in AndroidManifest.xml");
ResXmlPatcher.setApplicationDebugTagTrue(manifest);
LOGGER.info("Setting 'debuggable' attribute to 'true' in AndroidManifest.xml");
ResXmlUtils.setApplicationDebugTagTrue(manifest);
} else {
ResXmlPatcher.removeApplicationDebugTag(manifest);
ResXmlUtils.removeApplicationDebugTag(manifest);
}
}

Expand All @@ -343,8 +345,8 @@ private void buildResourcesFull(File outDir, File manifest) throws AndrolibExcep
}

File netSecConfOrig = new File(mApkDir, "res/xml/network_security_config.xml");
ResXmlPatcher.modNetworkSecurityConfig(netSecConfOrig);
ResXmlPatcher.setNetworkSecurityConfig(manifest);
ResXmlUtils.modNetworkSecurityConfig(netSecConfOrig);
ResXmlUtils.setNetworkSecurityConfig(manifest);
LOGGER.info("Added permissive network security config in manifest");
}
} catch (IOException | ParserConfigurationException | TransformerException | SAXException ex) {
Expand All @@ -366,7 +368,7 @@ private void buildResourcesFull(File outDir, File manifest) throws AndrolibExcep
ninePatch = null;
}

LOGGER.info("Building resources with " + AaptManager.getAaptBinaryName(mConfig.aaptVersion) + "...");
LOGGER.info("Building resources with " + AaptManager.getAaptName(mConfig.aaptVersion) + "...");

try {
AaptInvoker invoker = new AaptInvoker(mConfig, mApkInfo);
Expand Down Expand Up @@ -406,7 +408,7 @@ private void buildManifest(File outDir, File manifest) throws AndrolibException
ninePatch = null;
}

LOGGER.info("Building AndroidManifest.xml with " + AaptManager.getAaptBinaryName(mConfig.aaptVersion) + "...");
LOGGER.info("Building AndroidManifest.xml with " + AaptManager.getAaptName(mConfig.aaptVersion) + "...");

try {
AaptInvoker invoker = new AaptInvoker(mConfig, mApkInfo);
Expand Down Expand Up @@ -460,7 +462,7 @@ private void copyOriginalFiles(File outDir) throws AndrolibException {
}
}

private void importRawFiles(ZipOutputStream outStream) throws AndrolibException {
private void importRawFiles(ZipOutputStream out) throws AndrolibException {
for (String dirName : ApkInfo.RAW_DIRNAMES) {
File rawDir = new File(mApkDir, dirName);
if (!rawDir.isDirectory()) {
Expand All @@ -469,22 +471,22 @@ private void importRawFiles(ZipOutputStream outStream) throws AndrolibException

LOGGER.info("Importing " + dirName + "...");
try {
ZipUtils.zipDir(mApkDir, dirName, outStream, mApkInfo.doNotCompress);
ZipUtils.zipDir(mApkDir, dirName, out, mApkInfo.doNotCompress);
} catch (IOException ex) {
throw new AndrolibException(ex);
}
}
}

private void importUnknownFiles(ZipOutputStream outStream) throws AndrolibException {
private void importUnknownFiles(ZipOutputStream out) throws AndrolibException {
File unknownDir = new File(mApkDir, "unknown");
if (!unknownDir.isDirectory()) {
return;
}

LOGGER.info("Importing unknown files...");
try {
ZipUtils.zipDir(unknownDir, outStream, mApkInfo.doNotCompress);
ZipUtils.zipDir(unknownDir, out, mApkInfo.doNotCompress);
} catch (IOException ex) {
throw new AndrolibException(ex);
}
Expand Down
Loading
Loading