Commit a135eb44 authored by Skylot's avatar Skylot

core: check registers numbers, fix fallback mode

parent 252ed0e1
...@@ -302,7 +302,7 @@ public class ClassGen { ...@@ -302,7 +302,7 @@ public class ClassGen {
} }
} }
MethodGen mthGen; MethodGen mthGen;
if (badCode || mth.contains(AType.JADX_ERROR)) { if (badCode || mth.contains(AType.JADX_ERROR) || fallback) {
mthGen = MethodGen.getFallbackMethodGen(mth); mthGen = MethodGen.getFallbackMethodGen(mth);
} else { } else {
mthGen = new MethodGen(this, mth); mthGen = new MethodGen(this, mth);
...@@ -313,7 +313,11 @@ public class ClassGen { ...@@ -313,7 +313,11 @@ public class ClassGen {
code.add('{'); code.add('{');
code.incIndent(); code.incIndent();
insertSourceFileInfo(code, mth); insertSourceFileInfo(code, mth);
mthGen.addInstructions(code); if (fallback) {
mthGen.addFallbackMethodCode(code);
} else {
mthGen.addInstructions(code);
}
code.decIndent(); code.decIndent();
code.startLine('}'); code.startLine('}');
} }
...@@ -535,7 +539,7 @@ public class ClassGen { ...@@ -535,7 +539,7 @@ public class ClassGen {
private void insertSourceFileInfo(CodeWriter code, AttrNode node) { private void insertSourceFileInfo(CodeWriter code, AttrNode node) {
SourceFileAttr sourceFileAttr = node.get(AType.SOURCE_FILE); SourceFileAttr sourceFileAttr = node.get(AType.SOURCE_FILE);
if (sourceFileAttr != null) { if (sourceFileAttr != null) {
code.startLine("// compiled from: ").add(sourceFileAttr.getFileName()); code.startLine("/* compiled from: ").add(sourceFileAttr.getFileName()).add(" */");
} }
} }
......
...@@ -70,7 +70,7 @@ public class NameGen { ...@@ -70,7 +70,7 @@ public class NameGen {
public String useArg(RegisterArg arg) { public String useArg(RegisterArg arg) {
String name = arg.getName(); String name = arg.getName();
if (name == null) { if (name == null || fallback) {
return getFallbackName(arg); return getFallbackName(arg);
} }
return name; return name;
...@@ -117,10 +117,7 @@ public class NameGen { ...@@ -117,10 +117,7 @@ public class NameGen {
private String getFallbackName(RegisterArg arg) { private String getFallbackName(RegisterArg arg) {
String name = arg.getName(); String name = arg.getName();
String base = "r" + arg.getRegNum(); String base = "r" + arg.getRegNum();
if (name != null && !name.equals("this")) { return name != null ? base + "_" + name : base;
return base + "_" + name;
}
return base;
} }
private static String makeNameForType(ArgType type) { private static String makeNameForType(ArgType type) {
......
...@@ -114,6 +114,26 @@ public class MethodNode extends LineAttrNode implements ILoadable { ...@@ -114,6 +114,26 @@ public class MethodNode extends LineAttrNode implements ILoadable {
} }
} }
public void checkInstructions() {
List<RegisterArg> list = new ArrayList<RegisterArg>();
for (InsnNode insnNode : instructions) {
if (insnNode == null) {
continue;
}
list.clear();
RegisterArg resultArg = insnNode.getResult();
if (resultArg != null) {
list.add(resultArg);
}
insnNode.getRegisterArgs(list);
for (int i = 0, listSize = list.size(); i < listSize; i++) {
if (list.get(i).getRegNum() >= regsCount) {
throw new JadxRuntimeException("Incorrect register number in instruction: " + insnNode);
}
}
}
}
private void initMethodTypes() { private void initMethodTypes() {
if (!parseSignature()) { if (!parseSignature()) {
retType = mthInfo.getReturnType(); retType = mthInfo.getReturnType();
......
...@@ -45,6 +45,8 @@ public class BlockMakerVisitor extends AbstractVisitor { ...@@ -45,6 +45,8 @@ public class BlockMakerVisitor extends AbstractVisitor {
if (mth.isNoCode()) { if (mth.isNoCode()) {
return; return;
} }
mth.checkInstructions();
mth.initBasicBlocks(); mth.initBasicBlocks();
splitBasicBlocks(mth); splitBasicBlocks(mth);
processBlocksTree(mth); processBlocksTree(mth);
......
package jadx.core.dex.visitors; package jadx.core.dex.visitors;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.MethodNode;
import jadx.core.utils.ErrorsCounter; import jadx.core.utils.ErrorsCounter;
...@@ -23,6 +24,9 @@ public class DepthTraversal { ...@@ -23,6 +24,9 @@ public class DepthTraversal {
} }
public static void visit(IDexTreeVisitor visitor, MethodNode mth) { public static void visit(IDexTreeVisitor visitor, MethodNode mth) {
if (mth.contains(AType.JADX_ERROR)) {
return;
}
try { try {
visitor.visit(mth); visitor.visit(mth);
} catch (Throwable e) { } catch (Throwable e) {
......
...@@ -335,13 +335,15 @@ public abstract class IntegrationTest extends TestUtils { ...@@ -335,13 +335,15 @@ public abstract class IntegrationTest extends TestUtils {
return files; return files;
} }
public void noDebugInfo() { protected void noDebugInfo() {
this.withDebugInfo = false; this.withDebugInfo = false;
} }
// Try to make test class compilable protected void setFallback() {
@Deprecated this.isFallback = true;
public void disableCompilation() { }
protected void disableCompilation() {
this.compile = false; this.compile = false;
} }
...@@ -353,12 +355,6 @@ public abstract class IntegrationTest extends TestUtils { ...@@ -353,12 +355,6 @@ public abstract class IntegrationTest extends TestUtils {
// Use only for debug purpose // Use only for debug purpose
@Deprecated @Deprecated
protected void setFallback() {
this.isFallback = true;
}
// Use only for debug purpose
@Deprecated
protected void notDeleteTmpJar() { protected void notDeleteTmpJar() {
this.deleteTmpFiles = false; this.deleteTmpFiles = false;
} }
......
...@@ -25,7 +25,7 @@ public class SmaliTest extends IntegrationTest { ...@@ -25,7 +25,7 @@ public class SmaliTest extends IntegrationTest {
return getClassNodeFromFile(outDex, fullClsName); return getClassNodeFromFile(outDex, fullClsName);
} }
private File getSmaliFile(String clsName) { private static File getSmaliFile(String clsName) {
File smaliFile = new File(SMALI_TESTS_DIR, clsName + SMALI_TESTS_EXT); File smaliFile = new File(SMALI_TESTS_DIR, clsName + SMALI_TESTS_EXT);
if (smaliFile.exists()) { if (smaliFile.exists()) {
return smaliFile; return smaliFile;
...@@ -38,7 +38,7 @@ public class SmaliTest extends IntegrationTest { ...@@ -38,7 +38,7 @@ public class SmaliTest extends IntegrationTest {
return null; return null;
} }
public boolean compileSmali(File input, File output) { private static boolean compileSmali(File input, File output) {
List<String> args = new ArrayList<String>(); List<String> args = new ArrayList<String>();
args.add(input.getAbsolutePath()); args.add(input.getAbsolutePath());
......
package jadx.tests.integration.fallback;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
public class TestFallbackMode extends IntegrationTest {
public static class TestCls {
public int test(int a) {
while (a < 10) {
a++;
}
return a;
}
}
@Test
public void test() {
setFallback();
disableCompilation();
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, containsString("public int test(int r2) {"));
assertThat(code, containsString("r1_this = this;"));
assertThat(code, containsString("L_0x0004:"));
assertThat(code, not(containsString("throw new UnsupportedOperationException")));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment