Skip to content

Commit

Permalink
fix: refactor, improve performance and fix some issues in resource pr…
Browse files Browse the repository at this point in the history
…ocessing

fix(gui): instead gradle export was executed normal export
fix(gui): content of some resource files was not shown
perf: direct resource files saving without full length buffer in memory
perf(gui): line numbers will be disabled on big files due to performance issue
feat(gui): click on HeapUsageBar will run GC and update memory info
feat(gui): add more file types for syntax highlights
refactor: ResContainer class changed for support more types of data (added link to resource file)
  • Loading branch information
skylot committed Jan 22, 2019
1 parent bcaca78 commit 82d0d62
Show file tree
Hide file tree
Showing 18 changed files with 342 additions and 292 deletions.
14 changes: 7 additions & 7 deletions jadx-core/src/main/java/jadx/api/ResourceFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ public String toString() {
private final ResourceType type;
private ZipRef zipRef;

public static ResourceFile createResourceFile(JadxDecompiler decompiler, String name, ResourceType type) {
if (!ZipSecurity.isValidZipEntryName(name)) {
return null;
}
return new ResourceFile(decompiler, name, type);
}

protected ResourceFile(JadxDecompiler decompiler, String name, ResourceType type) {
this.decompiler = decompiler;
this.name = name;
Expand Down Expand Up @@ -65,11 +72,4 @@ public ZipRef getZipRef() {
public String toString() {
return "ResourceFile{name='" + name + '\'' + ", type=" + type + "}";
}

public static ResourceFile createResourceFileInstance(JadxDecompiler decompiler, String name, ResourceType type) {
if (!ZipSecurity.isValidZipEntryName(name)) {
return null;
}
return new ResourceFile(decompiler, name, type);
}
}
13 changes: 2 additions & 11 deletions jadx-core/src/main/java/jadx/api/ResourceFileContent.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,18 @@
package jadx.api;

import jadx.core.codegen.CodeWriter;
import jadx.core.utils.files.ZipSecurity;
import jadx.core.xmlgen.ResContainer;

public class ResourceFileContent extends ResourceFile {

private final CodeWriter content;

private ResourceFileContent(String name, ResourceType type, CodeWriter content) {
public ResourceFileContent(String name, ResourceType type, CodeWriter content) {
super(null, name, type);
this.content = content;
}

@Override
public ResContainer loadContent() {
return ResContainer.singleFile(getName(), content);
}

public static ResourceFileContent createResourceFileContentInstance(String name, ResourceType type, CodeWriter content) {
if (!ZipSecurity.isValidZipEntryName(name)) {
return null;
}
return new ResourceFileContent(name, type, content);
return ResContainer.textResource(getName(), content);
}
}
55 changes: 29 additions & 26 deletions jadx-core/src/main/java/jadx/api/ResourcesLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import jadx.api.ResourceFile.ZipRef;
import jadx.core.codegen.CodeWriter;
import jadx.core.utils.Utils;
import jadx.core.utils.android.Res9patchStreamDecoder;
import jadx.core.utils.exceptions.JadxException;
import jadx.core.utils.files.InputFile;
import jadx.core.utils.files.ZipSecurity;
Expand All @@ -31,8 +32,6 @@
public final class ResourcesLoader {
private static final Logger LOG = LoggerFactory.getLogger(ResourcesLoader.class);

private static final int LOAD_SIZE_LIMIT = 10 * 1024 * 1024;

private final JadxDecompiler jadxRef;

ResourcesLoader(JadxDecompiler jadxRef) {
Expand All @@ -47,11 +46,11 @@ List<ResourceFile> load(List<InputFile> inputFiles) {
return list;
}

public interface ResourceDecoder {
ResContainer decode(long size, InputStream is) throws IOException;
public interface ResourceDecoder<T> {
T decode(long size, InputStream is) throws IOException;
}

public static ResContainer decodeStream(ResourceFile rf, ResourceDecoder decoder) throws JadxException {
public static <T> T decodeStream(ResourceFile rf, ResourceDecoder<T> decoder) throws JadxException {
try {
ZipRef zipRef = rf.getZipRef();
if (zipRef == null) {
Expand Down Expand Up @@ -80,44 +79,48 @@ public static ResContainer decodeStream(ResourceFile rf, ResourceDecoder decoder

static ResContainer loadContent(JadxDecompiler jadxRef, ResourceFile rf) {
try {
return decodeStream(rf, (size, is) -> loadContent(jadxRef, rf, is, size));
return decodeStream(rf, (size, is) -> loadContent(jadxRef, rf, is));
} catch (JadxException e) {
LOG.error("Decode error", e);
CodeWriter cw = new CodeWriter();
cw.add("Error decode ").add(rf.getType().toString().toLowerCase());
cw.startLine(Utils.getStackTrace(e.getCause()));
return ResContainer.singleFile(rf.getName(), cw);
return ResContainer.textResource(rf.getName(), cw);
}
}

private static ResContainer loadContent(JadxDecompiler jadxRef, ResourceFile rf,
InputStream inputStream, long size) throws IOException {
InputStream inputStream) throws IOException {
switch (rf.getType()) {
case MANIFEST:
case XML:
return ResContainer.singleFile(rf.getName(),
jadxRef.getXmlParser().parse(inputStream));
CodeWriter content = jadxRef.getXmlParser().parse(inputStream);
return ResContainer.textResource(rf.getName(), content);

case ARSC:
return new ResTableParser()
.decodeFiles(inputStream);
return new ResTableParser().decodeFiles(inputStream);

case IMG:
return ResContainer.singleImageFile(rf.getName(), inputStream);

case CODE:
case LIB:
case FONT:
case UNKNOWN:
return ResContainer.singleBinaryFile(rf.getName(), inputStream);
return decodeImage(rf, inputStream);

default:
if (size > LOAD_SIZE_LIMIT) {
return ResContainer.singleFile(rf.getName(),
new CodeWriter().add("File too big, size: " + String.format("%.2f KB", size / 1024.)));
}
return ResContainer.singleFile(rf.getName(), loadToCodeWriter(inputStream));
return ResContainer.resourceFileLink(rf);
}
}

private static ResContainer decodeImage(ResourceFile rf, InputStream inputStream) {
String name = rf.getName();
if (name.endsWith(".9.png")) {
Res9patchStreamDecoder decoder = new Res9patchStreamDecoder();
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
decoder.decode(inputStream, os);
return ResContainer.decodedData(rf.getName(), os.toByteArray());
} catch (Exception e) {
LOG.error("Failed to decode 9-patch png image, path: {}", name, e);
}
}
return ResContainer.resourceFileLink(rf);
}

private void loadFile(List<ResourceFile> list, File file) {
Expand All @@ -141,7 +144,7 @@ private void loadFile(List<ResourceFile> list, File file) {
private void addResourceFile(List<ResourceFile> list, File file) {
String name = file.getAbsolutePath();
ResourceType type = ResourceType.getFileType(name);
ResourceFile rf = ResourceFile.createResourceFileInstance(jadxRef, name, type);
ResourceFile rf = ResourceFile.createResourceFile(jadxRef, name, type);
if (rf != null) {
list.add(rf);
}
Expand All @@ -153,7 +156,7 @@ private void addEntry(List<ResourceFile> list, File zipFile, ZipEntry entry) {
}
String name = entry.getName();
ResourceType type = ResourceType.getFileType(name);
ResourceFile rf = ResourceFile.createResourceFileInstance(jadxRef, name, type);
ResourceFile rf = ResourceFile.createResourceFile(jadxRef, name, type);
if (rf != null) {
rf.setZipRef(new ZipRef(zipFile, name));
list.add(rf);
Expand Down
31 changes: 16 additions & 15 deletions jadx-core/src/main/java/jadx/core/codegen/NameGen.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package jadx.core.codegen;

import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
Expand All @@ -21,6 +20,7 @@
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.utils.StringUtils;
import jadx.core.utils.Utils;

public class NameGen {

Expand All @@ -31,20 +31,21 @@ public class NameGen {
private final boolean fallback;

static {
OBJ_ALIAS = new HashMap<>();
OBJ_ALIAS.put(Consts.CLASS_STRING, "str");
OBJ_ALIAS.put(Consts.CLASS_CLASS, "cls");
OBJ_ALIAS.put(Consts.CLASS_THROWABLE, "th");
OBJ_ALIAS.put(Consts.CLASS_OBJECT, "obj");
OBJ_ALIAS.put("java.util.Iterator", "it");
OBJ_ALIAS.put("java.lang.Boolean", "bool");
OBJ_ALIAS.put("java.lang.Short", "sh");
OBJ_ALIAS.put("java.lang.Integer", "num");
OBJ_ALIAS.put("java.lang.Character", "ch");
OBJ_ALIAS.put("java.lang.Byte", "b");
OBJ_ALIAS.put("java.lang.Float", "f");
OBJ_ALIAS.put("java.lang.Long", "l");
OBJ_ALIAS.put("java.lang.Double", "d");
OBJ_ALIAS = Utils.newConstStringMap(
Consts.CLASS_STRING, "str",
Consts.CLASS_CLASS, "cls",
Consts.CLASS_THROWABLE, "th",
Consts.CLASS_OBJECT, "obj",
"java.util.Iterator", "it",
"java.lang.Boolean", "bool",
"java.lang.Short", "sh",
"java.lang.Integer", "num",
"java.lang.Character", "ch",
"java.lang.Byte", "b",
"java.lang.Float", "f",
"java.lang.Long", "l",
"java.lang.Double", "d"
);
}

public NameGen(MethodNode mth, boolean fallback) {
Expand Down
12 changes: 5 additions & 7 deletions jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import jadx.core.utils.ErrorsCounter;
import jadx.core.utils.StringUtils;
import jadx.core.utils.android.AndroidResourcesUtils;
import jadx.core.utils.exceptions.JadxException;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.core.utils.files.DexFile;
import jadx.core.utils.files.InputFile;
Expand Down Expand Up @@ -81,17 +80,16 @@ public void loadResources(List<ResourceFile> resources) {
LOG.debug("'.arsc' file not found");
return;
}
ResTableParser parser = new ResTableParser();
try {
ResourcesLoader.decodeStream(arsc, (size, is) -> {
ResourceStorage resStorage = ResourcesLoader.decodeStream(arsc, (size, is) -> {
ResTableParser parser = new ResTableParser();
parser.decode(is);
return null;
return parser.getResStorage();
});
} catch (JadxException e) {
processResources(resStorage);
} catch (Exception e) {
LOG.error("Failed to parse '.arsc' file", e);
return;
}
processResources(parser.getResStorage());
}

public void processResources(ResourceStorage resStorage) {
Expand Down
14 changes: 14 additions & 0 deletions jadx-core/src/main/java/jadx/core/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import jadx.api.JadxDecompiler;
Expand Down Expand Up @@ -161,4 +163,16 @@ public static <T> List<T> lockList(List<T> list) {
}
return new ImmutableList<>(list);
}

public static Map<String, String> newConstStringMap(String... parameters) {
int len = parameters.length;
if (len == 0) {
return Collections.emptyMap();
}
Map<String, String> result = new HashMap<>(len / 2);
for (int i = 0; i < len; i += 2) {
result.put(parameters[i], parameters[i + 1]);
}
return Collections.unmodifiableMap(result);
}
}
Loading

0 comments on commit 82d0d62

Please sign in to comment.