├── .gitignore ├── .idea ├── artifacts │ └── android_apktool_jar.xml ├── deploymentTargetDropDown.xml ├── gradle.xml ├── kotlinc.xml ├── migrations.xml ├── misc.xml ├── vcs.xml └── workspace.xml ├── ART ├── screenshot_1.png └── screenshot_2.png ├── README.MD ├── androlib ├── brut.apktool │ └── apktool-lib │ │ ├── .gitignore │ │ ├── build.gradle │ │ └── src │ │ └── main │ │ ├── java │ │ ├── brut │ │ │ └── androlib │ │ │ │ ├── AaptInvoker.java │ │ │ │ ├── ApkBuilder.java │ │ │ │ ├── ApkDecoder.java │ │ │ │ ├── ApktoolProperties.java │ │ │ │ ├── BackgroundWorker.java │ │ │ │ ├── Config.java │ │ │ │ ├── apk │ │ │ │ ├── ApkInfo.java │ │ │ │ ├── PackageInfo.java │ │ │ │ ├── UsesFramework.java │ │ │ │ ├── VersionInfo.java │ │ │ │ ├── YamlLine.java │ │ │ │ ├── YamlReader.java │ │ │ │ ├── YamlSerializable.java │ │ │ │ ├── YamlStringEscapeUtils.java │ │ │ │ └── YamlWriter.java │ │ │ │ ├── exceptions │ │ │ │ ├── AXmlDecodingException.java │ │ │ │ ├── AndrolibException.java │ │ │ │ ├── CantFind9PatchChunkException.java │ │ │ │ ├── CantFindFrameworkResException.java │ │ │ │ ├── InFileNotFoundException.java │ │ │ │ ├── OutDirExistsException.java │ │ │ │ ├── RawXmlEncounteredException.java │ │ │ │ └── UndefinedResObjectException.java │ │ │ │ ├── mod │ │ │ │ └── SmaliMod.java │ │ │ │ ├── res │ │ │ │ ├── Framework.java │ │ │ │ ├── ResourcesDecoder.java │ │ │ │ ├── data │ │ │ │ │ ├── ResConfigFlags.java │ │ │ │ │ ├── ResID.java │ │ │ │ │ ├── ResPackage.java │ │ │ │ │ ├── ResResSpec.java │ │ │ │ │ ├── ResResource.java │ │ │ │ │ ├── ResTable.java │ │ │ │ │ ├── ResType.java │ │ │ │ │ ├── ResTypeSpec.java │ │ │ │ │ ├── ResValuesFile.java │ │ │ │ │ ├── arsc │ │ │ │ │ │ ├── ARSCData.java │ │ │ │ │ │ ├── ARSCHeader.java │ │ │ │ │ │ ├── EntryData.java │ │ │ │ │ │ ├── FlagItem.java │ │ │ │ │ │ └── FlagsOffset.java │ │ │ │ │ ├── axml │ │ │ │ │ │ └── NamespaceStack.java │ │ │ │ │ ├── ninepatch │ │ │ │ │ │ ├── NinePatchData.java │ │ │ │ │ │ └── OpticalInset.java │ │ │ │ │ └── value │ │ │ │ │ │ ├── ResArrayValue.java │ │ │ │ │ │ ├── ResAttr.java │ │ │ │ │ │ ├── ResBagValue.java │ │ │ │ │ │ ├── ResBoolValue.java │ │ │ │ │ │ ├── ResColorValue.java │ │ │ │ │ │ ├── ResDimenValue.java │ │ │ │ │ │ ├── ResEmptyValue.java │ │ │ │ │ │ ├── ResEnumAttr.java │ │ │ │ │ │ ├── ResFileValue.java │ │ │ │ │ │ ├── ResFlagsAttr.java │ │ │ │ │ │ ├── ResFloatValue.java │ │ │ │ │ │ ├── ResFractionValue.java │ │ │ │ │ │ ├── ResIdValue.java │ │ │ │ │ │ ├── ResIntBasedValue.java │ │ │ │ │ │ ├── ResIntValue.java │ │ │ │ │ │ ├── ResPluralsValue.java │ │ │ │ │ │ ├── ResReferenceValue.java │ │ │ │ │ │ ├── ResScalarValue.java │ │ │ │ │ │ ├── ResStringValue.java │ │ │ │ │ │ ├── ResStyleValue.java │ │ │ │ │ │ ├── ResValue.java │ │ │ │ │ │ └── ResValueFactory.java │ │ │ │ ├── decoder │ │ │ │ │ ├── ARSCDecoder.java │ │ │ │ │ ├── AXmlResourceParser.java │ │ │ │ │ ├── AndroidManifestResourceParser.java │ │ │ │ │ ├── Res9patchStreamDecoder.java │ │ │ │ │ ├── ResFileDecoder.java │ │ │ │ │ ├── ResRawStreamDecoder.java │ │ │ │ │ ├── ResStreamDecoder.java │ │ │ │ │ ├── ResStreamDecoderContainer.java │ │ │ │ │ ├── StringBlock.java │ │ │ │ │ ├── StyledString.java │ │ │ │ │ └── XmlPullStreamDecoder.java │ │ │ │ ├── util │ │ │ │ │ ├── ExtMXSerializer.java │ │ │ │ │ └── ExtXmlSerializer.java │ │ │ │ └── xml │ │ │ │ │ ├── ResValuesXmlSerializable.java │ │ │ │ │ ├── ResXmlEncodable.java │ │ │ │ │ ├── ResXmlEncoders.java │ │ │ │ │ └── ResXmlPatcher.java │ │ │ │ └── src │ │ │ │ ├── SmaliBuilder.java │ │ │ │ └── SmaliDecoder.java │ │ └── org │ │ │ └── xmlpull │ │ │ └── renamed │ │ │ └── MXSerializer.java │ │ └── resources │ │ └── properties │ │ └── apktool.properties ├── brut.j.common │ ├── .gitignore │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── brut │ │ └── common │ │ ├── BrutException.java │ │ ├── InvalidUnknownFileException.java │ │ ├── RootUnknownFileException.java │ │ └── TraversalUnknownFileException.java ├── brut.j.core │ ├── .gitignore │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── mcal │ │ └── androlib │ │ ├── FastXmlSerializer.java │ │ ├── KXmlSerializer.java │ │ ├── LanguageMapping.java │ │ ├── NamespaceManager.java │ │ ├── ResSmaliIdProvider.java │ │ ├── ResourceIdProvider.java │ │ └── utils │ │ ├── Aapt.kt │ │ ├── Aapt2.kt │ │ ├── CharSequenceTranslator.kt │ │ ├── FileHelper.kt │ │ ├── LogHelper.kt │ │ ├── Logger.java │ │ └── StringEscapeUtils.kt ├── brut.j.dir │ ├── .gitignore │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── brut │ │ └── directory │ │ ├── AbstractDirectory.java │ │ ├── DirUtil.java │ │ ├── Directory.java │ │ ├── DirectoryException.java │ │ ├── ExtFile.java │ │ ├── FileDirectory.java │ │ ├── PathAlreadyExists.java │ │ ├── PathNotExist.java │ │ ├── ZipRODirectory.java │ │ └── ZipUtils.java └── brut.j.util │ ├── .gitignore │ ├── build.gradle │ └── src │ └── main │ └── java │ └── brut │ └── util │ ├── BrutIO.java │ ├── DataInputDelegate.java │ ├── Duo.java │ ├── ExtCountingDataInput.java │ ├── ExtDataInput.java │ ├── Jar.java │ └── OS.java ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── mcal │ │ └── example │ │ ├── MainActivity.kt │ │ └── utils │ │ ├── ApktoolHelper.java │ │ ├── FileHelper.kt │ │ └── Preferences.java │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ └── ic_launcher_background.xml │ ├── layout │ └── activity_main.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-mdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-xhdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-xxhdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-xxxhdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── values-ru │ └── strings.xml │ ├── values │ └── strings.xml │ └── xml │ └── network.xml ├── build.gradle ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── jitpack.yml ├── local.properties ├── settings.gradle └── xpp3 ├── .gitignore ├── build.gradle └── src └── main ├── AndroidManifest.xml └── java └── com └── mcal └── xmlpull └── v1 ├── dom2_builder └── DOM2XmlPullBuilder.java ├── parser_pool └── XmlPullParserPool.java ├── sax2 └── Driver.java ├── util └── XmlPullUtil.java ├── wrapper ├── XmlPullParserWrapper.java ├── XmlPullWrapperFactory.java ├── XmlSerializerWrapper.java ├── classic │ ├── StaticXmlPullParserWrapper.java │ ├── StaticXmlSerializerWrapper.java │ ├── XmlPullParserDelegate.java │ └── XmlSerializerDelegate.java └── perftest │ └── Driver.java ├── xmlrpc ├── XmlRpcParser.java └── XmlRpcParserME.java └── xsd ├── XsdException.java ├── XsdPullFactory.java ├── XsdPullParser.java ├── XsdSerializer.java ├── impl ├── XsdTypePullParserImpl.java ├── XsdTypeSerializerImpl.java └── base64 │ ├── Base64.java │ ├── Base64DecodingException.java │ ├── Base64DecodingState.java │ ├── Base64EncodingException.java │ └── Base64EncodingState.java └── package.html /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | !gradle/wrapper/gradle-wrapper.jar 4 | !**/src/main/**/build/ 5 | !**/src/test/**/build/ 6 | 7 | ### IntelliJ IDEA ### 8 | .idea/modules.xml 9 | .idea/jarRepositories.xml 10 | .idea/compiler.xml 11 | .idea/libraries/ 12 | *.iws 13 | *.iml 14 | *.ipr 15 | out/ 16 | !**/src/main/**/out/ 17 | !**/src/test/**/out/ 18 | 19 | ### Eclipse ### 20 | .apt_generated 21 | .classpath 22 | .factorypath 23 | .project 24 | .settings 25 | .springBeans 26 | .sts4-cache 27 | bin/ 28 | !**/src/main/**/bin/ 29 | !**/src/test/**/bin/ 30 | 31 | ### NetBeans ### 32 | /nbproject/private/ 33 | /nbbuild/ 34 | /dist/ 35 | /nbdist/ 36 | /.nb-gradle/ 37 | 38 | ### VS Code ### 39 | .vscode/ 40 | 41 | ### Mac OS ### 42 | .DS_Store 43 | 44 | ### KMP ### 45 | /wix311 46 | .idea/workspace.xml 47 | -------------------------------------------------------------------------------- /.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 26 | 27 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/migrations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ART/screenshot_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/ART/screenshot_1.png -------------------------------------------------------------------------------- /ART/screenshot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/ART/screenshot_2.png -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | ### ApkTool [2.9.2][1] for Android 2 | 3 | [![](https://jitpack.io/v/timscriptov/android-apktool.svg)](https://jitpack.io/#timscriptov/android-apktool) 4 | 5 | # Screenshot 6 | | ![Decode](/ART/screenshot_1.png) | ![Build](/ART/screenshot_2.png) | 7 | |----------------------------------|---------------------------------| 8 | 9 | [1]: https://github.com/iBotPeaches/Apktool/commit/69914eb5966490f8b987e4072746e026de23218e 10 | 11 | ## Add it in your root build.gradle at the end of repositories: 12 | ```groovy 13 | dependencyResolutionManagement { 14 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 15 | repositories { 16 | mavenCentral() 17 | maven { url 'https://jitpack.io' } 18 | } 19 | } 20 | ``` 21 | 22 | ## Add the dependency 23 | ```groovy 24 | dependencies { 25 | implementation("com.github.timscriptov:android-apktool:Tag") 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("org.jetbrains.kotlin.android") 4 | id("maven-publish") 5 | } 6 | 7 | group = 'com.mcal' 8 | version = project.artifactVersionName 9 | 10 | android { 11 | compileSdk project.compileSDK.toInteger() 12 | 13 | defaultConfig { 14 | minSdk project.minSDK.toInteger() 15 | targetSdk project.targetSDK.toInteger() 16 | 17 | aarMetadata { 18 | minCompileSdk = project.minSDK.toInteger() 19 | } 20 | } 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 25 | } 26 | } 27 | publishing { 28 | singleVariant('release') { 29 | withSourcesJar() 30 | withJavadocJar() 31 | } 32 | } 33 | kotlinOptions { 34 | jvmTarget = project.jvmTarget 35 | } 36 | compileOptions { 37 | sourceCompatibility project.sourceCompatibility.toInteger() 38 | targetCompatibility project.targetCompatibility.toInteger() 39 | } 40 | namespace 'com.mcal.androlib.lib' 41 | } 42 | 43 | dependencies { 44 | implementation project(':androlib:brut.j.dir') 45 | implementation project(':androlib:brut.j.util') 46 | implementation project(':androlib:brut.j.common') 47 | implementation project(':androlib:brut.j.core') 48 | implementation project(':xpp3') 49 | 50 | implementation(libs.smali.dexlib2) 51 | implementation(libs.smali) 52 | implementation(libs.smali.baksmali) 53 | 54 | implementation(libs.google.guava) 55 | implementation(libs.antlr) 56 | implementation(libs.annotations) 57 | implementation(libs.kotlinx.coroutines.core) 58 | implementation(libs.androidx.annotation) 59 | } 60 | 61 | publishing { 62 | publications { 63 | release(MavenPublication) { 64 | groupId = group 65 | artifactId = 'apktool-lib' 66 | version = version 67 | 68 | afterEvaluate { 69 | from components.release 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/AaptInvoker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib; 18 | 19 | import brut.androlib.apk.ApkInfo; 20 | import brut.androlib.exceptions.AndrolibException; 21 | import com.mcal.androlib.utils.Aapt; 22 | import com.mcal.androlib.utils.Aapt2; 23 | 24 | import java.io.File; 25 | 26 | public class AaptInvoker { 27 | private final Config mConfig; 28 | private final ApkInfo mApkInfo; 29 | 30 | public AaptInvoker(Config config, ApkInfo apkInfo) { 31 | mConfig = config; 32 | mApkInfo = apkInfo; 33 | } 34 | 35 | public void invokeAapt(File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include) 36 | throws AndrolibException { 37 | if (mConfig.isAapt2()) { 38 | Aapt2.build(apkFile, include, manifest, resDir, mApkInfo.getMinSdkVersion(), mApkInfo.getTargetSdkVersion(), mConfig.aapt2Path, mConfig.decodeAllPackages); 39 | } else { 40 | Aapt.build(apkFile, include, manifest, resDir, mApkInfo.getMinSdkVersion(), mApkInfo.getTargetSdkVersion(), mConfig.aaptPath, mConfig.decodeAllPackages); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApktoolProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib; 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | import java.util.Properties; 22 | import java.util.logging.Logger; 23 | 24 | public class ApktoolProperties { 25 | private static final Logger LOGGER = Logger.getLogger(ApktoolProperties.class.getName()); 26 | 27 | private static Properties sProps; 28 | 29 | public static String get(String key) { 30 | return get().getProperty(key); 31 | } 32 | 33 | public static Properties get() { 34 | if (sProps == null) { 35 | loadProps(); 36 | } 37 | return sProps; 38 | } 39 | 40 | public static String getVersion() { 41 | return get("application.version"); 42 | } 43 | 44 | private static void loadProps() { 45 | InputStream in = ApktoolProperties.class.getResourceAsStream("/properties/apktool.properties"); 46 | sProps = new Properties(); 47 | try { 48 | sProps.load(in); 49 | in.close(); 50 | } catch (IOException ex) { 51 | LOGGER.warning("Can't load properties."); 52 | } 53 | 54 | InputStream templateStream = null; 55 | try { 56 | templateStream = com.android.tools.smali.baksmali.Main.class.getClassLoader().getResourceAsStream("baksmali.properties"); 57 | } catch (NoClassDefFoundError ex) { 58 | LOGGER.warning("Can't load baksmali properties."); 59 | } 60 | Properties properties = new Properties(); 61 | String version = "(unknown)"; 62 | 63 | if (templateStream != null) { 64 | try { 65 | properties.load(templateStream); 66 | version = properties.getProperty("application.version"); 67 | templateStream.close(); 68 | } catch (IOException ignored) { 69 | } 70 | } 71 | sProps.put("baksmaliVersion", version); 72 | 73 | templateStream = null; 74 | try { 75 | templateStream = com.android.tools.smali.smali.Main.class.getClassLoader().getResourceAsStream("smali.properties"); 76 | } catch (NoClassDefFoundError ex) { 77 | LOGGER.warning("Can't load smali properties."); 78 | } 79 | properties = new Properties(); 80 | version = "(unknown)"; 81 | 82 | if (templateStream != null) { 83 | try { 84 | properties.load(templateStream); 85 | version = properties.getProperty("application.version"); 86 | templateStream.close(); 87 | } catch (IOException ignored) { 88 | } 89 | } 90 | sProps.put("smaliVersion", version); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/BackgroundWorker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib; 18 | 19 | import java.util.ArrayList; 20 | import java.util.concurrent.*; 21 | 22 | public class BackgroundWorker { 23 | private final ArrayList> mWorkerFutures = new ArrayList<>(); 24 | private final ExecutorService mExecutor; 25 | private volatile boolean mSubmitAllowed = true; 26 | 27 | public BackgroundWorker(int threads) { 28 | mExecutor = Executors.newFixedThreadPool(threads); 29 | } 30 | 31 | public void waitForFinish() { 32 | checkState(); 33 | mSubmitAllowed = false; 34 | for (Future future : mWorkerFutures) { 35 | try { 36 | future.get(); 37 | } catch (InterruptedException | ExecutionException e) { 38 | throw new RuntimeException(e); 39 | } 40 | } 41 | mWorkerFutures.clear(); 42 | mSubmitAllowed = true; 43 | } 44 | 45 | public void clearFutures() { 46 | mWorkerFutures.clear(); 47 | } 48 | 49 | private void checkState() { 50 | if (!mSubmitAllowed) { 51 | throw new IllegalStateException("BackgroundWorker is not ready"); 52 | } 53 | } 54 | 55 | public void shutdownNow() { 56 | mSubmitAllowed = false; 57 | mExecutor.shutdownNow(); 58 | } 59 | 60 | public ExecutorService getExecutor() { 61 | return mExecutor; 62 | } 63 | 64 | public void submit(Runnable task) { 65 | checkState(); 66 | mWorkerFutures.add(mExecutor.submit(task)); 67 | } 68 | 69 | public Future submit(Callable task) { 70 | checkState(); 71 | Future future = mExecutor.submit(task); 72 | mWorkerFutures.add(future); 73 | return future; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/PackageInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.apk; 18 | 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | public class PackageInfo implements YamlSerializable { 22 | public String forcedPackageId; 23 | public String renameManifestPackage; 24 | 25 | @Override 26 | public void readItem(@NotNull YamlReader reader) { 27 | YamlLine line = reader.getLine(); 28 | switch (line.getKey()) { 29 | case "forcedPackageId": { 30 | forcedPackageId = line.getValue(); 31 | break; 32 | } 33 | case "renameManifestPackage": { 34 | renameManifestPackage = line.getValue(); 35 | break; 36 | } 37 | } 38 | } 39 | 40 | @Override 41 | public void write(@NotNull YamlWriter writer) { 42 | writer.writeString("forcedPackageId", forcedPackageId); 43 | writer.writeString("renameManifestPackage", renameManifestPackage); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/UsesFramework.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.apk; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | public class UsesFramework implements YamlSerializable { 26 | public List ids; 27 | public String tag; 28 | 29 | @Override 30 | public void readItem(@NotNull YamlReader reader) throws AndrolibException { 31 | YamlLine line = reader.getLine(); 32 | switch (line.getKey()) { 33 | case "ids": { 34 | ids = new ArrayList<>(); 35 | reader.readIntList(ids); 36 | break; 37 | } 38 | case "tag": { 39 | tag = line.getValue(); 40 | break; 41 | } 42 | } 43 | } 44 | 45 | @Override 46 | public void write(@NotNull YamlWriter writer) { 47 | writer.writeList("ids", ids); 48 | writer.writeString("tag", tag); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/VersionInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.apk; 18 | 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | public class VersionInfo implements YamlSerializable { 22 | public String versionCode; 23 | public String versionName; 24 | 25 | @Override 26 | public void readItem(@NotNull YamlReader reader) { 27 | YamlLine line = reader.getLine(); 28 | switch (line.getKey()) { 29 | case "versionCode": { 30 | versionCode = line.getValue(); 31 | break; 32 | } 33 | case "versionName": { 34 | versionName = line.getValue(); 35 | break; 36 | } 37 | } 38 | } 39 | 40 | @Override 41 | public void write(@NotNull YamlWriter writer) { 42 | writer.writeString("versionCode", versionCode); 43 | writer.writeString("versionName", versionName); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlLine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.apk; 18 | 19 | import java.util.Objects; 20 | 21 | public class YamlLine { 22 | 23 | public int indent = 0; 24 | public boolean isComment; 25 | public boolean isEmpty; 26 | public boolean hasColon; 27 | public boolean isNull; 28 | public boolean isItem; 29 | private String key = ""; 30 | private String value = ""; 31 | 32 | public YamlLine(String line) { 33 | // special end line marker 34 | isNull = Objects.isNull(line); 35 | if (isNull) { 36 | return; 37 | } 38 | isEmpty = line.trim().isEmpty(); 39 | if (isEmpty) { 40 | return; 41 | } 42 | // count indent - space only 43 | for (int i = 0; i < line.length(); i++) { 44 | if (line.charAt(i) == ' ') { 45 | indent++; 46 | } else { 47 | break; 48 | } 49 | } 50 | // remove whitespace 51 | line = line.trim(); 52 | char first = line.charAt(0); 53 | 54 | isComment = first == '#' || first == '!'; 55 | isItem = first == '-'; 56 | if (isComment) { 57 | // for comment fill value 58 | value = line.substring(1).trim(); 59 | } else { 60 | // value line 61 | hasColon = line.contains(":"); 62 | if (isItem) { 63 | // array item line has only the value 64 | value = line.substring(1).trim(); 65 | } else { 66 | // split line to key - value 67 | String[] parts = line.split(":"); 68 | if (parts.length > 0) { 69 | key = parts[0].trim(); 70 | if (parts.length > 1) { 71 | value = parts[1].trim(); 72 | } 73 | } 74 | } 75 | } 76 | } 77 | 78 | public static String unescape(String value) { 79 | return YamlStringEscapeUtils.unescapeString(value); 80 | } 81 | 82 | public String getValue() { 83 | if (value.equals("null")) { 84 | return null; 85 | } 86 | String res = unescape(value); 87 | // remove quotation marks 88 | res = res.replaceAll("^\"|\"$", ""); 89 | res = res.replaceAll("^'|'$", ""); 90 | return res; 91 | } 92 | 93 | public String getKey() { 94 | String res = unescape(key); 95 | // remove quotation marks 96 | res = res.replaceAll("^\"|\"$", ""); 97 | res = res.replaceAll("^'|'$", ""); 98 | return res; 99 | } 100 | 101 | public boolean getValueBool() { 102 | return Objects.equals(value, "true"); 103 | } 104 | 105 | public int getValueInt() { 106 | return Integer.parseInt(value); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlSerializable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.apk; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | 21 | public interface YamlSerializable { 22 | void readItem(YamlReader reader) throws AndrolibException; 23 | 24 | void write(YamlWriter writer); 25 | } 26 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/exceptions/AXmlDecodingException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.exceptions; 18 | 19 | public class AXmlDecodingException extends AndrolibException { 20 | public AXmlDecodingException(String message, Throwable cause) { 21 | super(message, cause); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/exceptions/AndrolibException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.exceptions; 18 | 19 | import brut.common.BrutException; 20 | 21 | public class AndrolibException extends BrutException { 22 | public AndrolibException() { 23 | } 24 | 25 | public AndrolibException(String message) { 26 | super(message); 27 | } 28 | 29 | public AndrolibException(String message, Throwable cause) { 30 | super(message, cause); 31 | } 32 | 33 | public AndrolibException(Throwable cause) { 34 | super(cause); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/exceptions/CantFind9PatchChunkException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.exceptions; 18 | 19 | public class CantFind9PatchChunkException extends AndrolibException { 20 | public CantFind9PatchChunkException(String message, Throwable cause) { 21 | super(message, cause); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/exceptions/CantFindFrameworkResException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.exceptions; 18 | 19 | import java.util.Locale; 20 | 21 | public class CantFindFrameworkResException extends AndrolibException { 22 | private final int mPkgId; 23 | 24 | public CantFindFrameworkResException(int id) { 25 | mPkgId = id; 26 | } 27 | 28 | public int getPkgId() { 29 | return mPkgId; 30 | } 31 | 32 | @Override 33 | public String getMessage() { 34 | return String.format(Locale.getDefault(), "Can't find framework resources for package of id: %d", this.getPkgId()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/exceptions/InFileNotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.exceptions; 18 | 19 | public class InFileNotFoundException extends AndrolibException { 20 | public InFileNotFoundException() { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/exceptions/OutDirExistsException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.exceptions; 18 | 19 | public class OutDirExistsException extends AndrolibException { 20 | public OutDirExistsException() { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/exceptions/RawXmlEncounteredException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.exceptions; 18 | 19 | public class RawXmlEncounteredException extends AndrolibException { 20 | public RawXmlEncounteredException(String message, Throwable cause) { 21 | super(message, cause); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/exceptions/UndefinedResObjectException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.exceptions; 18 | 19 | public class UndefinedResObjectException extends AndrolibException { 20 | public UndefinedResObjectException(String message) { 21 | super(message); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/mod/SmaliMod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.mod; 18 | 19 | import com.android.tools.smali.dexlib2.writer.builder.DexBuilder; 20 | import com.android.tools.smali.smali.smaliFlexLexer; 21 | import com.android.tools.smali.smali.smaliParser; 22 | import com.android.tools.smali.smali.smaliTreeWalker; 23 | import org.antlr.runtime.CommonTokenStream; 24 | import org.antlr.runtime.RecognitionException; 25 | import org.antlr.runtime.Token; 26 | import org.antlr.runtime.tree.CommonTree; 27 | import org.antlr.runtime.tree.CommonTreeNodeStream; 28 | 29 | import java.io.*; 30 | import java.nio.charset.StandardCharsets; 31 | 32 | public class SmaliMod { 33 | public static boolean assembleSmaliFile(File smaliFile, DexBuilder dexBuilder, int apiLevel, boolean verboseErrors, 34 | boolean printTokens) throws IOException, RecognitionException, RuntimeException { 35 | 36 | CommonTokenStream tokens; 37 | smaliFlexLexer lexer; 38 | 39 | InputStream is = new FileInputStream(smaliFile); 40 | InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8); 41 | 42 | lexer = new smaliFlexLexer(reader, apiLevel); 43 | (lexer).setSourceFile(smaliFile); 44 | tokens = new CommonTokenStream(lexer); 45 | 46 | if (printTokens) { 47 | tokens.getTokens(); 48 | 49 | for (int i = 0; i < tokens.size(); i++) { 50 | Token token = tokens.get(i); 51 | if (token.getChannel() == smaliParser.HIDDEN) { 52 | continue; 53 | } 54 | 55 | System.out.println(smaliParser.tokenNames[token.getType()] + ": " + token.getText()); 56 | } 57 | } 58 | 59 | smaliParser parser = new smaliParser(tokens); 60 | parser.setApiLevel(apiLevel); 61 | parser.setVerboseErrors(verboseErrors); 62 | 63 | smaliParser.smali_file_return result = parser.smali_file(); 64 | 65 | if (parser.getNumberOfSyntaxErrors() > 0 || lexer.getNumberOfSyntaxErrors() > 0) { 66 | is.close(); 67 | reader.close(); 68 | String sourceName = lexer.getSourceName(); 69 | String errorMsg = "Source: " + sourceName + ";Line: " + lexer.getLine() + ";Column: " + lexer.getColumn(); 70 | throw new RuntimeException(errorMsg); 71 | } 72 | 73 | CommonTree t = result.getTree(); 74 | 75 | CommonTreeNodeStream treeStream = new CommonTreeNodeStream(t); 76 | treeStream.setTokenStream(tokens); 77 | 78 | smaliTreeWalker dexGen = new smaliTreeWalker(treeStream); 79 | dexGen.setApiLevel(apiLevel); 80 | dexGen.setVerboseErrors(verboseErrors); 81 | dexGen.setDexBuilder(dexBuilder); 82 | dexGen.smali_file(); 83 | 84 | is.close(); 85 | reader.close(); 86 | 87 | if (dexGen.getNumberOfSyntaxErrors() != 0) { 88 | String sourceName = lexer.getSourceName(); 89 | final String errorMsg = "Source: " + sourceName + ";Line: " + lexer.getLine() + ";Column: " + lexer.getColumn(); 90 | throw new RuntimeException(errorMsg); 91 | } 92 | 93 | return dexGen.getNumberOfSyntaxErrors() == 0; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data; 18 | 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | public class ResID { 22 | public final int pkgId; 23 | public final int type; 24 | public final int entry; 25 | public final int id; 26 | 27 | public ResID(int pkgId, int type, int entry) { 28 | this(pkgId, type, entry, (pkgId << 24) + (type << 16) + entry); 29 | } 30 | 31 | public ResID(int id) { 32 | this((id >> 24) & 0xff, (id >> 16) & 0x000000ff, id & 0x0000ffff, id); 33 | } 34 | 35 | public ResID(int pkgId, int type, int entry, int id) { 36 | this.pkgId = (pkgId == 0) ? 2 : pkgId; 37 | this.type = type; 38 | this.entry = entry; 39 | this.id = id; 40 | } 41 | 42 | @Override 43 | public @NotNull String toString() { 44 | return String.format("0x%08x", id); 45 | } 46 | 47 | @Override 48 | public int hashCode() { 49 | int hash = 17; 50 | hash = 31 * hash + this.id; 51 | return hash; 52 | } 53 | 54 | @Override 55 | public boolean equals(Object obj) { 56 | if (obj == null) { 57 | return false; 58 | } 59 | if (getClass() != obj.getClass()) { 60 | return false; 61 | } 62 | final ResID other = (ResID) obj; 63 | return this.id == other.id; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import brut.androlib.res.data.value.ResValue; 21 | 22 | public class ResResource { 23 | private final ResType mConfig; 24 | private final ResResSpec mResSpec; 25 | private final ResValue mValue; 26 | 27 | public ResResource(ResType config, ResResSpec spec, ResValue value) { 28 | this.mConfig = config; 29 | this.mResSpec = spec; 30 | this.mValue = value; 31 | } 32 | 33 | public String getFilePath() { 34 | return mResSpec.getType().getName() + mConfig.getFlags().getQualifiers() + "/" + mResSpec.getName(); 35 | } 36 | 37 | public ResType getConfig() { 38 | return mConfig; 39 | } 40 | 41 | public ResResSpec getResSpec() { 42 | return mResSpec; 43 | } 44 | 45 | public ResValue getValue() { 46 | return mValue; 47 | } 48 | 49 | public void replace(ResValue value) throws AndrolibException { 50 | ResResource res = new ResResource(mConfig, mResSpec, value); 51 | mConfig.addResource(res, true); 52 | mResSpec.addResource(res, true); 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return getFilePath(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import brut.androlib.exceptions.UndefinedResObjectException; 21 | import org.jetbrains.annotations.NotNull; 22 | 23 | import java.util.LinkedHashMap; 24 | import java.util.Map; 25 | 26 | public class ResType { 27 | private final ResConfigFlags mFlags; 28 | private final Map mResources = new LinkedHashMap<>(); 29 | 30 | public ResType(ResConfigFlags flags) { 31 | this.mFlags = flags; 32 | } 33 | 34 | public ResResource getResource(ResResSpec spec) throws AndrolibException { 35 | ResResource res = mResources.get(spec); 36 | if (res == null) { 37 | throw new UndefinedResObjectException(String.format("resource: spec=%s, config=%s", spec, this)); 38 | } 39 | return res; 40 | } 41 | 42 | public ResConfigFlags getFlags() { 43 | return mFlags; 44 | } 45 | 46 | public void addResource(ResResource res) throws AndrolibException { 47 | addResource(res, false); 48 | } 49 | 50 | public void addResource(@NotNull ResResource res, boolean overwrite) throws AndrolibException { 51 | ResResSpec spec = res.getResSpec(); 52 | if (mResources.put(spec, res) != null && !overwrite) { 53 | throw new AndrolibException(String.format("Multiple resources: spec=%s, config=%s", spec, this)); 54 | } 55 | } 56 | 57 | @Override 58 | public @NotNull String toString() { 59 | return mFlags.toString(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data; 18 | 19 | import androidx.annotation.NonNull; 20 | import brut.androlib.exceptions.AndrolibException; 21 | import brut.androlib.exceptions.UndefinedResObjectException; 22 | import org.jetbrains.annotations.NotNull; 23 | 24 | import java.util.LinkedHashMap; 25 | import java.util.Map; 26 | 27 | public final class ResTypeSpec { 28 | 29 | public static final String RES_TYPE_NAME_ARRAY = "array"; 30 | public static final String RES_TYPE_NAME_ATTR = "attr"; 31 | public static final String RES_TYPE_NAME_ATTR_PRIVATE = "^attr-private"; 32 | public static final String RES_TYPE_NAME_PLURALS = "plurals"; 33 | public static final String RES_TYPE_NAME_STRING = "string"; 34 | public static final String RES_TYPE_NAME_STYLES = "style"; 35 | 36 | private final String mName; 37 | private final Map mResSpecs = new LinkedHashMap<>(); 38 | 39 | private final int mId; 40 | 41 | public ResTypeSpec(String name, int id) { 42 | this.mName = name; 43 | this.mId = id; 44 | } 45 | 46 | public String getName() { 47 | return mName; 48 | } 49 | 50 | public int getId() { 51 | return mId; 52 | } 53 | 54 | public boolean isString() { 55 | return mName.equalsIgnoreCase(RES_TYPE_NAME_STRING); 56 | } 57 | 58 | public @NotNull ResResSpec getResSpec(String name) throws AndrolibException { 59 | ResResSpec spec = getResSpecUnsafe(name); 60 | if (spec == null) { 61 | throw new UndefinedResObjectException(String.format("resource spec: %s/%s", getName(), name)); 62 | } 63 | return spec; 64 | } 65 | 66 | public ResResSpec getResSpecUnsafe(String name) { 67 | return mResSpecs.get(name); 68 | } 69 | 70 | public void addResSpec(ResResSpec spec) throws AndrolibException { 71 | if (mResSpecs.put(spec.getName(), spec) != null) { 72 | throw new AndrolibException(String.format("Multiple res specs: %s/%s", getName(), spec.getName())); 73 | } 74 | } 75 | 76 | public void removeResSpec(@NonNull ResResSpec spec) { 77 | mResSpecs.remove(spec.getName()); 78 | } 79 | 80 | @Override 81 | public @NotNull String toString() { 82 | return mName; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResValuesFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data; 18 | 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | import java.util.LinkedHashSet; 22 | import java.util.Objects; 23 | import java.util.Set; 24 | 25 | public class ResValuesFile { 26 | private final ResPackage mPackage; 27 | private final ResTypeSpec mType; 28 | private final ResType mConfig; 29 | private final Set mResources = new LinkedHashSet<>(); 30 | 31 | public ResValuesFile(ResPackage pkg, ResTypeSpec type, ResType config) { 32 | this.mPackage = pkg; 33 | this.mType = type; 34 | this.mConfig = config; 35 | } 36 | 37 | public String getPath() { 38 | return "values" + mConfig.getFlags().getQualifiers() + "/" 39 | + mType.getName() + (mType.getName().endsWith("s") ? "" : "s") 40 | + ".xml"; 41 | } 42 | 43 | public Set listResources() { 44 | return mResources; 45 | } 46 | 47 | public ResTypeSpec getType() { 48 | return mType; 49 | } 50 | 51 | public boolean isSynthesized(@NotNull ResResource res) { 52 | return mPackage.isSynthesized(res.getResSpec().getId()); 53 | } 54 | 55 | public void addResource(ResResource res) { 56 | mResources.add(res); 57 | } 58 | 59 | @Override 60 | public boolean equals(Object obj) { 61 | if (obj == null) { 62 | return false; 63 | } 64 | if (getClass() != obj.getClass()) { 65 | return false; 66 | } 67 | final ResValuesFile other = (ResValuesFile) obj; 68 | if (!Objects.equals(this.mType, other.mType)) { 69 | return false; 70 | } 71 | return Objects.equals(this.mConfig, other.mConfig); 72 | } 73 | 74 | @Override 75 | public int hashCode() { 76 | int hash = 17; 77 | hash = 31 * hash + (this.mType != null ? this.mType.hashCode() : 0); 78 | hash = 31 * hash + (this.mConfig != null ? this.mConfig.hashCode() : 0); 79 | return hash; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/arsc/ARSCData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.arsc; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import brut.androlib.res.data.ResPackage; 21 | 22 | import java.util.logging.Logger; 23 | 24 | public class ARSCData { 25 | private static final Logger LOGGER = Logger.getLogger(ARSCData.class.getName()); 26 | private final ResPackage[] mPackages; 27 | private final FlagsOffset[] mFlagsOffsets; 28 | 29 | public ARSCData(ResPackage[] packages, FlagsOffset[] flagsOffsets) { 30 | mPackages = packages; 31 | mFlagsOffsets = flagsOffsets; 32 | } 33 | 34 | public FlagsOffset[] getFlagsOffsets() { 35 | return mFlagsOffsets; 36 | } 37 | 38 | public ResPackage[] getPackages() { 39 | return mPackages; 40 | } 41 | 42 | public ResPackage getOnePackage() throws AndrolibException { 43 | if (mPackages.length == 0) { 44 | throw new AndrolibException("Arsc file contains zero packages"); 45 | } else if (mPackages.length != 1) { 46 | int id = findPackageWithMostResSpecs(); 47 | LOGGER.info("Arsc file contains multiple packages. Using package " 48 | + mPackages[id].getName() + " as default."); 49 | 50 | return mPackages[id]; 51 | } 52 | return mPackages[0]; 53 | } 54 | 55 | public int findPackageWithMostResSpecs() { 56 | int count = mPackages[0].getResSpecCount(); 57 | int id = 0; 58 | 59 | for (int i = 0; i < mPackages.length; i++) { 60 | if (mPackages[i].getResSpecCount() >= count) { 61 | count = mPackages[i].getResSpecCount(); 62 | id = i; 63 | } 64 | } 65 | return id; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/arsc/EntryData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.arsc; 18 | 19 | import brut.androlib.res.data.value.ResValue; 20 | 21 | public class EntryData { 22 | public short mFlags; 23 | public int mSpecNamesId; 24 | public ResValue mValue; 25 | } 26 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/arsc/FlagItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.arsc; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import brut.androlib.res.data.value.ResReferenceValue; 21 | 22 | public class FlagItem { 23 | public final ResReferenceValue ref; 24 | public final int flag; 25 | public String value; 26 | 27 | public FlagItem(ResReferenceValue ref, int flag) { 28 | this.ref = ref; 29 | this.flag = flag; 30 | } 31 | 32 | public String getValue() throws AndrolibException { 33 | if (value == null) { 34 | if (ref.referentIsNull()) { 35 | return String.format("APKTOOL_MISSING_0x%08x", ref.getRawIntValue()); 36 | } 37 | value = ref.getReferent().getName(); 38 | } 39 | return value; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/arsc/FlagsOffset.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.arsc; 18 | 19 | public class FlagsOffset { 20 | public final int offset; 21 | public final int count; 22 | 23 | public FlagsOffset(int offset, int count) { 24 | this.offset = offset; 25 | this.count = count; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ninepatch/NinePatchData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.ninepatch; 18 | 19 | import brut.util.ExtDataInput; 20 | import org.jetbrains.annotations.Contract; 21 | import org.jetbrains.annotations.NotNull; 22 | 23 | import java.io.IOException; 24 | 25 | public class NinePatchData { 26 | public final int padLeft, padRight, padTop, padBottom; 27 | public final int[] xDivs, yDivs; 28 | 29 | public NinePatchData(int padLeft, int padRight, int padTop, int padBottom, int[] xDivs, int[] yDivs) { 30 | this.padLeft = padLeft; 31 | this.padRight = padRight; 32 | this.padTop = padTop; 33 | this.padBottom = padBottom; 34 | this.xDivs = xDivs; 35 | this.yDivs = yDivs; 36 | } 37 | 38 | @Contract("_ -> new") 39 | public static @NotNull NinePatchData decode(@NotNull ExtDataInput di) throws IOException { 40 | di.skipBytes(1); // wasDeserialized 41 | byte numXDivs = di.readByte(); 42 | byte numYDivs = di.readByte(); 43 | di.skipBytes(1); // numColors 44 | di.skipBytes(8); // xDivs/yDivs offset 45 | int padLeft = di.readInt(); 46 | int padRight = di.readInt(); 47 | int padTop = di.readInt(); 48 | int padBottom = di.readInt(); 49 | di.skipBytes(4); // colorsOffset 50 | int[] xDivs = di.readIntArray(numXDivs); 51 | int[] yDivs = di.readIntArray(numYDivs); 52 | 53 | return new NinePatchData(padLeft, padRight, padTop, padBottom, xDivs, yDivs); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ninepatch/OpticalInset.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.ninepatch; 18 | 19 | import brut.util.ExtDataInput; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | import java.io.IOException; 23 | 24 | public class OpticalInset { 25 | public final int layoutBoundsLeft, layoutBoundsTop, layoutBoundsRight, layoutBoundsBottom; 26 | 27 | public OpticalInset(int layoutBoundsLeft, int layoutBoundsTop, int layoutBoundsRight, int layoutBoundsBottom) { 28 | this.layoutBoundsLeft = layoutBoundsLeft; 29 | this.layoutBoundsTop = layoutBoundsTop; 30 | this.layoutBoundsRight = layoutBoundsRight; 31 | this.layoutBoundsBottom = layoutBoundsBottom; 32 | } 33 | 34 | public static @NotNull OpticalInset decode(@NotNull ExtDataInput di) throws IOException { 35 | int layoutBoundsLeft = Integer.reverseBytes(di.readInt()); 36 | int layoutBoundsTop = Integer.reverseBytes(di.readInt()); 37 | int layoutBoundsRight = Integer.reverseBytes(di.readInt()); 38 | int layoutBoundsBottom = Integer.reverseBytes(di.readInt()); 39 | return new OpticalInset(layoutBoundsLeft, layoutBoundsTop, layoutBoundsRight, layoutBoundsBottom); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResArrayValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import brut.androlib.res.data.ResResource; 21 | import brut.androlib.res.xml.ResValuesXmlSerializable; 22 | import brut.util.Duo; 23 | import org.jetbrains.annotations.NotNull; 24 | import org.xmlpull.v1.XmlSerializer; 25 | 26 | import java.io.IOException; 27 | import java.util.Arrays; 28 | 29 | public class ResArrayValue extends ResBagValue implements ResValuesXmlSerializable { 30 | private final ResScalarValue[] mItems; 31 | private final String[] AllowedArrayTypes = {"string", "integer"}; 32 | 33 | ResArrayValue(ResReferenceValue parent, Duo @NotNull [] items) { 34 | super(parent); 35 | 36 | mItems = new ResScalarValue[items.length]; 37 | for (int i = 0; i < items.length; i++) { 38 | mItems[i] = items[i].m2; 39 | } 40 | } 41 | 42 | public ResArrayValue(ResReferenceValue parent, ResScalarValue[] items) { 43 | super(parent); 44 | mItems = items; 45 | } 46 | 47 | @Override 48 | public void serializeToResValuesXml(@NotNull XmlSerializer serializer, 49 | @NotNull ResResource res) throws IOException, AndrolibException { 50 | String type = getType(); 51 | type = (type == null ? "" : type + "-") + "array"; 52 | serializer.startTag(null, type); 53 | serializer.attribute(null, "name", res.getResSpec().getName()); 54 | 55 | // lets check if we need to add formatted="false" to this array 56 | for (ResScalarValue item : mItems) { 57 | if (item.hasMultipleNonPositionalSubstitutions()) { 58 | serializer.attribute(null, "formatted", "false"); 59 | break; 60 | } 61 | } 62 | 63 | // add 's 64 | for (ResScalarValue mItem : mItems) { 65 | serializer.startTag(null, "item"); 66 | serializer.text(mItem.encodeAsResXmlNonEscapedItemValue()); 67 | serializer.endTag(null, "item"); 68 | } 69 | serializer.endTag(null, type); 70 | } 71 | 72 | public String getType() throws AndrolibException { 73 | if (mItems.length == 0) { 74 | return null; 75 | } 76 | String type = mItems[0].getType(); 77 | for (ResScalarValue mItem : mItems) { 78 | if (mItem.encodeAsResXmlItemValue().startsWith("@string")) { 79 | return "string"; 80 | } else if (mItem.encodeAsResXmlItemValue().startsWith("@drawable")) { 81 | return null; 82 | } else if (mItem.encodeAsResXmlItemValue().startsWith("@integer")) { 83 | return "integer"; 84 | } else if (!"string".equals(type) && !"integer".equals(type)) { 85 | return null; 86 | } else if (!type.equals(mItem.getType())) { 87 | return null; 88 | } 89 | } 90 | if (!Arrays.asList(AllowedArrayTypes).contains(type)) { 91 | return "string"; 92 | } 93 | return type; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBagValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import brut.androlib.res.data.ResResource; 21 | import brut.androlib.res.xml.ResValuesXmlSerializable; 22 | import brut.util.Duo; 23 | import org.jetbrains.annotations.NotNull; 24 | import org.xmlpull.v1.XmlSerializer; 25 | 26 | import java.io.IOException; 27 | 28 | public class ResBagValue extends ResValue implements ResValuesXmlSerializable { 29 | protected final ResReferenceValue mParent; 30 | 31 | public ResBagValue(ResReferenceValue parent) { 32 | this.mParent = parent; 33 | } 34 | 35 | @Override 36 | public void serializeToResValuesXml(XmlSerializer serializer, 37 | @NotNull ResResource res) throws IOException, AndrolibException { 38 | String type = res.getResSpec().getType().getName(); 39 | if ("style".equals(type)) { 40 | new ResStyleValue(mParent, new Duo[0], null).serializeToResValuesXml(serializer, res); 41 | return; 42 | } 43 | if ("array".equals(type)) { 44 | new ResArrayValue(mParent, new Duo[0]).serializeToResValuesXml(serializer, res); 45 | return; 46 | } 47 | if ("plurals".equals(type)) { 48 | new ResPluralsValue(mParent, new Duo[0]).serializeToResValuesXml(serializer, res); 49 | return; 50 | } 51 | 52 | serializer.startTag(null, "item"); 53 | serializer.attribute(null, "type", type); 54 | serializer.attribute(null, "name", res.getResSpec().getName()); 55 | serializer.endTag(null, "item"); 56 | } 57 | 58 | public ResReferenceValue getParent() { 59 | return mParent; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBoolValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | public class ResBoolValue extends ResScalarValue { 20 | private final boolean mValue; 21 | 22 | public ResBoolValue(boolean value, int rawIntValue, String rawValue) { 23 | super("bool", rawIntValue, rawValue); 24 | this.mValue = value; 25 | } 26 | 27 | public boolean getValue() { 28 | return mValue; 29 | } 30 | 31 | @Override 32 | protected String encodeAsResXml() { 33 | return mValue ? "true" : "false"; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResColorValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | public class ResColorValue extends ResIntValue { 20 | public ResColorValue(int value, String rawValue) { 21 | super(value, rawValue, "color"); 22 | } 23 | 24 | @Override 25 | protected String encodeAsResXml() { 26 | return String.format("#%08x", mValue); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResDimenValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import android.util.TypedValue; 20 | import brut.androlib.exceptions.AndrolibException; 21 | 22 | public class ResDimenValue extends ResIntValue { 23 | public ResDimenValue(int value, String rawValue) { 24 | super(value, rawValue, "dimen"); 25 | } 26 | 27 | @Override 28 | protected String encodeAsResXml() throws AndrolibException { 29 | return TypedValue.coerceToString(TypedValue.TYPE_DIMENSION, mValue); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEmptyValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | 21 | public class ResEmptyValue extends ResScalarValue { 22 | protected final int mValue; 23 | protected int type; 24 | 25 | public ResEmptyValue(int value, String rawValue, int type) { 26 | this(value, rawValue, "integer"); 27 | this.type = type; 28 | } 29 | 30 | public ResEmptyValue(int value, String rawValue, String type) { 31 | super(type, value, rawValue); 32 | if (value != 1) 33 | throw new UnsupportedOperationException(); 34 | this.mValue = value; 35 | } 36 | 37 | public int getValue() { 38 | return mValue; 39 | } 40 | 41 | @Override 42 | protected String encodeAsResXml() throws AndrolibException { 43 | return "@empty"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import brut.androlib.res.data.ResResSpec; 21 | import brut.androlib.res.data.ResResource; 22 | import brut.util.Duo; 23 | import org.xmlpull.v1.XmlSerializer; 24 | 25 | import java.io.IOException; 26 | import java.util.HashMap; 27 | import java.util.Map; 28 | import java.util.logging.Logger; 29 | 30 | public class ResEnumAttr extends ResAttr { 31 | private static final Logger LOGGER = Logger.getLogger(ResEnumAttr.class.getName()); 32 | private final Duo[] mItems; 33 | private final Map mItemsCache = new HashMap<>(); 34 | 35 | ResEnumAttr(ResReferenceValue parent, int type, Integer min, Integer max, 36 | Boolean l10n, Duo[] items) { 37 | super(parent, type, min, max, l10n); 38 | mItems = items; 39 | } 40 | 41 | @Override 42 | public String convertToResXmlFormat(ResScalarValue value) 43 | throws AndrolibException { 44 | if (value instanceof ResIntValue) { 45 | String ret = decodeValue(((ResIntValue) value).getValue()); 46 | if (ret != null) { 47 | return ret; 48 | } 49 | } 50 | return super.convertToResXmlFormat(value); 51 | } 52 | 53 | @Override 54 | protected void serializeBody(XmlSerializer serializer, ResResource res) throws AndrolibException, IOException { 55 | for (Duo duo : mItems) { 56 | int intVal = duo.m2.getRawIntValue(); 57 | 58 | // #2836 - Support skipping items if the resource cannot be identified. 59 | ResResSpec m1Referent = duo.m1.getReferent(); 60 | if (m1Referent == null && shouldRemoveUnknownRes()) { 61 | LOGGER.fine(String.format("null enum reference: m1=0x%08x(%s), m2=0x%08x(%s)", 62 | duo.m1.getRawIntValue(), duo.m1.getType(), duo.m2.getRawIntValue(), duo.m2.getType())); 63 | continue; 64 | } 65 | 66 | serializer.startTag(null, "enum"); 67 | serializer.attribute(null, "name", 68 | m1Referent != null ? m1Referent.getName() : String.format("APKTOOL_MISSING_0x%08x", duo.m1.getRawIntValue()) 69 | ); 70 | serializer.attribute(null, "value", String.valueOf(intVal)); 71 | serializer.endTag(null, "enum"); 72 | } 73 | } 74 | 75 | private String decodeValue(int value) throws AndrolibException { 76 | String value2 = mItemsCache.get(value); 77 | if (value2 == null) { 78 | ResReferenceValue ref = null; 79 | for (Duo duo : mItems) { 80 | if (duo.m2.getRawIntValue() == value) { 81 | ref = duo.m1; 82 | break; 83 | } 84 | } 85 | if (ref != null && !ref.referentIsNull()) { 86 | value2 = ref.getReferent().getName(); 87 | mItemsCache.put(value, value2); 88 | } 89 | } 90 | return value2; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFileValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | 21 | public class ResFileValue extends ResIntBasedValue { 22 | private final String mPath; 23 | 24 | public ResFileValue(String path, int rawIntValue) { 25 | super(rawIntValue); 26 | this.mPath = path; 27 | } 28 | 29 | public String getStrippedPath() throws AndrolibException { 30 | if (mPath.startsWith("res/")) { 31 | return mPath.substring(4); 32 | } 33 | if (mPath.startsWith("r/") || mPath.startsWith("R/")) { 34 | return mPath.substring(2); 35 | } 36 | throw new AndrolibException("File path does not start with \"res/\" or \"r/\": " + mPath); 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return mPath; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFloatValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | public class ResFloatValue extends ResScalarValue { 20 | private final float mValue; 21 | 22 | public ResFloatValue(float value, int rawIntValue, String rawValue) { 23 | super("float", rawIntValue, rawValue); 24 | this.mValue = value; 25 | } 26 | 27 | public float getValue() { 28 | return mValue; 29 | } 30 | 31 | @Override 32 | protected String encodeAsResXml() { 33 | return String.valueOf(mValue); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFractionValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import android.util.TypedValue; 20 | import brut.androlib.exceptions.AndrolibException; 21 | 22 | public class ResFractionValue extends ResIntValue { 23 | public ResFractionValue(int value, String rawValue) { 24 | super(value, rawValue, "fraction"); 25 | } 26 | 27 | @Override 28 | protected String encodeAsResXml() throws AndrolibException { 29 | return TypedValue.coerceToString(TypedValue.TYPE_FRACTION, mValue); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIdValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import brut.androlib.res.data.ResResource; 20 | import brut.androlib.res.xml.ResValuesXmlSerializable; 21 | import org.jetbrains.annotations.NotNull; 22 | import org.xmlpull.v1.XmlSerializer; 23 | 24 | import java.io.IOException; 25 | 26 | public class ResIdValue extends ResValue implements ResValuesXmlSerializable { 27 | @Override 28 | public void serializeToResValuesXml(@NotNull XmlSerializer serializer, @NotNull ResResource res) throws IOException { 29 | serializer.startTag(null, "item"); 30 | serializer.attribute(null, "type", res.getResSpec().getType().getName()); 31 | serializer.attribute(null, "name", res.getResSpec().getName()); 32 | serializer.endTag(null, "item"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntBasedValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | public class ResIntBasedValue extends ResValue { 20 | private final int mRawIntValue; 21 | 22 | protected ResIntBasedValue(int rawIntValue) { 23 | mRawIntValue = rawIntValue; 24 | } 25 | 26 | public int getRawIntValue() { 27 | return mRawIntValue; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import android.util.TypedValue; 20 | import brut.androlib.exceptions.AndrolibException; 21 | 22 | public class ResIntValue extends ResScalarValue { 23 | protected final int mValue; 24 | private int type; 25 | 26 | public ResIntValue(int value, String rawValue, int type) { 27 | this(value, rawValue, "integer"); 28 | this.type = type; 29 | } 30 | 31 | public ResIntValue(int value, String rawValue, String type) { 32 | super(type, value, rawValue); 33 | this.mValue = value; 34 | } 35 | 36 | public int getValue() { 37 | return mValue; 38 | } 39 | 40 | @Override 41 | protected String encodeAsResXml() throws AndrolibException { 42 | return TypedValue.coerceToString(type, mValue); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResPluralsValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import brut.androlib.res.data.ResResource; 21 | import brut.androlib.res.xml.ResValuesXmlSerializable; 22 | import brut.androlib.res.xml.ResXmlEncoders; 23 | import brut.util.Duo; 24 | import org.jetbrains.annotations.NotNull; 25 | import org.xmlpull.v1.XmlSerializer; 26 | 27 | import java.io.IOException; 28 | 29 | public class ResPluralsValue extends ResBagValue implements ResValuesXmlSerializable { 30 | public static final int BAG_KEY_PLURALS_START = 0x01000004; 31 | private static final String[] QUANTITY_MAP = new String[]{"other", "zero", "one", "two", "few", "many"}; 32 | private final ResScalarValue[] mItems; 33 | 34 | ResPluralsValue(ResReferenceValue parent, Duo @NotNull [] items) { 35 | super(parent); 36 | 37 | mItems = new ResScalarValue[6]; 38 | for (Duo item : items) { 39 | mItems[item.m1 - BAG_KEY_PLURALS_START] = item.m2; 40 | } 41 | } 42 | 43 | @Override 44 | public void serializeToResValuesXml(@NotNull XmlSerializer serializer, 45 | @NotNull ResResource res) throws IOException, AndrolibException { 46 | serializer.startTag(null, "plurals"); 47 | serializer.attribute(null, "name", res.getResSpec().getName()); 48 | for (int i = 0; i < mItems.length; i++) { 49 | ResScalarValue item = mItems[i]; 50 | if (item == null) { 51 | continue; 52 | } 53 | 54 | serializer.startTag(null, "item"); 55 | serializer.attribute(null, "quantity", QUANTITY_MAP[i]); 56 | serializer.text(ResXmlEncoders.enumerateNonPositionalSubstitutionsIfRequired(item.encodeAsResXmlNonEscapedItemValue())); 57 | serializer.endTag(null, "item"); 58 | } 59 | serializer.endTag(null, "plurals"); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResReferenceValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import brut.androlib.exceptions.UndefinedResObjectException; 21 | import brut.androlib.res.data.ResPackage; 22 | import brut.androlib.res.data.ResResSpec; 23 | 24 | public class ResReferenceValue extends ResIntValue { 25 | private final ResPackage mPackage; 26 | private final boolean mTheme; 27 | 28 | public ResReferenceValue(ResPackage package_, int value, String rawValue) { 29 | this(package_, value, rawValue, false); 30 | } 31 | 32 | public ResReferenceValue(ResPackage package_, int value, String rawValue, 33 | boolean theme) { 34 | super(value, rawValue, "reference"); 35 | mPackage = package_; 36 | mTheme = theme; 37 | } 38 | 39 | @Override 40 | protected String encodeAsResXml() throws AndrolibException { 41 | if (isNull()) { 42 | return "@null"; 43 | } 44 | 45 | ResResSpec spec = getReferent(); 46 | if (spec == null) { 47 | return "@null"; 48 | } 49 | boolean newId = spec.hasDefaultResource() && spec.getDefaultResource().getValue() instanceof ResIdValue; 50 | 51 | // generate the beginning to fix @android 52 | String mStart = (mTheme ? '?' : '@') + (newId ? "+" : ""); 53 | 54 | return mStart + spec.getFullName(mPackage, mTheme && spec.getType().getName().equals("attr")); 55 | } 56 | 57 | public ResResSpec getReferent() throws AndrolibException { 58 | try { 59 | return mPackage.getResTable().getResSpec(getValue()); 60 | } catch (UndefinedResObjectException ex) { 61 | return null; 62 | } 63 | } 64 | 65 | public boolean isNull() { 66 | return mValue == 0; 67 | } 68 | 69 | public boolean referentIsNull() throws AndrolibException { 70 | return getReferent() == null; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStringValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import brut.androlib.res.data.ResResource; 21 | import brut.androlib.res.xml.ResXmlEncoders; 22 | import org.xmlpull.v1.XmlSerializer; 23 | 24 | import java.io.IOException; 25 | import java.util.regex.Pattern; 26 | 27 | public class ResStringValue extends ResScalarValue { 28 | private static final Pattern allDigits = Pattern.compile("\\d{9,}"); 29 | 30 | public ResStringValue(String value, int rawValue) { 31 | this(value, rawValue, "string"); 32 | } 33 | 34 | public ResStringValue(String value, int rawValue, String type) { 35 | super(type, rawValue, value); 36 | } 37 | 38 | @Override 39 | public String encodeAsResXmlAttr() { 40 | return checkIfStringIsNumeric(ResXmlEncoders.encodeAsResXmlAttr(mRawValue)); 41 | } 42 | 43 | @Override 44 | public String encodeAsResXmlItemValue() { 45 | return ResXmlEncoders.enumerateNonPositionalSubstitutionsIfRequired(ResXmlEncoders.encodeAsXmlValue(mRawValue)); 46 | } 47 | 48 | @Override 49 | public String encodeAsResXmlValue() { 50 | return ResXmlEncoders.encodeAsXmlValue(mRawValue); 51 | } 52 | 53 | @Override 54 | protected String encodeAsResXml() throws AndrolibException { 55 | throw new UnsupportedOperationException(); 56 | } 57 | 58 | @Override 59 | protected void serializeExtraXmlAttrs(XmlSerializer serializer, ResResource res) throws IOException { 60 | if (ResXmlEncoders.hasMultipleNonPositionalSubstitutions(mRawValue)) { 61 | serializer.attribute(null, "formatted", "false"); 62 | } 63 | } 64 | 65 | private String checkIfStringIsNumeric(String val) { 66 | if (val == null || val.isEmpty()) { 67 | return val; 68 | } 69 | return allDigits.matcher(val).matches() ? "\\ " + val : val; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.data.value; 18 | 19 | import brut.androlib.Config; 20 | 21 | public class ResValue { 22 | public boolean shouldRemoveUnknownRes() { 23 | return Config.getInstance().isDecodeResolveModeRemoving(); 24 | } 25 | 26 | public boolean isAnalysisMode() { 27 | return Config.getInstance().analysisMode; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AndroidManifestResourceParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.decoder; 18 | 19 | import android.util.TypedValue; 20 | import brut.androlib.res.data.ResTable; 21 | 22 | import java.util.regex.Pattern; 23 | 24 | /** 25 | * AXmlResourceParser specifically for parsing encoded AndroidManifest.xml. 26 | */ 27 | public class AndroidManifestResourceParser extends AXmlResourceParser { 28 | 29 | /** 30 | * Pattern for matching numeric string meta-data values. aapt automatically infers the 31 | * type for a manifest meta-data value based on the string in the unencoded XML. However, 32 | * some apps intentionally coerce integers to be strings by prepending an escaped space. 33 | * For details/discussion, see https://stackoverflow.com/questions/2154945/how-to-force-a-meta-data-value-to-type-string 34 | * With aapt1, the escaped space is dropped when encoded. For aapt2, the escaped space is preserved. 35 | */ 36 | private static final Pattern PATTERN_NUMERIC_STRING = Pattern.compile("\\s?\\d+"); 37 | 38 | public AndroidManifestResourceParser(ResTable resTable) { 39 | super(resTable); 40 | } 41 | 42 | @Override 43 | public String getAttributeValue(int index) { 44 | String value = super.getAttributeValue(index); 45 | if (value == null) { 46 | return ""; 47 | } 48 | 49 | if (!isNumericStringMetadataAttributeValue(index, value)) { 50 | return value; 51 | } 52 | 53 | // Patch the numeric string value by prefixing it with an escaped space. 54 | // Otherwise, when the decoded app is rebuilt, aapt will incorrectly encode 55 | // the value as an int or float (depending on aapt version), breaking the original 56 | // app functionality. 57 | return "\\ " + value.trim(); 58 | } 59 | 60 | private boolean isNumericStringMetadataAttributeValue(int index, String value) { 61 | return "meta-data".equalsIgnoreCase(super.getName()) 62 | && "value".equalsIgnoreCase(super.getAttributeName(index)) 63 | && super.getAttributeValueType(index) == TypedValue.TYPE_STRING 64 | && PATTERN_NUMERIC_STRING.matcher(value).matches(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResRawStreamDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.decoder; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import com.mcal.androlib.utils.FileHelper; 21 | 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.io.OutputStream; 25 | 26 | public class ResRawStreamDecoder implements ResStreamDecoder { 27 | @Override 28 | public void decode(InputStream in, OutputStream out) 29 | throws AndrolibException { 30 | try { 31 | FileHelper.copyFile(in, out); 32 | } catch (IOException ex) { 33 | throw new AndrolibException("Could not decode raw stream", ex); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.decoder; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | 21 | import java.io.InputStream; 22 | import java.io.OutputStream; 23 | 24 | public interface ResStreamDecoder { 25 | void decode(InputStream in, OutputStream out) 26 | throws AndrolibException; 27 | } 28 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoderContainer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.decoder; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | 21 | import java.io.InputStream; 22 | import java.io.OutputStream; 23 | import java.util.HashMap; 24 | import java.util.Map; 25 | 26 | public class ResStreamDecoderContainer { 27 | private final Map mDecoders = new HashMap<>(); 28 | 29 | public void decode(InputStream in, OutputStream out, String decoderName) 30 | throws AndrolibException { 31 | getDecoder(decoderName).decode(in, out); 32 | } 33 | 34 | public ResStreamDecoder getDecoder(String name) throws AndrolibException { 35 | ResStreamDecoder decoder = mDecoders.get(name); 36 | if (decoder == null) { 37 | throw new AndrolibException("Undefined decoder: " + name); 38 | } 39 | return decoder; 40 | } 41 | 42 | public void setDecoder(String name, ResStreamDecoder decoder) { 43 | mDecoders.put(name, decoder); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtMXSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.util; 18 | 19 | import org.xmlpull.renamed.MXSerializer; 20 | 21 | import java.io.IOException; 22 | import java.io.OutputStream; 23 | import java.io.Writer; 24 | 25 | public class ExtMXSerializer extends MXSerializer implements ExtXmlSerializer { 26 | private String mDefaultEncoding; 27 | private boolean mIsDisabledAttrEscape = false; 28 | 29 | @Override 30 | public void startDocument(String encoding, Boolean standalone) 31 | throws IOException, IllegalArgumentException, IllegalStateException { 32 | super.startDocument(encoding != null ? encoding : mDefaultEncoding, standalone); 33 | this.newLine(); 34 | } 35 | 36 | @Override 37 | protected void writeAttributeValue(String value, Writer out) throws IOException { 38 | if (mIsDisabledAttrEscape) { 39 | out.write(value == null ? "" : value); 40 | return; 41 | } 42 | super.writeAttributeValue(value, out); 43 | } 44 | 45 | @Override 46 | public void setOutput(OutputStream os, String encoding) throws IOException { 47 | super.setOutput(os, encoding != null ? encoding : mDefaultEncoding); 48 | } 49 | 50 | @Override 51 | public Object getProperty(String name) throws IllegalArgumentException { 52 | if (PROPERTY_DEFAULT_ENCODING.equals(name)) { 53 | return mDefaultEncoding; 54 | } 55 | return super.getProperty(name); 56 | } 57 | 58 | @Override 59 | public void setProperty(String name, Object value) throws IllegalArgumentException, IllegalStateException { 60 | if (PROPERTY_DEFAULT_ENCODING.equals(name)) { 61 | mDefaultEncoding = (String) value; 62 | } else { 63 | super.setProperty(name, value); 64 | } 65 | } 66 | 67 | @Override 68 | public ExtXmlSerializer newLine() throws IOException { 69 | super.out.write(lineSeparator); 70 | return this; 71 | } 72 | 73 | @Override 74 | public void setDisabledAttrEscape(boolean disabled) { 75 | mIsDisabledAttrEscape = disabled; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtXmlSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.util; 18 | 19 | import org.xmlpull.v1.XmlSerializer; 20 | 21 | import java.io.IOException; 22 | 23 | public interface ExtXmlSerializer extends XmlSerializer { 24 | 25 | String PROPERTY_SERIALIZER_INDENTATION = "http://xmlpull.org/v1/doc/properties.html#serializer-indentation"; 26 | String PROPERTY_SERIALIZER_LINE_SEPARATOR = "http://xmlpull.org/v1/doc/properties.html#serializer-line-separator"; 27 | String PROPERTY_DEFAULT_ENCODING = "DEFAULT_ENCODING"; 28 | 29 | ExtXmlSerializer newLine() throws IOException; 30 | 31 | void setDisabledAttrEscape(boolean disabled); 32 | } 33 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResValuesXmlSerializable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.xml; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import brut.androlib.res.data.ResResource; 21 | import org.xmlpull.v1.XmlSerializer; 22 | 23 | import java.io.IOException; 24 | 25 | public interface ResValuesXmlSerializable { 26 | void serializeToResValuesXml(XmlSerializer serializer, 27 | ResResource res) throws IOException, AndrolibException; 28 | } 29 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncodable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.res.xml; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | 21 | public interface ResXmlEncodable { 22 | String encodeAsResXmlAttr() throws AndrolibException; 23 | 24 | String encodeAsResXmlValue() throws AndrolibException; 25 | } 26 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.androlib.src; 18 | 19 | import brut.androlib.exceptions.AndrolibException; 20 | import brut.androlib.mod.SmaliMod; 21 | import brut.directory.DirectoryException; 22 | import brut.directory.ExtFile; 23 | import com.android.tools.smali.dexlib2.Opcodes; 24 | import com.android.tools.smali.dexlib2.writer.builder.DexBuilder; 25 | import com.android.tools.smali.dexlib2.writer.io.FileDataStore; 26 | import org.antlr.runtime.RecognitionException; 27 | 28 | import java.io.File; 29 | import java.io.FileInputStream; 30 | import java.io.IOException; 31 | import java.io.InputStream; 32 | import java.util.logging.Logger; 33 | 34 | public class SmaliBuilder { 35 | 36 | private final static Logger LOGGER = Logger.getLogger(SmaliBuilder.class.getName()); 37 | private final ExtFile mSmaliDir; 38 | private final File mDexFile; 39 | private final int mApiLevel; 40 | 41 | private SmaliBuilder(ExtFile smaliDir, File dexFile, int apiLevel) { 42 | mSmaliDir = smaliDir; 43 | mDexFile = dexFile; 44 | mApiLevel = apiLevel; 45 | } 46 | 47 | public static void build(ExtFile smaliDir, File dexFile, int apiLevel) throws AndrolibException { 48 | new SmaliBuilder(smaliDir, dexFile, apiLevel).build(); 49 | } 50 | 51 | private void build() throws AndrolibException { 52 | try { 53 | DexBuilder dexBuilder; 54 | if (mApiLevel > 0) { 55 | dexBuilder = new DexBuilder(Opcodes.forApi(mApiLevel)); 56 | } else { 57 | dexBuilder = new DexBuilder(Opcodes.getDefault()); 58 | } 59 | 60 | for (String fileName : mSmaliDir.getDirectory().getFiles(true)) { 61 | buildFile(fileName, dexBuilder); 62 | } 63 | dexBuilder.writeTo(new FileDataStore(new File(mDexFile.getAbsolutePath()))); 64 | } catch (IOException | DirectoryException ex) { 65 | throw new AndrolibException(ex); 66 | } 67 | } 68 | 69 | private void buildFile(String fileName, DexBuilder dexBuilder) 70 | throws AndrolibException, IOException { 71 | File inFile = new File(mSmaliDir, fileName); 72 | InputStream inStream = new FileInputStream(inFile); 73 | 74 | if (fileName.endsWith(".smali")) { 75 | try { 76 | if (!SmaliMod.assembleSmaliFile(inFile, dexBuilder, mApiLevel, false, false)) { 77 | throw new AndrolibException("Could not smali file: " + fileName); 78 | } 79 | } catch (IOException | RecognitionException ex) { 80 | throw new AndrolibException(ex); 81 | } 82 | } else { 83 | LOGGER.warning("Unknown file type, ignoring: " + inFile); 84 | } 85 | inStream.close(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /androlib/brut.apktool/apktool-lib/src/main/resources/properties/apktool.properties: -------------------------------------------------------------------------------- 1 | application.version=2.9.1 2 | git.commit.id.abbrev=e5c88ece1b7881879ed1a6f65e5f81d3cf788c4c 3 | -------------------------------------------------------------------------------- /androlib/brut.j.common/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /androlib/brut.j.common/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("org.jetbrains.kotlin.android") 4 | id("maven-publish") 5 | } 6 | 7 | group = 'com.mcal' 8 | version = project.artifactVersionName 9 | 10 | android { 11 | compileSdk project.compileSDK.toInteger() 12 | 13 | defaultConfig { 14 | minSdk project.minSDK.toInteger() 15 | targetSdk project.targetSDK.toInteger() 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 21 | } 22 | } 23 | publishing { 24 | singleVariant('release') { 25 | withSourcesJar() 26 | withJavadocJar() 27 | } 28 | } 29 | kotlinOptions { 30 | jvmTarget = project.jvmTarget 31 | } 32 | compileOptions { 33 | sourceCompatibility project.sourceCompatibility.toInteger() 34 | targetCompatibility project.targetCompatibility.toInteger() 35 | } 36 | namespace 'com.mcal.androlib.common' 37 | } 38 | 39 | publishing { 40 | publications { 41 | release(MavenPublication) { 42 | groupId = group 43 | artifactId = 'apktool-common' 44 | version = version 45 | 46 | afterEvaluate { 47 | from components.release 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /androlib/brut.j.common/src/main/java/brut/common/BrutException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.common; 18 | 19 | public class BrutException extends Exception { 20 | public BrutException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public BrutException(String message, Throwable cause) { 25 | super(message, cause); 26 | } 27 | 28 | public BrutException(String message) { 29 | super(message); 30 | } 31 | 32 | public BrutException() { 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /androlib/brut.j.common/src/main/java/brut/common/InvalidUnknownFileException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.common; 18 | 19 | public class InvalidUnknownFileException extends BrutException { 20 | public InvalidUnknownFileException(String message) { 21 | super(message); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /androlib/brut.j.common/src/main/java/brut/common/RootUnknownFileException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.common; 18 | 19 | public class RootUnknownFileException extends BrutException { 20 | public RootUnknownFileException(String message) { 21 | super(message); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /androlib/brut.j.common/src/main/java/brut/common/TraversalUnknownFileException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.common; 18 | 19 | public class TraversalUnknownFileException extends BrutException { 20 | public TraversalUnknownFileException(String message) { 21 | super(message); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /androlib/brut.j.core/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /androlib/brut.j.core/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("org.jetbrains.kotlin.android") 4 | id("maven-publish") 5 | } 6 | 7 | group = 'com.mcal' 8 | version = project.artifactVersionName 9 | 10 | android { 11 | compileSdk project.compileSDK.toInteger() 12 | 13 | defaultConfig { 14 | minSdk project.minSDK.toInteger() 15 | targetSdk project.targetSDK.toInteger() 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 21 | } 22 | } 23 | publishing { 24 | singleVariant('release') { 25 | withSourcesJar() 26 | withJavadocJar() 27 | } 28 | } 29 | kotlinOptions { 30 | jvmTarget = project.jvmTarget 31 | } 32 | compileOptions { 33 | sourceCompatibility project.sourceCompatibility.toInteger() 34 | targetCompatibility project.targetCompatibility.toInteger() 35 | } 36 | namespace 'com.mcal.androlib.core' 37 | } 38 | 39 | dependencies { 40 | implementation fileTree(dir: 'libs', include: ['*.jar']) 41 | implementation project(':xpp3') 42 | 43 | implementation(libs.androidx.annotation) 44 | implementation(libs.annotations) 45 | } 46 | 47 | publishing { 48 | publications { 49 | release(MavenPublication) { 50 | groupId = group 51 | artifactId = 'apktool-core' 52 | version = version 53 | 54 | afterEvaluate { 55 | from components.release 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /androlib/brut.j.core/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /androlib/brut.j.core/src/main/java/com/mcal/androlib/NamespaceManager.java: -------------------------------------------------------------------------------- 1 | package com.mcal.androlib; 2 | 3 | import android.util.Pair; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.annotation.Nullable; 7 | 8 | import org.jetbrains.annotations.Contract; 9 | 10 | import java.util.ArrayList; 11 | 12 | public class NamespaceManager { 13 | 14 | private static final int defaultDepthSize = 4; 15 | 16 | // Each object is a hashmap 17 | private Object[] namespaces = new Object[defaultDepthSize]; 18 | // How many depth contain namespaces 19 | private int depthNum = 0; 20 | // Depth value last saved 21 | private int lastSavedDepth; 22 | 23 | // Get the name space from an array recrd 24 | @Nullable 25 | @Contract(pure = true) 26 | private String getName(@NonNull ArrayList> l, String uri) { 27 | for (Pair p : l) { 28 | if (p.second.equals(uri)) { 29 | return p.first; 30 | } 31 | } 32 | return null; 33 | } 34 | 35 | public String getNsName(int depth, String uri) { 36 | String name = null; 37 | // Special common case: only one depth contain namespace 38 | if (depthNum == 1) { 39 | ArrayList> t = (ArrayList>) namespaces[lastSavedDepth]; 40 | if (t != null) { 41 | // For one element, just return the ONLY namespace, correct??? 42 | if (t.size() == 1) { 43 | Pair ns = t.get(0); 44 | int len1 = ns.second.length(); 45 | int len2 = uri.length(); 46 | // uri almost match 47 | if (len1 == len2 && ns.second.charAt(len1 - 1) == uri.charAt(len2 - 1)) { 48 | name = ns.first; 49 | } 50 | } else { 51 | name = getName(t, uri); 52 | } 53 | } 54 | } else { 55 | int startIndex = (depth >= namespaces.length ? (namespaces.length - 1) 56 | : depth); 57 | for (int i = startIndex; i >= 0; --i) { 58 | if (namespaces[i] != null) { 59 | ArrayList> t = (ArrayList>) namespaces[i]; 60 | name = getName(t, uri); 61 | if (name != null) { 62 | break; 63 | } 64 | } 65 | } 66 | } 67 | return name; 68 | } 69 | 70 | public void putNamespace(int depth, String namespace, String uri) { 71 | this.lastSavedDepth = depth; 72 | 73 | // Enlarge the array 74 | if (depth >= namespaces.length) { 75 | Object[] newArray = new Object[depth + 1]; 76 | System.arraycopy(namespaces, 0, newArray, 0, namespaces.length); 77 | namespaces = newArray; 78 | } 79 | 80 | // Put namespace to related depth name space record 81 | if (namespaces[depth] == null) { 82 | ArrayList> t = new ArrayList<>(); 83 | t.add(Pair.create(namespace, uri)); 84 | namespaces[depth] = t; 85 | depthNum += 1; 86 | } else { 87 | ArrayList> t = (ArrayList>) namespaces[depth]; 88 | t.add(Pair.create(namespace, uri)); 89 | } 90 | } 91 | 92 | // Exit a depth 93 | // Clear the namespace for that depth 94 | public void depthEnded(int depth) { 95 | if (namespaces.length > depth && namespaces[depth] != null) { 96 | namespaces[depth] = null; 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /androlib/brut.j.core/src/main/java/com/mcal/androlib/ResSmaliIdProvider.java: -------------------------------------------------------------------------------- 1 | package com.mcal.androlib; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import java.io.BufferedReader; 6 | import java.io.File; 7 | import java.io.FileInputStream; 8 | import java.io.IOException; 9 | import java.io.InputStreamReader; 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | // Manage the resource id read from smali files 14 | public class ResSmaliIdProvider implements ResourceIdProvider { 15 | 16 | Map id2Name = new HashMap(); 17 | 18 | // workDir is the root path contains the R.smali 19 | public ResSmaliIdProvider(String workDir, @NonNull String pkgName) { 20 | String[] names = pkgName.split("\\."); 21 | StringBuilder sb = new StringBuilder(); 22 | sb.append(workDir); 23 | for (String name : names) { 24 | sb.append(name); 25 | sb.append("/"); 26 | } 27 | 28 | File dir = new File(sb.toString()); 29 | File[] files = dir.listFiles(); 30 | if (files == null) { 31 | return; 32 | } 33 | 34 | for (File f : files) { 35 | String filename = f.getName(); 36 | if (filename.startsWith("R$")) { 37 | readFields(f); 38 | } 39 | } 40 | } 41 | 42 | private void readFields(File f) { 43 | BufferedReader br = null; 44 | try { 45 | br = new BufferedReader( 46 | new InputStreamReader(new FileInputStream(f))); 47 | // Read like: .field public static final DialogTitleStyle:I = 48 | // 0x7f080013 49 | String line = br.readLine(); 50 | while (line != null) { 51 | if (line.startsWith(".field ")) { 52 | int nameEndPos = line.indexOf(":I"); 53 | if (nameEndPos != -1) { 54 | int nameStartPos = line.lastIndexOf(" ", nameEndPos) 55 | + 1; 56 | parseNameAndId(line, nameStartPos, nameEndPos); 57 | } 58 | } 59 | line = br.readLine(); 60 | } 61 | } catch (Exception e) { 62 | e.printStackTrace(); 63 | } finally { 64 | if (br != null) { 65 | try { 66 | br.close(); 67 | } catch (IOException e) { 68 | e.printStackTrace(); 69 | } 70 | } 71 | } 72 | } 73 | 74 | private void parseNameAndId(@NonNull String line, int nameStartPos, int nameEndPos) { 75 | String name = line.substring(nameStartPos, nameEndPos); 76 | int idStartPos = nameEndPos + 7; 77 | 78 | try { 79 | String hexStr = line.substring(idStartPos); 80 | int id = Integer.parseInt(hexStr, 16); 81 | id2Name.put(id, name); 82 | } catch (Exception e) { 83 | e.printStackTrace(); 84 | } 85 | } 86 | 87 | public String getNameById(int id) { 88 | return id2Name.get(id); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /androlib/brut.j.core/src/main/java/com/mcal/androlib/ResourceIdProvider.java: -------------------------------------------------------------------------------- 1 | package com.mcal.androlib; 2 | 3 | // Use to get the resource name by id 4 | public interface ResourceIdProvider { 5 | public String getNameById(int id); 6 | } 7 | -------------------------------------------------------------------------------- /androlib/brut.j.core/src/main/java/com/mcal/androlib/utils/Aapt.kt: -------------------------------------------------------------------------------- 1 | package com.mcal.androlib.utils 2 | 3 | import java.io.File 4 | import java.nio.charset.StandardCharsets 5 | 6 | object Aapt { 7 | @JvmStatic 8 | fun build( 9 | apkFile: File, 10 | include: Array?, 11 | manifest: File, 12 | resDir: File, 13 | minSdk: String?, 14 | targetSdk: String?, 15 | aaptPath: String, 16 | buildAllPackages: Boolean 17 | ) { 18 | val args: MutableList = ArrayList() 19 | args.add(aaptPath) 20 | args.add("package") 21 | args.add("-f") 22 | include?.forEach { framework -> 23 | framework?.let { 24 | args.add("-I") 25 | args.add(it.path) 26 | } 27 | } 28 | 29 | args.add("--min-sdk-version") 30 | args.add(minSdk ?: "21") 31 | 32 | args.add("--target-sdk-version") 33 | args.add(targetSdk ?: "32") 34 | 35 | args.add("-S") 36 | args.add(resDir.path) 37 | if (buildAllPackages) { 38 | resDir.parent?.let { path -> 39 | File(path).walk().forEach { file -> 40 | if (file.name.startsWith("res_") && file.exists() && file.isDirectory) { 41 | args.add("-S") 42 | args.add(file.path) 43 | } 44 | } 45 | } 46 | } 47 | args.add("-M") 48 | args.add(manifest.path) 49 | args.add("-F") 50 | if (!apkFile.exists()) { 51 | apkFile.createNewFile() 52 | } 53 | args.add(apkFile.path) 54 | 55 | val aaptProcess = Runtime.getRuntime().exec(args.toTypedArray()) 56 | val error = aaptProcess.errorStream.readBytes().toString(StandardCharsets.UTF_8) 57 | if (error.isNotEmpty()) { 58 | throw Exception(LogHelper.formatLog(error)) 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /androlib/brut.j.core/src/main/java/com/mcal/androlib/utils/CharSequenceTranslator.kt: -------------------------------------------------------------------------------- 1 | package com.mcal.androlib.utils 2 | 3 | object CharSequenceTranslator { 4 | /** 5 | * Returns an upper case hexadecimal `String` for the given 6 | * character. 7 | * 8 | * @param codePoint The code point to convert. 9 | * @return An upper case hexadecimal `String` 10 | */ 11 | @JvmStatic 12 | fun hex(codePoint: Int): String { 13 | return Integer.toHexString(codePoint).uppercase() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /androlib/brut.j.core/src/main/java/com/mcal/androlib/utils/FileHelper.kt: -------------------------------------------------------------------------------- 1 | package com.mcal.androlib.utils 2 | 3 | import java.io.* 4 | 5 | object FileHelper { 6 | @JvmStatic 7 | fun getExtension(file: String): String { 8 | return File(file).extension 9 | } 10 | 11 | @JvmStatic 12 | fun getExtension(file: File): String { 13 | return file.extension 14 | } 15 | 16 | @JvmStatic 17 | fun moveFile(sourceFile: File, destFile: File) { 18 | if (!destFile.exists()) { 19 | sourceFile.renameTo(destFile) 20 | } else { 21 | throw FileAlreadyExistsException( 22 | file = destFile, 23 | other = null, 24 | reason = "Destination file already exists." 25 | ) 26 | } 27 | } 28 | 29 | @JvmStatic 30 | @Throws(IOException::class) 31 | fun createNewFile(parent: File, name: String): File { 32 | val createdFile = File(parent, name) 33 | parent.mkdirs() 34 | createdFile.createNewFile() 35 | return createdFile 36 | } 37 | 38 | @JvmStatic 39 | @Throws(IOException::class) 40 | fun copyFile(srcFilePath: String, dstFilePath: String) { 41 | copyFile(File(srcFilePath), File(dstFilePath)) 42 | } 43 | 44 | @JvmStatic 45 | @Throws(IOException::class) 46 | fun copyFile(filename: File, output: File) { 47 | copyFile(FileInputStream(filename), FileOutputStream(output)) 48 | } 49 | 50 | @JvmStatic 51 | @Throws(IOException::class) 52 | fun copyFile(input: InputStream, output: File) { 53 | copyFile(input, FileOutputStream(output)) 54 | } 55 | 56 | @JvmStatic 57 | @Throws(IOException::class) 58 | fun copyFile(source: InputStream, target: OutputStream) { 59 | source.copyTo(target) 60 | } 61 | 62 | @JvmStatic 63 | fun toByteArray(input: InputStream): ByteArray { 64 | return input.readBytes() 65 | } 66 | } -------------------------------------------------------------------------------- /androlib/brut.j.core/src/main/java/com/mcal/androlib/utils/LogHelper.kt: -------------------------------------------------------------------------------- 1 | package com.mcal.androlib.utils 2 | 3 | import java.util.regex.Matcher 4 | import java.util.regex.Pattern 5 | 6 | object LogHelper { 7 | private val DIAGNOSTIC_PATTERN: Pattern = Pattern.compile("(.*?):(\\d+): (.*?): (.+)") 8 | private val DIAGNOSTIC_PATTERN_NO_LINE: Pattern = 9 | Pattern.compile("(.*?): (.*?)" + ":" + " (.+)") 10 | 11 | fun formatLog(error: String): String { 12 | val lines = error.split("\n").toTypedArray() 13 | for (line in lines) { 14 | if (line.isEmpty()) { 15 | continue 16 | } 17 | val matcher: Matcher = DIAGNOSTIC_PATTERN.matcher(line) 18 | val m: Matcher = DIAGNOSTIC_PATTERN_NO_LINE.matcher(line) 19 | val path: String 20 | val lineNumber: String 21 | // val level: String 22 | val message: String 23 | if (matcher.find()) { 24 | path = matcher.group(1) as String 25 | lineNumber = matcher.group(2) as String 26 | // level = matcher.group(3) as String 27 | message = matcher.group(4) as String 28 | } else if (m.find()) { 29 | path = m.group(1) as String 30 | lineNumber = "-1" 31 | // level = m.group(2) as String 32 | message = m.group(3) as String 33 | } else { 34 | // val trim = line.trim() 35 | // level = if (trim.startsWith("error")) { 36 | // "Error" 37 | // } else { 38 | // "Info" 39 | // } 40 | path = "" 41 | lineNumber = "-1" 42 | message = line 43 | } 44 | return "Source: $path;Line: $lineNumber;Message: $message" 45 | } 46 | return "Unknown error" 47 | } 48 | } -------------------------------------------------------------------------------- /androlib/brut.j.core/src/main/java/com/mcal/androlib/utils/Logger.java: -------------------------------------------------------------------------------- 1 | package com.mcal.androlib.utils; 2 | 3 | import java.util.logging.Level; 4 | 5 | public interface Logger { 6 | 7 | public void error(String log); 8 | 9 | public void log(Level warring, String format, Throwable ex); 10 | 11 | public void fine(String log); 12 | 13 | public void warning(String log); 14 | 15 | public void info(String log); 16 | } -------------------------------------------------------------------------------- /androlib/brut.j.core/src/main/java/com/mcal/androlib/utils/StringEscapeUtils.kt: -------------------------------------------------------------------------------- 1 | package com.mcal.androlib.utils 2 | 3 | object StringEscapeUtils { 4 | @JvmStatic 5 | fun unescapeJava(str: String?): String? { 6 | if (str == null) { 7 | return null 8 | } 9 | 10 | val builder = StringBuilder() 11 | var hadSlash = false 12 | 13 | for (element in str) { 14 | if (hadSlash) { 15 | when (element) { 16 | 'n' -> builder.append('\n') 17 | 't' -> builder.append('\t') 18 | 'b' -> builder.append('\b') 19 | 'r' -> builder.append('\r') 20 | 'f' -> builder.append('\u000c') 21 | '\'' -> builder.append('\'') 22 | '\"' -> builder.append('\"') 23 | '\\' -> builder.append('\\') 24 | else -> builder.append('\\').append(element) 25 | } 26 | hadSlash = false 27 | } else { 28 | if (element == '\\') { 29 | hadSlash = true 30 | } else { 31 | builder.append(element) 32 | } 33 | } 34 | } 35 | 36 | if (hadSlash) { 37 | builder.append('\\') 38 | } 39 | 40 | return builder.toString() 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /androlib/brut.j.dir/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /androlib/brut.j.dir/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("org.jetbrains.kotlin.android") 4 | id("maven-publish") 5 | } 6 | 7 | group = 'com.mcal' 8 | version = project.artifactVersionName 9 | 10 | android { 11 | compileSdk project.compileSDK.toInteger() 12 | 13 | defaultConfig { 14 | minSdk project.minSDK.toInteger() 15 | targetSdk project.targetSDK.toInteger() 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 21 | } 22 | } 23 | publishing { 24 | singleVariant('release') { 25 | withSourcesJar() 26 | withJavadocJar() 27 | } 28 | } 29 | kotlinOptions { 30 | jvmTarget = project.jvmTarget 31 | } 32 | compileOptions { 33 | sourceCompatibility project.sourceCompatibility.toInteger() 34 | targetCompatibility project.targetCompatibility.toInteger() 35 | } 36 | namespace 'com.mcal.androlib.dir' 37 | } 38 | 39 | dependencies { 40 | implementation project(':androlib:brut.j.core') 41 | implementation project(':androlib:brut.j.common') 42 | implementation project(':androlib:brut.j.util') 43 | } 44 | 45 | publishing { 46 | publications { 47 | release(MavenPublication) { 48 | groupId = group 49 | artifactId = 'apktool-dir' 50 | version = version 51 | 52 | afterEvaluate { 53 | from components.release 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /androlib/brut.j.dir/src/main/java/brut/directory/Directory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.directory; 18 | 19 | import java.io.File; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.io.OutputStream; 23 | import java.util.Map; 24 | import java.util.Set; 25 | 26 | public interface Directory { 27 | char separator = '/'; 28 | 29 | Set getFiles(); 30 | 31 | Set getFiles(boolean recursive); 32 | 33 | Map getDirs(); 34 | 35 | Map getDirs(boolean recursive); 36 | 37 | boolean containsFile(String path); 38 | 39 | boolean containsDir(String path); 40 | 41 | InputStream getFileInput(String path) throws DirectoryException; 42 | 43 | OutputStream getFileOutput(String path) throws DirectoryException; 44 | 45 | Directory getDir(String path) throws PathNotExist; 46 | 47 | Directory createDir(String path) throws DirectoryException; 48 | 49 | boolean removeFile(String path); 50 | 51 | void copyToDir(Directory out) throws DirectoryException; 52 | 53 | void copyToDir(Directory out, String[] fileNames) throws DirectoryException; 54 | 55 | void copyToDir(Directory out, String fileName) throws DirectoryException; 56 | 57 | void copyToDir(File out) throws DirectoryException; 58 | 59 | void copyToDir(File out, String[] fileNames) throws DirectoryException; 60 | 61 | void copyToDir(File out, String fileName) throws DirectoryException; 62 | 63 | long getSize(String fileName) throws DirectoryException; 64 | 65 | long getCompressedSize(String fileName) throws DirectoryException; 66 | 67 | int getCompressionLevel(String fileName) throws DirectoryException; 68 | 69 | void close() throws IOException; 70 | } 71 | -------------------------------------------------------------------------------- /androlib/brut.j.dir/src/main/java/brut/directory/DirectoryException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.directory; 18 | 19 | import brut.common.BrutException; 20 | 21 | public class DirectoryException extends BrutException { 22 | private static final long serialVersionUID = -8871963042836625387L; 23 | 24 | public DirectoryException(String detailMessage, Throwable throwable) { 25 | super(detailMessage, throwable); 26 | } 27 | 28 | public DirectoryException(String detailMessage) { 29 | super(detailMessage); 30 | } 31 | 32 | public DirectoryException(Throwable throwable) { 33 | super(throwable); 34 | } 35 | 36 | public DirectoryException() { 37 | super(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /androlib/brut.j.dir/src/main/java/brut/directory/ExtFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.directory; 18 | 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | import java.io.File; 22 | import java.io.IOException; 23 | import java.net.URI; 24 | 25 | public class ExtFile extends File { 26 | private Directory mDirectory; 27 | 28 | public ExtFile(@NotNull File file) { 29 | super(file.getPath()); 30 | } 31 | 32 | public ExtFile(URI uri) { 33 | super(uri); 34 | } 35 | 36 | public ExtFile(File parent, String child) { 37 | super(parent, child); 38 | } 39 | 40 | public ExtFile(String parent, String child) { 41 | super(parent, child); 42 | } 43 | 44 | public ExtFile(String pathname) { 45 | super(pathname); 46 | } 47 | 48 | public Directory getDirectory() throws DirectoryException { 49 | if (mDirectory == null) { 50 | if (isDirectory()) { 51 | mDirectory = new FileDirectory(this); 52 | } else { 53 | mDirectory = new ZipRODirectory(this); 54 | } 55 | } 56 | return mDirectory; 57 | } 58 | 59 | public void close() throws IOException { 60 | if (mDirectory != null) { 61 | mDirectory.close(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /androlib/brut.j.dir/src/main/java/brut/directory/PathAlreadyExists.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.directory; 18 | 19 | public class PathAlreadyExists extends DirectoryException { 20 | private static final long serialVersionUID = 3776428251424428904L; 21 | 22 | public PathAlreadyExists() { 23 | } 24 | 25 | public PathAlreadyExists(Throwable throwable) { 26 | super(throwable); 27 | } 28 | 29 | public PathAlreadyExists(String detailMessage) { 30 | super(detailMessage); 31 | } 32 | 33 | public PathAlreadyExists(String detailMessage, Throwable throwable) { 34 | super(detailMessage, throwable); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /androlib/brut.j.dir/src/main/java/brut/directory/PathNotExist.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.directory; 18 | 19 | public class PathNotExist extends DirectoryException { 20 | private static final long serialVersionUID = -6949242015506342032L; 21 | 22 | public PathNotExist() { 23 | super(); 24 | } 25 | 26 | public PathNotExist(String detailMessage, Throwable throwable) { 27 | super(detailMessage, throwable); 28 | } 29 | 30 | public PathNotExist(String detailMessage) { 31 | super(detailMessage); 32 | } 33 | 34 | public PathNotExist(Throwable throwable) { 35 | super(throwable); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /androlib/brut.j.util/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /androlib/brut.j.util/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("org.jetbrains.kotlin.android") 4 | id("maven-publish") 5 | } 6 | 7 | group = 'com.mcal' 8 | version = project.artifactVersionName 9 | 10 | android { 11 | compileSdk project.compileSDK.toInteger() 12 | 13 | defaultConfig { 14 | minSdk project.minSDK.toInteger() 15 | targetSdk project.targetSDK.toInteger() 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 21 | } 22 | } 23 | publishing { 24 | singleVariant('release') { 25 | withSourcesJar() 26 | withJavadocJar() 27 | } 28 | } 29 | kotlinOptions { 30 | jvmTarget = project.jvmTarget 31 | } 32 | compileOptions { 33 | sourceCompatibility project.sourceCompatibility.toInteger() 34 | targetCompatibility project.targetCompatibility.toInteger() 35 | } 36 | namespace 'com.mcal.androlib.util' 37 | } 38 | 39 | dependencies { 40 | implementation project(':androlib:brut.j.core') 41 | implementation project(':androlib:brut.j.common') 42 | 43 | implementation(libs.google.guava) 44 | } 45 | 46 | publishing { 47 | publications { 48 | release(MavenPublication) { 49 | groupId = group 50 | artifactId = 'apktool-util' 51 | version = version 52 | 53 | afterEvaluate { 54 | from components.release 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /androlib/brut.j.util/src/main/java/brut/util/DataInputDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.util; 18 | 19 | import java.io.DataInput; 20 | import java.io.IOException; 21 | 22 | public abstract class DataInputDelegate implements DataInput { 23 | protected final DataInput mDelegate; 24 | 25 | public DataInputDelegate(DataInput delegate) { 26 | this.mDelegate = delegate; 27 | } 28 | 29 | public int skipBytes(int n) throws IOException { 30 | return mDelegate.skipBytes(n); 31 | } 32 | 33 | public int readUnsignedShort() throws IOException { 34 | return mDelegate.readUnsignedShort(); 35 | } 36 | 37 | public int readUnsignedByte() throws IOException { 38 | return mDelegate.readUnsignedByte(); 39 | } 40 | 41 | public String readUTF() throws IOException { 42 | return mDelegate.readUTF(); 43 | } 44 | 45 | public short readShort() throws IOException { 46 | return mDelegate.readShort(); 47 | } 48 | 49 | public long readLong() throws IOException { 50 | return mDelegate.readLong(); 51 | } 52 | 53 | public String readLine() throws IOException { 54 | return mDelegate.readLine(); 55 | } 56 | 57 | public int readInt() throws IOException { 58 | return mDelegate.readInt(); 59 | } 60 | 61 | public void readFully(byte[] b, int off, int len) throws IOException { 62 | mDelegate.readFully(b, off, len); 63 | } 64 | 65 | public void readFully(byte[] b) throws IOException { 66 | mDelegate.readFully(b); 67 | } 68 | 69 | public float readFloat() throws IOException { 70 | return mDelegate.readFloat(); 71 | } 72 | 73 | public double readDouble() throws IOException { 74 | return mDelegate.readDouble(); 75 | } 76 | 77 | public char readChar() throws IOException { 78 | return mDelegate.readChar(); 79 | } 80 | 81 | public byte readByte() throws IOException { 82 | return mDelegate.readByte(); 83 | } 84 | 85 | public boolean readBoolean() throws IOException { 86 | return mDelegate.readBoolean(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /androlib/brut.j.util/src/main/java/brut/util/Duo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.util; 18 | 19 | import java.util.Objects; 20 | 21 | public class Duo { 22 | public final T1 m1; 23 | public final T2 m2; 24 | 25 | public Duo(T1 t1, T2 t2) { 26 | this.m1 = t1; 27 | this.m2 = t2; 28 | } 29 | 30 | @SuppressWarnings("unchecked") 31 | @Override 32 | public boolean equals(Object obj) { 33 | if (obj == null) { 34 | return false; 35 | } 36 | if (getClass() != obj.getClass()) { 37 | return false; 38 | } 39 | final Duo other = (Duo) obj; 40 | if (!Objects.equals(this.m1, other.m1)) { 41 | return false; 42 | } 43 | return Objects.equals(this.m2, other.m2); 44 | } 45 | 46 | @Override 47 | public int hashCode() { 48 | int hash = 3; 49 | hash = 71 * hash + (this.m1 != null ? this.m1.hashCode() : 0); 50 | hash = 71 * hash + (this.m2 != null ? this.m2.hashCode() : 0); 51 | return hash; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /androlib/brut.j.util/src/main/java/brut/util/ExtCountingDataInput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.util; 18 | 19 | import com.google.common.io.CountingInputStream; 20 | import com.google.common.io.LittleEndianDataInputStream; 21 | 22 | import java.io.DataInput; 23 | import java.io.IOException; 24 | import java.util.Locale; 25 | import java.util.logging.Logger; 26 | 27 | public class ExtCountingDataInput extends ExtDataInput { 28 | private static final Logger LOGGER = Logger.getLogger(ExtCountingDataInput.class.getName()); 29 | private final CountingInputStream mCountIn; 30 | 31 | public ExtCountingDataInput(LittleEndianDataInputStream in) { 32 | this(new CountingInputStream(in)); 33 | } 34 | 35 | public ExtCountingDataInput(CountingInputStream countIn) { 36 | // We need to explicitly cast to DataInput as otherwise the constructor is ambiguous. 37 | // We choose DataInput instead of InputStream as ExtDataInput wraps an InputStream in 38 | // a DataInputStream which is big-endian and ignores the little-endian behavior. 39 | super((DataInput) new LittleEndianDataInputStream(countIn)); 40 | mCountIn = countIn; 41 | } 42 | 43 | public int position() { 44 | return (int) mCountIn.getCount(); 45 | } 46 | 47 | public int remaining() throws IOException { 48 | return mCountIn.available(); 49 | } 50 | 51 | public long skip(int bytes) throws IOException { 52 | return mCountIn.skip(bytes); 53 | } 54 | 55 | public int[] readSafeIntArray(int length, long maxPosition) throws IOException { 56 | int[] array = new int[length]; 57 | 58 | for (int i = 0; i < length; i++) { 59 | // #3236 - In some applications we have more strings than fit into the block. This function takes 60 | // an expected max position and if we are past it, we return early during processing. 61 | if (position() >= maxPosition) { 62 | LOGGER.warning(String.format(Locale.getDefault(), "Bad string block: string entry is at %d, past end at %d", 63 | position(), maxPosition) 64 | ); 65 | return array; 66 | } 67 | 68 | array[i] = readInt(); 69 | } 70 | return array; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /androlib/brut.j.util/src/main/java/brut/util/ExtDataInput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.util; 18 | 19 | import java.io.DataInput; 20 | import java.io.DataInputStream; 21 | import java.io.IOException; 22 | import java.io.InputStream; 23 | 24 | public class ExtDataInput extends DataInputDelegate { 25 | public ExtDataInput(InputStream in) { 26 | this((DataInput) new DataInputStream(in)); 27 | } 28 | 29 | public ExtDataInput(DataInput delegate) { 30 | super(delegate); 31 | } 32 | 33 | public int[] readIntArray(int length) throws IOException { 34 | int[] array = new int[length]; 35 | for (int i = 0; i < length; i++) { 36 | array[i] = readInt(); 37 | } 38 | return array; 39 | } 40 | 41 | public void skipInt() throws IOException { 42 | skipBytes(4); 43 | } 44 | 45 | public void skipShort() throws IOException { 46 | skipBytes(2); 47 | } 48 | 49 | public void skipCheckShort(short expected) throws IOException { 50 | short got = readShort(); 51 | if (got != expected) { 52 | throw new IOException(String.format("Expected: 0x%08x, got: 0x%08x", expected, got)); 53 | } 54 | } 55 | 56 | public void skipCheckByte(byte expected) throws IOException { 57 | byte got = readByte(); 58 | if (got != expected) { 59 | throw new IOException(String.format("Expected: 0x%08x, got: 0x%08x", expected, got)); 60 | } 61 | } 62 | 63 | /** 64 | * The general contract of DataInput doesn't guarantee all the bytes requested will be skipped 65 | * and failure can occur for many reasons. We override this to try harder to skip all the bytes 66 | * requested (this is similar to DataInputStream's wrapper). 67 | */ 68 | public final int skipBytes(int n) throws IOException { 69 | int total = 0; 70 | int cur; 71 | 72 | while ((total < n) && ((cur = super.skipBytes(n - total)) > 0)) { 73 | total += cur; 74 | } 75 | 76 | return total; 77 | } 78 | 79 | public String readNullEndedString(int length, boolean fixed) throws IOException { 80 | StringBuilder string = new StringBuilder(16); 81 | while (length-- != 0) { 82 | short ch = readShort(); 83 | if (ch == 0) { 84 | break; 85 | } 86 | string.append((char) ch); 87 | } 88 | if (fixed) { 89 | skipBytes(length * 2); 90 | } 91 | 92 | return string.toString(); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /androlib/brut.j.util/src/main/java/brut/util/Jar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.util; 18 | 19 | import java.io.*; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | import java.util.concurrent.ThreadLocalRandom; 23 | 24 | import brut.common.BrutException; 25 | import com.mcal.androlib.utils.FileHelper; 26 | import org.jetbrains.annotations.NotNull; 27 | 28 | public abstract class Jar { 29 | private static final Map mExtracted = new HashMap<>(); 30 | 31 | public static @NotNull File getResourceAsFile(String name, Class clazz) throws BrutException { 32 | File file = mExtracted.get(name); 33 | if (file == null) { 34 | file = extractToTmp(name, clazz); 35 | mExtracted.put(name, file); 36 | } 37 | return file; 38 | } 39 | 40 | public static @NotNull File extractToTmp(String resourcePath, Class clazz) throws BrutException { 41 | return extractToTmp(resourcePath, "brut_util_Jar_", clazz); 42 | } 43 | 44 | public static @NotNull File extractToTmp(String resourcePath, String tmpPrefix, @NotNull Class clazz) throws BrutException { 45 | try { 46 | InputStream in = clazz.getResourceAsStream(resourcePath); 47 | if (in == null) { 48 | throw new FileNotFoundException(resourcePath); 49 | } 50 | long suffix = ThreadLocalRandom.current().nextLong(); 51 | suffix = suffix == Long.MIN_VALUE ? 0 : Math.abs(suffix); 52 | File fileOut = File.createTempFile(tmpPrefix, suffix + ".tmp"); 53 | fileOut.deleteOnExit(); 54 | 55 | OutputStream out = new FileOutputStream(fileOut); 56 | FileHelper.copyFile(in, out); 57 | in.close(); 58 | out.close(); 59 | 60 | return fileOut; 61 | } catch (IOException ex) { 62 | throw new BrutException("Could not extract resource: " + resourcePath, ex); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /androlib/brut.j.util/src/main/java/brut/util/OS.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Ryszard Wiśniewski 3 | * Copyright (C) 2010 Connor Tumbleson 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package brut.util; 18 | 19 | import brut.common.BrutException; 20 | import com.mcal.androlib.utils.FileHelper; 21 | import org.jetbrains.annotations.NotNull; 22 | 23 | import java.io.*; 24 | import java.util.logging.Logger; 25 | 26 | public class OS { 27 | 28 | private static final Logger LOGGER = Logger.getLogger(""); 29 | 30 | public static void rmdir(@NotNull File dir) throws BrutException { 31 | if (!dir.exists()) { 32 | return; 33 | } 34 | File[] files = dir.listFiles(); 35 | if (files == null) { 36 | return; 37 | } 38 | 39 | for (File file : files) { 40 | if (file.isDirectory()) { 41 | rmdir(file); 42 | } else { 43 | //noinspection ResultOfMethodCallIgnored 44 | file.delete(); 45 | } 46 | } 47 | //noinspection ResultOfMethodCallIgnored 48 | dir.delete(); 49 | } 50 | 51 | public static void cpdir(@NotNull File src, @NotNull File dest) throws BrutException { 52 | //noinspection ResultOfMethodCallIgnored 53 | dest.mkdirs(); 54 | File[] files = src.listFiles(); 55 | if (files == null) { 56 | return; 57 | } 58 | 59 | for (File file : files) { 60 | File destFile = new File(dest.getPath() + File.separatorChar + file.getName()); 61 | if (file.isDirectory()) { 62 | cpdir(file, destFile); 63 | continue; 64 | } 65 | try { 66 | try (InputStream in = new FileInputStream(file)) { 67 | try (OutputStream out = new FileOutputStream(destFile)) { 68 | FileHelper.copyFile(in, out); 69 | } 70 | } 71 | } catch (IOException ex) { 72 | throw new BrutException("Could not copy file: " + file, ex); 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /release -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.application") 3 | id("org.jetbrains.kotlin.android") 4 | id("maven-publish") 5 | } 6 | 7 | android { 8 | namespace 'com.mcal.apktool' 9 | compileSdk project.compileSDK.toInteger() 10 | 11 | defaultConfig { 12 | applicationId "com.mcal.apktool" 13 | minSdk project.minSDK.toInteger() 14 | targetSdk project.targetSDK.toInteger() 15 | versionCode project.artifactVersionCode.toInteger() 16 | versionName project.artifactVersionName 17 | 18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 19 | } 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | kotlinOptions { 27 | jvmTarget = project.jvmTarget 28 | } 29 | buildFeatures { 30 | viewBinding true 31 | } 32 | compileOptions { 33 | sourceCompatibility project.sourceCompatibility.toInteger() 34 | targetCompatibility project.targetCompatibility.toInteger() 35 | } 36 | } 37 | 38 | dependencies { 39 | implementation project(':androlib:brut.j.core') 40 | implementation project(':androlib:brut.apktool:apktool-lib') 41 | implementation project(':androlib:brut.j.dir') 42 | implementation project(':androlib:brut.j.common') 43 | 44 | implementation(libs.ktor.client.okhttp) 45 | implementation(libs.ktor.client.core) 46 | implementation(libs.ktor.client.cio) 47 | 48 | implementation(libs.kotlinx.coroutines.core) 49 | implementation(libs.kotlinx.coroutines.android) 50 | } 51 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/mcal/example/utils/ApktoolHelper.java: -------------------------------------------------------------------------------- 1 | package com.mcal.example.utils; 2 | 3 | import brut.androlib.ApkBuilder; 4 | import brut.androlib.ApkDecoder; 5 | import brut.androlib.Config; 6 | import brut.androlib.exceptions.AndrolibException; 7 | import brut.common.BrutException; 8 | import brut.directory.DirectoryException; 9 | import brut.directory.ExtFile; 10 | import com.mcal.androlib.utils.Logger; 11 | import org.jetbrains.annotations.NotNull; 12 | 13 | import java.io.File; 14 | import java.io.IOException; 15 | 16 | public class ApktoolHelper { 17 | public static void decode( 18 | @NotNull File apkFile, 19 | @NotNull File decodeDir, 20 | @NotNull String frameworkPath, 21 | boolean decodeSmali, 22 | @NotNull Logger logger) { 23 | try { 24 | Config config = Config.getDefaultConfig(); 25 | config.setDecodeSources(decodeSmali ? Config.DECODE_SOURCES_SMALI : Config.DECODE_SOURCES_NONE); 26 | config.setDecodeResources(Config.DECODE_RESOURCES_FULL); 27 | config.setDecodeAssets(Config.DECODE_ASSETS_NONE); 28 | config.setDefaultFramework(frameworkPath); 29 | config.setDecodeAllPackages(true); 30 | config.setForceDelete(true); 31 | new ApkDecoder(config, new ExtFile(apkFile), logger).decode(decodeDir); 32 | } catch (AndrolibException | IOException | DirectoryException e) { 33 | throw new RuntimeException(e); 34 | } 35 | } 36 | 37 | public static void buildProject( 38 | @NotNull File apkFile, 39 | @NotNull File decodeDir, 40 | @NotNull String frameworkPath, 41 | @NotNull String aaptPath, 42 | @NotNull String aapt2Path, 43 | boolean useAapt2, 44 | @NotNull Logger logger) { 45 | try { 46 | logger.info("Aapt version: " + (useAapt2 ? "2" : "1")); 47 | ExtFile appDecodeDir = new ExtFile(decodeDir); 48 | Config config = Config.getDefaultConfig(); 49 | config.setUseAapt2(useAapt2); 50 | config.setAaptPath(aaptPath); 51 | config.setAapt2Path(aapt2Path); 52 | config.setDefaultFramework(frameworkPath); 53 | config.setDecodeAllPackages(false); // aapt and aapt2 not support multi packages 54 | config.setForceDelete(true); 55 | new ApkBuilder(config, appDecodeDir, logger).build(apkFile); 56 | } catch (BrutException e) { 57 | throw new RuntimeException(e); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/mcal/example/utils/FileHelper.kt: -------------------------------------------------------------------------------- 1 | package com.mcal.example.utils 2 | 3 | import android.content.Context 4 | import java.io.* 5 | 6 | object FileHelper { 7 | @JvmStatic 8 | fun getToolsDir(context: Context): File { 9 | val dir = File(context.filesDir, "bin") 10 | if (!dir.exists()) { 11 | dir.mkdirs() 12 | } 13 | return dir 14 | } 15 | 16 | fun getDecodeDir(context: Context): File { 17 | val dir = File(context.filesDir, "decode") 18 | if (!dir.exists()) { 19 | dir.mkdirs() 20 | } 21 | return dir 22 | } 23 | 24 | @Throws(IOException::class) 25 | fun copyAssetsFile(context: Context, filename: String, output: File, execute: Boolean) { 26 | val input: InputStream = context.assets.open(filename) 27 | try { 28 | FileOutputStream(output).use { target -> 29 | copyFile(input, target, input.available()) 30 | } 31 | output.setExecutable(execute) 32 | } finally { 33 | input.close() 34 | } 35 | } 36 | 37 | @Throws(IOException::class) 38 | fun copyFile(source: InputStream, target: FileOutputStream, size: Int) { 39 | val buf = ByteArray(size) 40 | var length: Int 41 | while (source.read(buf).also { length = it } != -1) { 42 | target.write(buf, 0, length) 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mcal/example/utils/Preferences.java: -------------------------------------------------------------------------------- 1 | package com.mcal.example.utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import java.io.File; 8 | 9 | public class Preferences { 10 | @NotNull 11 | private static SharedPreferences preferences(@NotNull Context context) { 12 | return context.getSharedPreferences("preferences", Context.MODE_PRIVATE); 13 | } 14 | 15 | @NotNull 16 | private static SharedPreferences.Editor editor(@NotNull Context context) { 17 | return preferences(context).edit(); 18 | } 19 | 20 | @NotNull 21 | public static String getAaptPath(@NotNull Context context) { 22 | final SharedPreferences preferences = preferences(context); 23 | return preferences.getString("aapt", new File(FileHelper.getToolsDir(context), "aapt").getPath()); 24 | } 25 | 26 | public static void setAaptPath(@NotNull Context context, @NotNull String path) { 27 | final SharedPreferences.Editor editor = editor(context); 28 | editor.putString("aapt", path); 29 | editor.apply(); 30 | } 31 | 32 | @NotNull 33 | public static String getAapt2Path(@NotNull Context context) { 34 | final SharedPreferences preferences = preferences(context); 35 | return preferences.getString("aapt2", new File(FileHelper.getToolsDir(context), "aapt2").getPath()); 36 | } 37 | 38 | public static void setAapt2Path(@NotNull Context context, @NotNull String path) { 39 | final SharedPreferences.Editor editor = editor(context); 40 | editor.putString("aapt2", path); 41 | editor.apply(); 42 | } 43 | 44 | @NotNull 45 | public static String getFrameworkPath(@NotNull Context context) { 46 | final SharedPreferences preferences = preferences(context); 47 | return preferences.getString("framework", new File(FileHelper.getToolsDir(context), "android.jar").getPath()); 48 | } 49 | 50 | public static void setFrameworkPath(@NotNull Context context, @NotNull String path) { 51 | final SharedPreferences.Editor editor = editor(context); 52 | editor.putString("framework", path); 53 | editor.apply(); 54 | } 55 | 56 | public static boolean isUseAapt2(@NotNull Context context) { 57 | final SharedPreferences preferences = preferences(context); 58 | return preferences.getBoolean("use_aapt2", true); 59 | } 60 | 61 | public static void setUseAapt2(@NotNull Context context, boolean mode) { 62 | final SharedPreferences.Editor editor = editor(context); 63 | editor.putBoolean("use_aapt2", mode); 64 | editor.apply(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values-ru/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ApkTool Mobile 3 | Восстановить 4 | Сообщество 5 | GitHub 6 | Telegram 7 | Инструменты(Не обязательно) 8 | Использовать aapt2 9 | Введите путь к фреймфорку 10 | Введите путь к aapt 11 | Введите путь к aapt2 12 | Декомпилятор 13 | Введите путь к apk 14 | Введите путь к директории проекта 15 | Декомпилировать 16 | Компилятор 17 | Введите путь к директории проекта 18 | Введите путь к APK 19 | Компилировать 20 | Декомпиляция завершена. 21 | Компиляция завершена. 22 | Инструменты 23 | Загрузить фреймфорк 24 | Загрузить aapt 25 | Загрузить aapt2 26 | Декомпилировать smali 27 | Разрешение на чтение и запись не предоставлено 28 | Разрешение на чтение и запись предоставлено 29 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ApkTool Mobile 3 | Restore 4 | Community 5 | GitHub 6 | Telegram 7 | Tools(optional) 8 | Use aapt2 9 | Enter framework path 10 | Enter aapt path 11 | Enter aapt2 path 12 | Apktool Decoder 13 | Enter apk path 14 | Enter output dir 15 | Decode 16 | Apktool Builder 17 | Enter decode path 18 | Enter output APK 19 | Build 20 | Decoding finished. 21 | Building finished. 22 | Tools 23 | Download framework 24 | Download aapt 25 | Download aapt2 26 | Decode smali 27 | Permission for reading and writing not granted 28 | Permission for reading and writing granted 29 | -------------------------------------------------------------------------------- /app/src/main/res/xml/network.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | maven { url 'https://jitpack.io' } 6 | } 7 | } 8 | 9 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 10 | plugins { 11 | id 'com.android.application' version '8.2.0' apply false 12 | id 'com.android.library' version '8.2.0' apply false 13 | id 'org.jetbrains.kotlin.android' version '1.9.21' apply false 14 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | android.useAndroidX=true 2 | android.nonTransitiveRClass=true 3 | kotlin.code.style=official 4 | 5 | org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 6 | 7 | compileSDK=34 8 | targetSDK=26 9 | minSDK=21 10 | 11 | sourceCompatibility=17 12 | targetCompatibility=17 13 | jvmTarget=17 14 | 15 | artifactVersionName='2.9.2.4' 16 | artifactVersionCode=292 -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | kotlinxCoroutinesAndroid = "1.7.3" 3 | smali = "3.0.3" 4 | 5 | ktor = "2.3.7" 6 | 7 | [libraries] 8 | 9 | kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinxCoroutinesAndroid" } 10 | 11 | google-guava = { module = "com.google.guava:guava", version = "31.0.1-android" } 12 | antlr = { module = "org.antlr:antlr-runtime", version = "3.5.3" } 13 | annotations = { module = "org.jetbrains:annotations", version = "24.1.0" } 14 | androidx-annotation = { module = "androidx.annotation:annotation", version = "1.7.1" } 15 | kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.7.3" } 16 | 17 | ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } 18 | ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } 19 | ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" } 20 | 21 | smali-dexlib2 = { module = "com.android.tools.smali:smali-dexlib2", version.ref = "smali" } 22 | smali = { module = "com.android.tools.smali:smali", version.ref = "smali" } 23 | smali-baksmali = { module = "com.android.tools.smali:smali-baksmali", version.ref = "smali" } 24 | 25 | [plugins] 26 | 27 | [bundles] 28 | 29 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timscriptov/android-apktool/a45ae393930b1d90028a79056f00bff1c28ea4ab/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | jdk: 2 | - openjdk17 3 | 4 | before_install: 5 | - sdk update 6 | - sdk install java 17.0.9-oracle 7 | - sdk use java 17.0.9-oracle 8 | - sdk install gradle 8.2.0 9 | - sdk use gradle 8.2.0 10 | - sdk install maven 11 | - mvn -v 12 | 13 | install: 14 | - mvn install -Dmaven.javadoc.skip=true -DskipTests 15 | 16 | script: 17 | - ./gradlew publish 18 | -------------------------------------------------------------------------------- /local.properties: -------------------------------------------------------------------------------- 1 | ## This file must *NOT* be checked into Version Control Systems, 2 | # as it contains information specific to your local configuration. 3 | # 4 | # Location of the SDK. This is only used by Gradle. 5 | # For customization when using a Version Control System, please read the 6 | # header note. 7 | #Thu Dec 28 11:44:06 MSK 2023 8 | sdk.dir=C\:\\SDK\\android 9 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | gradlePluginPortal() 6 | } 7 | } 8 | dependencyResolutionManagement { 9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | } 15 | rootProject.name = "android-apktool" 16 | include ':app' 17 | 18 | include ':androlib:brut.j.common', 19 | ':androlib:brut.j.util', 20 | ':androlib:brut.j.dir', 21 | ':androlib:brut.apktool:apktool-lib', 22 | ':androlib:brut.j.core' 23 | 24 | include ':xpp3' 25 | -------------------------------------------------------------------------------- /xpp3/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /xpp3/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("org.jetbrains.kotlin.android") 4 | id("maven-publish") 5 | } 6 | 7 | group = 'com.mcal' 8 | version = project.artifactVersionName 9 | 10 | android { 11 | compileSdk project.compileSDK.toInteger() 12 | 13 | defaultConfig { 14 | minSdk project.minSDK.toInteger() 15 | targetSdk project.targetSDK.toInteger() 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 21 | } 22 | } 23 | publishing { 24 | singleVariant('release') { 25 | withSourcesJar() 26 | withJavadocJar() 27 | } 28 | } 29 | kotlinOptions { 30 | jvmTarget = project.jvmTarget 31 | } 32 | compileOptions { 33 | sourceCompatibility project.sourceCompatibility.toInteger() 34 | targetCompatibility project.targetCompatibility.toInteger() 35 | } 36 | namespace 'com.mcal.xpp3' 37 | } 38 | 39 | dependencies { 40 | implementation fileTree(dir: 'libs', include: ['*.jar']) 41 | implementation(libs.annotations) 42 | implementation(libs.androidx.annotation) 43 | } 44 | 45 | publishing { 46 | publications { 47 | release(MavenPublication) { 48 | groupId = group 49 | artifactId = 'xpp3' 50 | version = version 51 | 52 | afterEvaluate { 53 | from components.release 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /xpp3/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xpp3/src/main/java/com/mcal/xmlpull/v1/parser_pool/XmlPullParserPool.java: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/ 2 | // for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/) 3 | 4 | package com.mcal.xmlpull.v1.parser_pool; 5 | 6 | import org.xmlpull.v1.XmlPullParser; 7 | import org.xmlpull.v1.XmlPullParserException; 8 | import org.xmlpull.v1.XmlPullParserFactory; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | // add aging so parser used more than X times is not resused ... 14 | 15 | /** 16 | * Very simple utility to make pooling of XmlPull parsers easy. 17 | * 18 | * @author Aleksander Slominski 19 | */ 20 | public class XmlPullParserPool { 21 | protected final List pool = new ArrayList<>(); 22 | protected XmlPullParserFactory factory; 23 | 24 | 25 | public XmlPullParserPool() throws XmlPullParserException { 26 | this(XmlPullParserFactory.newInstance()); 27 | } 28 | 29 | public XmlPullParserPool(XmlPullParserFactory factory) { 30 | if (factory == null) throw new IllegalArgumentException(); 31 | this.factory = factory; 32 | } 33 | 34 | // simple inline test 35 | public static void main(String[] args) throws Exception { 36 | //XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); 37 | //XmlPullParserPool pool = new XmlPullParserPool(factory); 38 | XmlPullParserPool pool = new XmlPullParserPool(); 39 | XmlPullParser p1 = pool.getPullParserFromPool(); 40 | pool.returnPullParserToPool(p1); 41 | XmlPullParser p2 = pool.getPullParserFromPool(); 42 | //assert p1 == p2; 43 | if (p1 != p2) throw new RuntimeException(); 44 | pool.returnPullParserToPool(p2); 45 | System.out.println(pool.getClass() + " OK"); 46 | } 47 | 48 | protected XmlPullParser newParser() throws XmlPullParserException { 49 | return factory.newPullParser(); 50 | } 51 | 52 | public XmlPullParser getPullParserFromPool() 53 | throws XmlPullParserException { 54 | XmlPullParser pp = null; 55 | if (!pool.isEmpty()) { 56 | synchronized (pool) { 57 | if (!pool.isEmpty()) { 58 | pp = (XmlPullParser) pool.remove(pool.size() - 1); 59 | } 60 | } 61 | } 62 | if (pp == null) { 63 | pp = newParser(); 64 | //System.err.println("new parser instance created pp="+pp); 65 | } 66 | return pp; 67 | } 68 | 69 | public void returnPullParserToPool(XmlPullParser pp) { 70 | if (pp == null) throw new IllegalArgumentException(); 71 | synchronized (pool) { 72 | pool.add(pp); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /xpp3/src/main/java/com/mcal/xmlpull/v1/wrapper/perftest/Driver.java: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/ 2 | // for license see accompanying LICENSE_TESTS.txt file (available also at http://www.xmlpull.org) 3 | 4 | package com.mcal.xmlpull.v1.wrapper.perftest; 5 | 6 | //import junit.framework.Test; 7 | 8 | import com.mcal.xmlpull.v1.util.XmlPullUtil; 9 | import com.mcal.xmlpull.v1.wrapper.XmlPullParserWrapper; 10 | import com.mcal.xmlpull.v1.wrapper.XmlPullWrapperFactory; 11 | import org.xmlpull.v1.XmlPullParser; 12 | import org.xmlpull.v1.XmlPullParserFactory; 13 | 14 | import java.io.StringReader; 15 | 16 | /** 17 | * Test overhead of wrapper approach. 18 | * 19 | * @author Aleksander Slominski 20 | */ 21 | public class Driver { 22 | 23 | public static void main(String[] args) throws Exception { 24 | final int PASSES = 20; 25 | final int REPEAT = 5 * 10000; 26 | 27 | System.err.println("starting tests with PASSES=" + PASSES + " REPEAT=" + REPEAT); 28 | long startDirect = -1, endDirect = -1; 29 | long startStaticWrap = -1, endStaticWrap = -1; 30 | XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); 31 | factory.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); 32 | XmlPullWrapperFactory staticWrapperFactory = XmlPullWrapperFactory.newInstance(factory); 33 | 34 | // multiple passes necessary to do some warmup to remove HotSpot influences ... 35 | for (int count = 0; count < PASSES; count++) { 36 | System.err.println("pass " + (count + 1) + " of " + PASSES); 37 | startDirect = System.currentTimeMillis(); 38 | 39 | XmlPullParser pp = factory.newPullParser(); 40 | for (int i = 0; i < REPEAT; i++) { 41 | StringReader sr = new StringReader("world!"); 42 | pp.setInput(sr); 43 | pp.nextTag(); 44 | pp.require(XmlPullParser.START_TAG, null, "hello"); 45 | pp.next(); 46 | XmlPullUtil.nextEndTag(pp); 47 | pp.require(XmlPullParser.END_TAG, null, "hello"); 48 | } 49 | endDirect = System.currentTimeMillis(); 50 | System.err.println("direct test took " + (endDirect - startDirect) / 1000.0 + " seconds"); 51 | 52 | startStaticWrap = System.currentTimeMillis(); 53 | XmlPullParserWrapper spw = staticWrapperFactory.newPullParserWrapper(); 54 | for (int i = 0; i < REPEAT; i++) { 55 | StringReader sr = new StringReader("world!"); 56 | spw.setInput(sr); 57 | spw.nextTag(); 58 | spw.require(XmlPullParser.START_TAG, null, "hello"); 59 | spw.next(); 60 | spw.nextEndTag(); 61 | spw.require(XmlPullParser.END_TAG, null, "hello"); 62 | } 63 | endStaticWrap = System.currentTimeMillis(); 64 | System.err.println("static wrap test took " + (endStaticWrap - startStaticWrap) / 1000.0 + " seconds"); 65 | 66 | 67 | } 68 | 69 | double directSecs = (endDirect - startDirect) / 1000.0; 70 | //System.err.println("direct test took "+directSecs+" seconds"); 71 | 72 | { 73 | double staticWrapSecs = (endStaticWrap - startStaticWrap) / 1000.0; 74 | double staticSpeedup = staticWrapSecs / directSecs; 75 | double percent = Math.round((staticSpeedup - 1) * 100.0 * 100.0) / 100.0; 76 | System.err.println("speedup when using direct over static wrap " + staticSpeedup + " (" + percent + "%)"); 77 | } 78 | 79 | System.err.println("finished"); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /xpp3/src/main/java/com/mcal/xmlpull/v1/xmlrpc/XmlRpcParser.java: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/ 2 | // for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/) 3 | 4 | package com.mcal.xmlpull.v1.xmlrpc; 5 | 6 | 7 | import org.jetbrains.annotations.NotNull; 8 | import org.xmlpull.v1.XmlPullParser; 9 | import org.xmlpull.v1.XmlPullParserException; 10 | 11 | import java.io.IOException; 12 | 13 | /** 14 | * @author Stefan Haustein 15 | * 16 | *

