Skip to content

Commit

Permalink
Add experimental COMPUTE_FRAMES option
Browse files Browse the repository at this point in the history
  • Loading branch information
ThexXTURBOXx committed Dec 16, 2023
1 parent 9c9580b commit 2f6e9e0
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
Expand Up @@ -98,6 +98,13 @@ public class DexFileReader implements BaseDexFileReader {

public static final int DONT_SANITIZE_NAMES = 1 << 9;

/**
* Instruct ASM to compute frames when generating class files,
* using {@link org.objectweb.asm.ClassWriter#COMPUTE_FRAMES}
* **EXPERIMENTAL CODE**
*/
public static final int COMPUTE_FRAMES = 1 << 10;

// private static final int REVERSE_ENDIAN_CONSTANT = 0x78563412;

static final int DBG_END_SEQUENCE = 0x00;
Expand Down
Expand Up @@ -61,6 +61,10 @@ public static void main(String... args) {
@Opt(opt = "dsn", longOpt = "dont-sanitize-names", hasArg = false, description = "do not replace '_' by '-'")
private boolean dontSanitizeNames = false;

@Opt(opt = "cf", longOpt = "compute-frames", hasArg = false,
description = "instructs ASM to compute frames - experimental!")
private boolean computeFrames = false;

@Override
protected void doCommandLine() throws Exception {
if (remainingArgs.length == 0) {
Expand Down Expand Up @@ -104,7 +108,8 @@ protected void doCommandLine() throws Exception {
BaksmaliBaseDexExceptionHandler handler = notHandleException ? null : new BaksmaliBaseDexExceptionHandler();
Dex2jar.from(reader).withExceptionHandler(handler).reUseReg(reuseReg).topoLogicalSort()
.skipDebug(!debugInfo).optimizeSynchronized(this.optmizeSynchronized).printIR(printIR)
.noCode(noCode).skipExceptions(skipExceptions).dontSanitizeNames(dontSanitizeNames).to(file);
.noCode(noCode).skipExceptions(skipExceptions).dontSanitizeNames(dontSanitizeNames)
.computeFrames(computeFrames).to(file);

if (!notHandleException) {
if (handler.hasException()) {
Expand Down
51 changes: 50 additions & 1 deletion dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2jar.java
Expand Up @@ -20,9 +20,12 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.spi.FileSystemProvider;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
Expand Down Expand Up @@ -57,6 +60,11 @@ public void doTranslate(final ByteArrayOutputStream baos) {
doTranslate(null, baos);
}

private static String toInternalClassName(String key) {
if (key.endsWith(";")) key = key.substring(1, key.length() - 1);
return key;
}

/**
* Translates a dex file to a class file and writes it to the specified destination path and stream.
*
Expand All @@ -71,10 +79,42 @@ public void doTranslate(final Path dist, final ByteArrayOutputStream baos) {
} catch (Exception ex) {
exceptionHandler.handleFileException(ex);
}

Map<String, String> parentsByName = fileNode.clzs.stream()
.filter(c -> c.superClass != null)
.collect(Collectors.toMap(
c -> toInternalClassName(c.className),
c -> toInternalClassName(c.superClass)));

ClassVisitorFactory cvf = new ClassVisitorFactory() {
@Override
public ClassVisitor create(final String name) {
final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
final ClassWriter cw = (readerConfig & DexFileReader.COMPUTE_FRAMES) == 0
? new ClassWriter(ClassWriter.COMPUTE_MAXS)
: new ClassWriter(ClassWriter.COMPUTE_FRAMES) {
@Override
protected String getCommonSuperClass(String type1, String type2) {
if (type1.equals(type2)) return type1;

List<String> parentsOfType1 = new ArrayList<>();
parentsOfType1.add(type1);
while (parentsByName.containsKey(type1)) {
type1 = parentsByName.get(type1);
parentsOfType1.add(type1);
}

while (parentsByName.containsKey(type2)) {
type2 = parentsByName.get(type2);
if (parentsOfType1.contains(type2)) return type2;
}

try {
return super.getCommonSuperClass(type1, type2);
} catch (Throwable t) {
return "java/util/Object";
}
}
};
final LambadaNameSafeClassAdapter rca = new LambadaNameSafeClassAdapter(cw,
(readerConfig & DexFileReader.DONT_SANITIZE_NAMES) != 0);
return new ClassVisitor(Constants.ASM_VERSION, rca) {
Expand Down Expand Up @@ -324,6 +364,15 @@ public Dex2jar dontSanitizeNames(boolean b) {
return this;
}

public Dex2jar computeFrames(boolean b) {
if (b) {
this.readerConfig |= DexFileReader.COMPUTE_FRAMES;
} else {
this.readerConfig &= ~DexFileReader.COMPUTE_FRAMES;
}
return this;
}

public Dex2jar setRandom(Random random) {
Dex2jar.random = random;
return this;
Expand Down

0 comments on commit 2f6e9e0

Please sign in to comment.