Skip to content

Commit

Permalink
Update ARSCLib 1.3.6
Browse files Browse the repository at this point in the history
  • Loading branch information
REAndroid committed Nov 8, 2024
1 parent 26b5715 commit 4d3cfe3
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 139 deletions.
Binary file modified libs/ARSCLib.jar
Binary file not shown.
17 changes: 8 additions & 9 deletions src/main/java/com/reandroid/apkeditor/compile/Builder.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@ public void buildJson() throws IOException {

BuildOptions options = getOptions();

SmaliCompiler smaliCompiler = new SmaliCompiler(options.noCache);
smaliCompiler.setApkLogger(this);
encoder.setDexEncoder(smaliCompiler);
encoder.setDexEncoder(getSmaliCompiler());

encoder.scanDirectory(options.inputFile);
ApkModule loadedModule = encoder.getApkModule();
Expand All @@ -99,10 +97,8 @@ public void buildXml() throws IOException {

BuildOptions options = getOptions();

SmaliCompiler smaliCompiler = new SmaliCompiler(options.noCache);
smaliCompiler.setApkLogger(this);
encoder.setDexEncoder(getSmaliCompiler());

encoder.setDexEncoder(smaliCompiler);
ApkModule loadedModule = encoder.getApkModule();
loadedModule.setAPKLogger(this);

Expand All @@ -128,10 +124,8 @@ public void buildRaw() throws IOException {
logMessage("Keep original binaries");
}

SmaliCompiler smaliCompiler = new SmaliCompiler(options.noCache);
smaliCompiler.setApkLogger(this);
encoder.setDexEncoder(getSmaliCompiler());

encoder.setDexEncoder(smaliCompiler);
ApkModule loadedModule = encoder.getApkModule();
loadedModule.setAPKLogger(this);

Expand All @@ -146,4 +140,9 @@ public void buildRaw() throws IOException {
loadedModule.close();
logMessage("Saved to: " + options.outputFile);
}
private SmaliCompiler getSmaliCompiler() {
SmaliCompiler smaliCompiler = new SmaliCompiler(getOptions());
smaliCompiler.setApkLogger(this);
return smaliCompiler;
}
}
9 changes: 7 additions & 2 deletions src/main/java/com/reandroid/apkeditor/info/Info.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@
import com.reandroid.arsc.model.ResourceEntry;
import com.reandroid.arsc.value.*;
import com.reandroid.dex.model.DexDirectory;
import com.reandroid.dex.sections.SectionType;
import com.reandroid.utils.CompareUtil;
import com.reandroid.utils.HexUtil;
import com.reandroid.utils.collection.CollectionUtil;
import com.reandroid.utils.collection.ComputeIterator;

import java.io.*;
import java.util.*;
import java.util.function.Function;

public class Info extends CommandExecutor<InfoOptions> {
private InfoWriter mInfoWriter;
Expand Down Expand Up @@ -138,8 +138,13 @@ private void printDex(ApkModule apkModule) throws IOException {
return;
}
InfoWriter infoWriter = getInfoWriter();
DexDirectory dexDirectory = DexDirectory.readStrings(apkModule.getZipEntryMap());
DexDirectory dexDirectory = DexDirectory.fromZip(apkModule.getZipEntryMap(),
sectionType -> sectionType == SectionType.STRING_ID ||
sectionType == SectionType.STRING_DATA);

infoWriter.writeDexInfo(dexDirectory);

dexDirectory.close();
}
private void printSignatures(ApkModule apkModule) throws IOException {
InfoOptions options = getOptions();
Expand Down
51 changes: 37 additions & 14 deletions src/main/java/com/reandroid/apkeditor/info/InfoWriterText.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
import com.reandroid.arsc.value.*;
import com.reandroid.common.Namespace;
import com.reandroid.dex.model.DexFile;
import com.reandroid.dex.sections.MapItem;
import com.reandroid.dex.sections.MapList;
import com.reandroid.dex.model.DexLayout;
import com.reandroid.dex.model.DexSectionInfo;
import com.reandroid.dex.sections.Marker;
import com.reandroid.utils.HexUtil;
import com.reandroid.utils.StringsUtil;
Expand Down Expand Up @@ -203,8 +203,41 @@ public void writeDexInfo(DexFile dexFile, boolean writeSectionInfo) throws IOExc
Writer writer = getWriter();
writer.write("\n");
writeNameValue("Name", dexFile.getFileName());
writeNameValue("Version", dexFile.getVersion());
List<Marker> markersList = CollectionUtil.toList(dexFile.getMarkers());
if (dexFile.isMultiLayout()) {
int size = dexFile.size();
for (int i = 0; i < size; i++) {
writeLayout(dexFile.getLayout(i));
}
writeNameValue("TotalClasses", dexFile.getDexClassesCountForDebug());
} else if(dexFile.size() != 0) {
writeLayout(dexFile.getFirst());
} else {
writer.write("EMPTY DEX");
writer.write("\n");
}
writer.flush();
}
private void writeLayout(DexLayout layout) throws IOException {
Writer writer = getWriter();
if (layout.isMultiLayoutEntry()) {
writer.write(layout.getName());
writer.write(", ");
}
writeNameValue("Version", layout.getVersion());
writeMarkers(layout.getMarkers());
writer.write("Sections:");
Iterator<DexSectionInfo> iterator = layout.getSectionInfo();
while (iterator.hasNext()){
DexSectionInfo sectionInfo = iterator.next();
writer.write("\n");
writer.write(ARRAY_TAB);
writer.write(sectionInfo.print(false));
}
writer.write("\n");
}
private void writeMarkers(Iterator<Marker> iterator) throws IOException {
Writer writer = getWriter();
List<Marker> markersList = CollectionUtil.toList(iterator);
if(markersList.size() != 0){
writer.write("Markers:");
for(Marker marker : markersList){
Expand All @@ -213,16 +246,6 @@ public void writeDexInfo(DexFile dexFile, boolean writeSectionInfo) throws IOExc
writer.write(marker.toString());
}
}
writer.write("\n");
MapList mapList = dexFile.getDexLayout().getMapList();
writer.write("Sections:");
for(MapItem mapItem : mapList){
writer.write("\n");
writer.write(ARRAY_TAB);
writer.write(mapItem.toString());
}
writer.write("\n");
writer.flush();
}
@Override
public void writeResources(PackageBlock packageBlock, List<String> typeFilters, boolean writeEntries) throws IOException {
Expand Down
78 changes: 58 additions & 20 deletions src/main/java/com/reandroid/apkeditor/info/InfoWriterXml.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import com.reandroid.arsc.item.StringItem;
import com.reandroid.arsc.pool.StringPool;
import com.reandroid.dex.model.DexFile;
import com.reandroid.dex.sections.MapItem;
import com.reandroid.dex.sections.MapList;
import com.reandroid.dex.model.DexLayout;
import com.reandroid.dex.model.DexSectionInfo;
import com.reandroid.dex.sections.Marker;
import com.reandroid.utils.collection.CollectionUtil;
import com.reandroid.utils.collection.ComputeList;
Expand Down Expand Up @@ -119,35 +119,73 @@ public void writeDexInfo(DexFile dexFile, boolean writeSectionInfo) throws IOExc
int indent = mIndent + 2;
mIndent = indent;
writeIndent(serializer, indent);
indent = mIndent + 2;
mIndent = indent;
serializer.startTag(null, "dex");

serializer.attribute(null, "name", dexFile.getFileName());
serializer.attribute(null, "version", Integer.toString(dexFile.getVersion()));
List<Marker> markersList = CollectionUtil.toList(dexFile.getMarkers());
writeArray("markers", markersList.toArray());

MapList mapList = dexFile.getDexLayout().getMapList();
if (dexFile.isMultiLayout()) {
int size = dexFile.size();
serializer.attribute(null, "layouts", Integer.toString(size));
for (int i = 0; i < size; i++) {
writeDexLayout(serializer, dexFile.getLayout(i));
}
} else if (dexFile.size() != 0) {
writeDexLayout(serializer, dexFile.getFirst());
} else {
serializer.text("EMPTY DEX");
}
writeIndent(serializer, indent);
serializer.startTag(null, "dex-sections");
indent = mIndent + 2;
serializer.endTag(null, "dex");
indent = mIndent - 2;
mIndent = indent;
for(MapItem mapItem : mapList){
}
private void writeDexLayout(KXmlSerializer serializer, DexLayout layout) throws IOException {
int indent = mIndent + 2;
mIndent = indent;
boolean tagOpened = false;
if (layout.isMultiLayoutEntry()) {
writeIndent(serializer, indent);
serializer.startTag(null, "layout");
indent = mIndent + 2;
mIndent = indent;
tagOpened = true;
serializer.attribute(null, "name", layout.getName());
serializer.attribute(null, "version", Integer.toString(layout.getVersion()));
}
List<Marker> markersList = CollectionUtil.toList(layout.getMarkers());
if (markersList.size() != 0) {
writeArray("markers", markersList.toArray());
}
writeSectionInfo(serializer, layout);
indent = indent - 2;
this.mIndent = indent;
if (tagOpened) {
writeIndent(serializer, indent);
serializer.endTag(null, "layout");
indent = indent - 2;
this.mIndent = indent;
}
}
private void writeSectionInfo(KXmlSerializer serializer, DexLayout layout) throws IOException {
Iterator<DexSectionInfo> iterator = layout.getSectionInfo();
if (!iterator.hasNext()) {
return;
}
int indent = this.mIndent;
writeIndent(serializer, indent);
serializer.startTag(null, "dex-sections");
while (iterator.hasNext()) {
DexSectionInfo sectionInfo = iterator.next();
writeIndent(serializer, indent + 2);
serializer.startTag(null, "section");
serializer.attribute(null, "name", mapItem.getSectionType().getName());
serializer.attribute(null, "count", Integer.toString(mapItem.getCountValue()));
serializer.attribute(null, "offset", Integer.toString(mapItem.getOffsetValue()));
serializer.attribute(null, "name", sectionInfo.getSectionType().getName());
serializer.attribute(null, "count", Integer.toString(sectionInfo.getCount()));
serializer.attribute(null, "offset", Integer.toString(sectionInfo.getOffset()));
serializer.endTag(null, "section");
}
indent = mIndent - 2;
mIndent = indent;
this.mIndent = indent;
writeIndent(serializer, indent);
serializer.endTag(null, "dex-sections");
indent = mIndent - 2;
mIndent = indent;
writeIndent(serializer, indent);
serializer.endTag(null, "dex");
}
@Override
public void writeResources(PackageBlock packageBlock, List<String> typeFilters, boolean writeEntries) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.reandroid.apkeditor.protect;

import com.reandroid.apk.ApkModule;
import com.reandroid.app.AndroidApiLevel;
import com.reandroid.arsc.chunk.xml.AndroidManifestBlock;
import com.reandroid.arsc.chunk.xml.ResXmlAttribute;
import com.reandroid.arsc.chunk.xml.ResXmlElement;
Expand All @@ -38,6 +39,7 @@ public void confuse() {
}
ApkModule apkModule = getApkModule();
AndroidManifestBlock manifestBlock = apkModule.getAndroidManifest();
placeBadChunk(manifestBlock);
int defaultAttributeSize = 20;
List<ResXmlElement> elementList = CollectionUtil.toList(manifestBlock.recursiveElements());
Random random = new Random();
Expand All @@ -52,4 +54,15 @@ public void confuse() {
defaultAttributeSize, false);
manifestBlock.refresh();
}
private void placeBadChunk(AndroidManifestBlock manifestBlock) {
AndroidManifestBlock badManifest = new AndroidManifestBlock();
badManifest.setPackageName("android");
badManifest.setCompileSdk(AndroidApiLevel.U);
badManifest.setPlatformBuild(AndroidApiLevel.U);
badManifest.setVersionCode(1);
badManifest.setVersionName("1.0");
badManifest.refreshFull();
manifestBlock.getUnexpectedBlockContainer()
.setItem(badManifest);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,5 @@ public void runCommand() throws IOException {
module.writeApk(options.outputFile);
module.close();
logMessage("Saved to: " + options.outputFile);
module.close();
}
}
47 changes: 11 additions & 36 deletions src/main/java/com/reandroid/apkeditor/smali/SmaliCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,12 @@
import com.reandroid.apk.ApkModuleEncoder;
import com.reandroid.apk.DexEncoder;
import com.reandroid.apkeditor.APKEditor;
import com.reandroid.apkeditor.compile.BuildOptions;
import com.reandroid.archive.FileInputSource;
import com.reandroid.archive.InputSource;
import com.reandroid.arsc.chunk.xml.AndroidManifestBlock;
import com.reandroid.dex.model.DexFile;
import com.reandroid.dex.sections.Marker;
import com.reandroid.dex.sections.SectionType;
import com.reandroid.dex.smali.SmaliReader;
import com.reandroid.utils.StringsUtil;
import com.reandroid.utils.io.FileIterator;
import com.reandroid.utils.io.IOUtil;
import org.jf.dexlib2.extra.DexMarker;
import org.jf.smali.Smali;
import org.jf.smali.SmaliOptions;
Expand All @@ -39,12 +35,15 @@
import java.util.List;

public class SmaliCompiler implements DexEncoder {

private final BuildOptions buildOptions;
private APKLogger apkLogger;
private final boolean noCache;
private Integer minSdkVersion;
public SmaliCompiler(boolean noCache){
this.noCache = noCache;

public SmaliCompiler(BuildOptions buildOptions) {
this.buildOptions = buildOptions;
}

@Override
public List<InputSource> buildDexFiles(ApkModuleEncoder apkModuleEncoder, File mainDir) throws IOException {
File smaliDir = new File(mainDir, "smali");
Expand All @@ -56,7 +55,7 @@ public List<InputSource> buildDexFiles(ApkModuleEncoder apkModuleEncoder, File m
this.minSdkVersion = manifestBlock.getMinSdkVersion();
}
if(minSdkVersion == null){
minSdkVersion = 30;
minSdkVersion = 24;
}
List<InputSource> results = new ArrayList<>();
List<File> classesDirList = listClassesDirectories(smaliDir);
Expand Down Expand Up @@ -112,48 +111,24 @@ private InputSource buildJesusFreke(String progress, File classesDir, File dexCa
private InputSource buildExperimental(String progress, File classesDir, File dexCacheFile) throws IOException {
logMessage(progress + "Smali: " + dexCacheFile.getName());
DexFile dexFile = DexFile.createDefault();
FileIterator fileIterator = new FileIterator(classesDir,
FileIterator.getExtensionFilter(".smali"));
while (fileIterator.hasNext()) {
File file = fileIterator.next();
try {
dexFile.fromSmali(SmaliReader.of(file));
}catch (Exception e) {
throw new IOException("Error at: " + file, e);
}
}
dexFile.refresh();
readMarkers(dexFile, classesDir);
int version = 0;
if (this.minSdkVersion != null) {
version = minSdkVersion;
}
version = apiToDexVersion(version);
dexFile.setVersion(version);
dexFile.parseSmaliDirectory(classesDir);
dexFile.refresh();
dexFile.clearEmptySections();
dexFile.sortSection(SectionType.getR8Order());
dexFile.shrink();
dexFile.refreshFull();
dexFile.write(dexCacheFile);
dexFile.close();
return new FileInputSource(dexCacheFile, dexCacheFile.getName());
}
private void readMarkers(DexFile dexFile, File classesDir) throws IOException {
File markersFile = new File(classesDir, DexMarker.FILE_NAME);
if(markersFile.isFile()){
logMessage("Reading markers ...");
String[] content = StringsUtil.split(IOUtil.readUtf8(markersFile), '\n');
for(String markerString : content) {
Marker marker = Marker.parse(markerString);
if(marker != null) {
dexFile.addMarker(marker);
}
}
}
}

private boolean isModified(File classesDir, File dexCacheFile){
if(noCache || !dexCacheFile.isFile()){
if(buildOptions.noCache || !dexCacheFile.isFile()){
return true;
}
long dexMod = dexCacheFile.lastModified();
Expand Down
Loading

0 comments on commit 4d3cfe3

Please sign in to comment.