A simple XML RPC parser based on the XML PULL API, 17 | * intended to show the XMLPULL and KXml2 API usage with 18 | * a real application example.

19 | * 20 | *
    21 | *
  • For the XML RPC specification, please refer to 22 | * http://www.xmlrpc.com/spec
  • 23 | *
  • For the XmlPullParser API specification, please refer to 24 | * xmlpull.org
  • 25 | *
  • For information about kXML 2, please refer to 26 | * kxml.org
  • 27 | *
28 | */ 29 | 30 | public class XmlRpcParser extends XmlRpcParserME { 31 | 32 | public XmlRpcParser(XmlPullParser parser) { 33 | super(parser); 34 | } 35 | 36 | protected Object parseType(@NotNull String name) throws IOException, XmlPullParserException { 37 | if (name.equals("double")) { 38 | return Double.valueOf(parser.nextText()); 39 | } else { 40 | return super.parseType(name); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /xpp3/src/main/java/com/mcal/xmlpull/v1/xsd/XsdException.java: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/ 2 | // for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/) 3 | 4 | package com.mcal.xmlpull.v1.xsd; 5 | 6 | /** 7 | * This exception is thrown to signal XB1 related exceptions. 8 | * 9 | * @author Aleksander Slominski 10 | */ 11 | public class XsdException extends RuntimeException { 12 | protected Throwable detail; 13 | //protected int row = -1; 14 | //protected int column = -1; 15 | 16 | public XsdException(String s) { 17 | super(s); 18 | } 19 | 20 | 21 | public XsdException(String s, Throwable thrwble) { 22 | super(s); 23 | this.detail = thrwble; 24 | } 25 | 26 | 27 | public Throwable getDetail() { 28 | return detail; 29 | } 30 | // public void setDetail(Throwable cause) { this.detail = cause; } 31 | 32 | public String getMessage() { 33 | if (detail == null) 34 | return super.getMessage(); 35 | else 36 | return super.getMessage() + "; nested exception is: \n\t" 37 | + detail.getMessage(); 38 | } 39 | 40 | 41 | public void printStackTrace(java.io.PrintStream ps) { 42 | if (detail == null) { 43 | super.printStackTrace(ps); 44 | } else { 45 | synchronized (ps) { 46 | //ps.println(this); 47 | ps.println(super.getMessage() + "; nested exception is:"); 48 | detail.printStackTrace(ps); 49 | } 50 | } 51 | } 52 | 53 | public void printStackTrace() { 54 | printStackTrace(System.err); 55 | } 56 | 57 | public void printStackTrace(java.io.PrintWriter pw) { 58 | if (detail == null) { 59 | super.printStackTrace(pw); 60 | } else { 61 | synchronized (pw) { 62 | //pw.println(this); 63 | pw.println(super.getMessage() + "; nested exception is:"); 64 | detail.printStackTrace(pw); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /xpp3/src/main/java/com/mcal/xmlpull/v1/xsd/impl/base64/Base64DecodingException.java: -------------------------------------------------------------------------------- 1 | /* -*- mode: Java; c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/ 2 | /* 3 | * Copyright (c) 2002-2004 Extreme! Lab, Indiana University. All rights reserved. 4 | * 5 | * This software is open source. See the bottom of this file for the licence. 6 | * 7 | * $Id: Base64DecodingException.java,v 1.4 2003/04/06 00:04:25 aslom Exp $ 8 | */ 9 | 10 | package com.mcal.xmlpull.v1.xsd.impl.base64; 11 | 12 | 13 | /** 14 | * There was exception in BASE64 decoding. 15 | * 16 | * @author Aleksander Slominski 17 | * @version $Revision: 1.4 $ $Date: 2003/04/06 00:04:25 $ (GMT) 18 | */ 19 | 20 | public class Base64DecodingException extends RuntimeException { 21 | public Base64DecodingException(String msg) { 22 | super(msg); 23 | } 24 | } 25 | 26 | /* 27 | * Indiana University Extreme! Lab Software License, Version 1.2 28 | * 29 | * Copyright (c) 2002-2004 The Trustees of Indiana University. 30 | * All rights reserved. 31 | * 32 | * Redistribution and use in source and binary forms, with or without 33 | * modification, are permitted provided that the following conditions are 34 | * met: 35 | * 36 | * 1) All redistributions of source code must retain the above 37 | * copyright notice, the list of authors in the original source 38 | * code, this list of conditions and the disclaimer listed in this 39 | * license; 40 | * 41 | * 2) All redistributions in binary form must reproduce the above 42 | * copyright notice, this list of conditions and the disclaimer 43 | * listed in this license in the documentation and/or other 44 | * materials provided with the distribution; 45 | * 46 | * 3) Any documentation included with all redistributions must include 47 | * the following acknowledgement: 48 | * 49 | * "This product includes software developed by the Indiana 50 | * University Extreme! Lab. For further information please visit 51 | * http://www.extreme.indiana.edu/" 52 | * 53 | * Alternatively, this acknowledgment may appear in the software 54 | * itself, and wherever such third-party acknowledgments normally 55 | * appear. 56 | * 57 | * 4) The name "Indiana University" or "Indiana University 58 | * Extreme! Lab" shall not be used to endorse or promote 59 | * products derived from this software without prior written 60 | * permission from Indiana University. For written permission, 61 | * please contact http://www.extreme.indiana.edu/. 62 | * 63 | * 5) Products derived from this software may not use "Indiana 64 | * University" name nor may "Indiana University" appear in their name, 65 | * without prior written permission of the Indiana University. 66 | * 67 | * Indiana University provides no reassurances that the source code 68 | * provided does not infringe the patent or any other intellectual 69 | * property rights of any other entity. Indiana University disclaims any 70 | * liability to any recipient for claims brought by any other entity 71 | * based on infringement of intellectual property rights or otherwise. 72 | * 73 | * LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH 74 | * NO WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA 75 | * UNIVERSITY GIVES NO WARRANTIES AND MAKES NO REPRESENTATION THAT 76 | * SOFTWARE IS FREE OF INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR 77 | * OTHER PROPRIETARY RIGHTS. INDIANA UNIVERSITY MAKES NO WARRANTIES THAT 78 | * SOFTWARE IS FREE FROM "BUGS", "VIRUSES", "TROJAN HORSES", "TRAP 79 | * DOORS", "WORMS", OR OTHER HARMFUL CODE. LICENSEE ASSUMES THE ENTIRE 80 | * RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR ASSOCIATED MATERIALS, 81 | * AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION GENERATED USING 82 | * SOFTWARE. 83 | */ 84 | 85 | -------------------------------------------------------------------------------- /xpp3/src/main/java/com/mcal/xmlpull/v1/xsd/impl/base64/Base64DecodingState.java: -------------------------------------------------------------------------------- 1 | /* -*- mode: Java; c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/ 2 | /* 3 | * Copyright (c) 2002-2004 Extreme! Lab, Indiana University. All rights reserved. 4 | * 5 | * This software is open source. See the bottom of this file for the licence. 6 | * 7 | * $Id: Base64DecodingState.java,v 1.4 2003/04/06 00:04:25 aslom Exp $ 8 | */ 9 | 10 | package com.mcal.xmlpull.v1.xsd.impl.base64; 11 | 12 | /** 13 | * @author Aleksander Slominski 14 | * @version $Revision: 1.4 $ $Date: 2003/04/06 00:04:25 $ (GMT) 15 | */ 16 | 17 | public class Base64DecodingState { 18 | 19 | // codec state - when operated in streaming mode 20 | byte[] input = new byte[4]; 21 | int inputEnd; 22 | 23 | public Base64DecodingState() { 24 | } 25 | 26 | } 27 | 28 | /* 29 | * Indiana University Extreme! Lab Software License, Version 1.2 30 | * 31 | * Copyright (c) 2002-2004 The Trustees of Indiana University. 32 | * All rights reserved. 33 | * 34 | * Redistribution and use in source and binary forms, with or without 35 | * modification, are permitted provided that the following conditions are 36 | * met: 37 | * 38 | * 1) All redistributions of source code must retain the above 39 | * copyright notice, the list of authors in the original source 40 | * code, this list of conditions and the disclaimer listed in this 41 | * license; 42 | * 43 | * 2) All redistributions in binary form must reproduce the above 44 | * copyright notice, this list of conditions and the disclaimer 45 | * listed in this license in the documentation and/or other 46 | * materials provided with the distribution; 47 | * 48 | * 3) Any documentation included with all redistributions must include 49 | * the following acknowledgement: 50 | * 51 | * "This product includes software developed by the Indiana 52 | * University Extreme! Lab. For further information please visit 53 | * http://www.extreme.indiana.edu/" 54 | * 55 | * Alternatively, this acknowledgment may appear in the software 56 | * itself, and wherever such third-party acknowledgments normally 57 | * appear. 58 | * 59 | * 4) The name "Indiana University" or "Indiana University 60 | * Extreme! Lab" shall not be used to endorse or promote 61 | * products derived from this software without prior written 62 | * permission from Indiana University. For written permission, 63 | * please contact http://www.extreme.indiana.edu/. 64 | * 65 | * 5) Products derived from this software may not use "Indiana 66 | * University" name nor may "Indiana University" appear in their name, 67 | * without prior written permission of the Indiana University. 68 | * 69 | * Indiana University provides no reassurances that the source code 70 | * provided does not infringe the patent or any other intellectual 71 | * property rights of any other entity. Indiana University disclaims any 72 | * liability to any recipient for claims brought by any other entity 73 | * based on infringement of intellectual property rights or otherwise. 74 | * 75 | * LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH 76 | * NO WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA 77 | * UNIVERSITY GIVES NO WARRANTIES AND MAKES NO REPRESENTATION THAT 78 | * SOFTWARE IS FREE OF INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR 79 | * OTHER PROPRIETARY RIGHTS. INDIANA UNIVERSITY MAKES NO WARRANTIES THAT 80 | * SOFTWARE IS FREE FROM "BUGS", "VIRUSES", "TROJAN HORSES", "TRAP 81 | * DOORS", "WORMS", OR OTHER HARMFUL CODE. LICENSEE ASSUMES THE ENTIRE 82 | * RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR ASSOCIATED MATERIALS, 83 | * AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION GENERATED USING 84 | * SOFTWARE. 85 | */ 86 | -------------------------------------------------------------------------------- /xpp3/src/main/java/com/mcal/xmlpull/v1/xsd/impl/base64/Base64EncodingException.java: -------------------------------------------------------------------------------- 1 | /* -*- mode: Java; c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/ 2 | /* 3 | * Copyright (c) 2002-2004 Extreme! Lab, Indiana University. All rights reserved. 4 | * 5 | * This software is open source. See the bottom of this file for the licence. 6 | * 7 | * $Id: Base64EncodingException.java,v 1.4 2003/04/06 00:04:25 aslom Exp $ 8 | */ 9 | 10 | package com.mcal.xmlpull.v1.xsd.impl.base64; 11 | 12 | /** 13 | * @author Aleksander Slominski 14 | * @version $Revision: 1.4 $ $Date: 2003/04/06 00:04:25 $ (GMT) 15 | */ 16 | 17 | public class Base64EncodingException extends RuntimeException { 18 | public Base64EncodingException(String msg) { 19 | super(msg); 20 | } 21 | } 22 | 23 | /* 24 | * Indiana University Extreme! Lab Software License, Version 1.2 25 | * 26 | * Copyright (c) 2002-2004 The Trustees of Indiana University. 27 | * All rights reserved. 28 | * 29 | * Redistribution and use in source and binary forms, with or without 30 | * modification, are permitted provided that the following conditions are 31 | * met: 32 | * 33 | * 1) All redistributions of source code must retain the above 34 | * copyright notice, the list of authors in the original source 35 | * code, this list of conditions and the disclaimer listed in this 36 | * license; 37 | * 38 | * 2) All redistributions in binary form must reproduce the above 39 | * copyright notice, this list of conditions and the disclaimer 40 | * listed in this license in the documentation and/or other 41 | * materials provided with the distribution; 42 | * 43 | * 3) Any documentation included with all redistributions must include 44 | * the following acknowledgement: 45 | * 46 | * "This product includes software developed by the Indiana 47 | * University Extreme! Lab. For further information please visit 48 | * http://www.extreme.indiana.edu/" 49 | * 50 | * Alternatively, this acknowledgment may appear in the software 51 | * itself, and wherever such third-party acknowledgments normally 52 | * appear. 53 | * 54 | * 4) The name "Indiana University" or "Indiana University 55 | * Extreme! Lab" shall not be used to endorse or promote 56 | * products derived from this software without prior written 57 | * permission from Indiana University. For written permission, 58 | * please contact http://www.extreme.indiana.edu/. 59 | * 60 | * 5) Products derived from this software may not use "Indiana 61 | * University" name nor may "Indiana University" appear in their name, 62 | * without prior written permission of the Indiana University. 63 | * 64 | * Indiana University provides no reassurances that the source code 65 | * provided does not infringe the patent or any other intellectual 66 | * property rights of any other entity. Indiana University disclaims any 67 | * liability to any recipient for claims brought by any other entity 68 | * based on infringement of intellectual property rights or otherwise. 69 | * 70 | * LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH 71 | * NO WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA 72 | * UNIVERSITY GIVES NO WARRANTIES AND MAKES NO REPRESENTATION THAT 73 | * SOFTWARE IS FREE OF INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR 74 | * OTHER PROPRIETARY RIGHTS. INDIANA UNIVERSITY MAKES NO WARRANTIES THAT 75 | * SOFTWARE IS FREE FROM "BUGS", "VIRUSES", "TROJAN HORSES", "TRAP 76 | * DOORS", "WORMS", OR OTHER HARMFUL CODE. LICENSEE ASSUMES THE ENTIRE 77 | * RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR ASSOCIATED MATERIALS, 78 | * AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION GENERATED USING 79 | * SOFTWARE. 80 | */ 81 | -------------------------------------------------------------------------------- /xpp3/src/main/java/com/mcal/xmlpull/v1/xsd/impl/base64/Base64EncodingState.java: -------------------------------------------------------------------------------- 1 | /* -*- mode: Java; c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/ 2 | /* 3 | * Copyright (c) 2002-2004 Extreme! Lab, Indiana University. All rights reserved. 4 | * 5 | * This software is open source. See the bottom of this file for the licence. 6 | * 7 | * $Id: Base64EncodingState.java,v 1.4 2003/04/06 00:04:25 aslom Exp $ 8 | */ 9 | 10 | package com.mcal.xmlpull.v1.xsd.impl.base64; 11 | 12 | /** 13 | * @author Aleksander Slominski 14 | * @version $Revision: 1.4 $ $Date: 2003/04/06 00:04:25 $ (GMT) 15 | */ 16 | 17 | public class Base64EncodingState { 18 | int[] output = new int[3]; 19 | int outputEnd; 20 | 21 | public Base64EncodingState() { 22 | } 23 | } 24 | 25 | /* 26 | * Indiana University Extreme! Lab Software License, Version 1.2 27 | * 28 | * Copyright (c) 2002-2004 The Trustees of Indiana University. 29 | * All rights reserved. 30 | * 31 | * Redistribution and use in source and binary forms, with or without 32 | * modification, are permitted provided that the following conditions are 33 | * met: 34 | * 35 | * 1) All redistributions of source code must retain the above 36 | * copyright notice, the list of authors in the original source 37 | * code, this list of conditions and the disclaimer listed in this 38 | * license; 39 | * 40 | * 2) All redistributions in binary form must reproduce the above 41 | * copyright notice, this list of conditions and the disclaimer 42 | * listed in this license in the documentation and/or other 43 | * materials provided with the distribution; 44 | * 45 | * 3) Any documentation included with all redistributions must include 46 | * the following acknowledgement: 47 | * 48 | * "This product includes software developed by the Indiana 49 | * University Extreme! Lab. For further information please visit 50 | * http://www.extreme.indiana.edu/" 51 | * 52 | * Alternatively, this acknowledgment may appear in the software 53 | * itself, and wherever such third-party acknowledgments normally 54 | * appear. 55 | * 56 | * 4) The name "Indiana University" or "Indiana University 57 | * Extreme! Lab" shall not be used to endorse or promote 58 | * products derived from this software without prior written 59 | * permission from Indiana University. For written permission, 60 | * please contact http://www.extreme.indiana.edu/. 61 | * 62 | * 5) Products derived from this software may not use "Indiana 63 | * University" name nor may "Indiana University" appear in their name, 64 | * without prior written permission of the Indiana University. 65 | * 66 | * Indiana University provides no reassurances that the source code 67 | * provided does not infringe the patent or any other intellectual 68 | * property rights of any other entity. Indiana University disclaims any 69 | * liability to any recipient for claims brought by any other entity 70 | * based on infringement of intellectual property rights or otherwise. 71 | * 72 | * LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH 73 | * NO WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA 74 | * UNIVERSITY GIVES NO WARRANTIES AND MAKES NO REPRESENTATION THAT 75 | * SOFTWARE IS FREE OF INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR 76 | * OTHER PROPRIETARY RIGHTS. INDIANA UNIVERSITY MAKES NO WARRANTIES THAT 77 | * SOFTWARE IS FREE FROM "BUGS", "VIRUSES", "TROJAN HORSES", "TRAP 78 | * DOORS", "WORMS", OR OTHER HARMFUL CODE. LICENSEE ASSUMES THE ENTIRE 79 | * RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR ASSOCIATED MATERIALS, 80 | * AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION GENERATED USING 81 | * SOFTWARE. 82 | */ 83 | --------------------------------------------------------------------------------