core: check registers numbers, fix fallback mode
This commit is contained in:
@@ -302,7 +302,7 @@ public class ClassGen {
|
||||
}
|
||||
}
|
||||
MethodGen mthGen;
|
||||
if (badCode || mth.contains(AType.JADX_ERROR)) {
|
||||
if (badCode || mth.contains(AType.JADX_ERROR) || fallback) {
|
||||
mthGen = MethodGen.getFallbackMethodGen(mth);
|
||||
} else {
|
||||
mthGen = new MethodGen(this, mth);
|
||||
@@ -313,7 +313,11 @@ public class ClassGen {
|
||||
code.add('{');
|
||||
code.incIndent();
|
||||
insertSourceFileInfo(code, mth);
|
||||
mthGen.addInstructions(code);
|
||||
if (fallback) {
|
||||
mthGen.addFallbackMethodCode(code);
|
||||
} else {
|
||||
mthGen.addInstructions(code);
|
||||
}
|
||||
code.decIndent();
|
||||
code.startLine('}');
|
||||
}
|
||||
@@ -535,7 +539,7 @@ public class ClassGen {
|
||||
private void insertSourceFileInfo(CodeWriter code, AttrNode node) {
|
||||
SourceFileAttr sourceFileAttr = node.get(AType.SOURCE_FILE);
|
||||
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 {
|
||||
|
||||
public String useArg(RegisterArg arg) {
|
||||
String name = arg.getName();
|
||||
if (name == null) {
|
||||
if (name == null || fallback) {
|
||||
return getFallbackName(arg);
|
||||
}
|
||||
return name;
|
||||
@@ -117,10 +117,7 @@ public class NameGen {
|
||||
private String getFallbackName(RegisterArg arg) {
|
||||
String name = arg.getName();
|
||||
String base = "r" + arg.getRegNum();
|
||||
if (name != null && !name.equals("this")) {
|
||||
return base + "_" + name;
|
||||
}
|
||||
return base;
|
||||
return name != null ? base + "_" + name : base;
|
||||
}
|
||||
|
||||
private static String makeNameForType(ArgType type) {
|
||||
|
||||
@@ -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() {
|
||||
if (!parseSignature()) {
|
||||
retType = mthInfo.getReturnType();
|
||||
|
||||
@@ -45,6 +45,8 @@ public class BlockMakerVisitor extends AbstractVisitor {
|
||||
if (mth.isNoCode()) {
|
||||
return;
|
||||
}
|
||||
mth.checkInstructions();
|
||||
|
||||
mth.initBasicBlocks();
|
||||
splitBasicBlocks(mth);
|
||||
processBlocksTree(mth);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package jadx.core.dex.visitors;
|
||||
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
import jadx.core.utils.ErrorsCounter;
|
||||
@@ -23,6 +24,9 @@ public class DepthTraversal {
|
||||
}
|
||||
|
||||
public static void visit(IDexTreeVisitor visitor, MethodNode mth) {
|
||||
if (mth.contains(AType.JADX_ERROR)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
visitor.visit(mth);
|
||||
} catch (Throwable e) {
|
||||
|
||||
@@ -335,13 +335,15 @@ public abstract class IntegrationTest extends TestUtils {
|
||||
return files;
|
||||
}
|
||||
|
||||
public void noDebugInfo() {
|
||||
protected void noDebugInfo() {
|
||||
this.withDebugInfo = false;
|
||||
}
|
||||
|
||||
// Try to make test class compilable
|
||||
@Deprecated
|
||||
public void disableCompilation() {
|
||||
protected void setFallback() {
|
||||
this.isFallback = true;
|
||||
}
|
||||
|
||||
protected void disableCompilation() {
|
||||
this.compile = false;
|
||||
}
|
||||
|
||||
@@ -351,12 +353,6 @@ public abstract class IntegrationTest extends TestUtils {
|
||||
this.outputCFG = true;
|
||||
}
|
||||
|
||||
// Use only for debug purpose
|
||||
@Deprecated
|
||||
protected void setFallback() {
|
||||
this.isFallback = true;
|
||||
}
|
||||
|
||||
// Use only for debug purpose
|
||||
@Deprecated
|
||||
protected void notDeleteTmpJar() {
|
||||
|
||||
@@ -25,7 +25,7 @@ public class SmaliTest extends IntegrationTest {
|
||||
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);
|
||||
if (smaliFile.exists()) {
|
||||
return smaliFile;
|
||||
@@ -38,7 +38,7 @@ public class SmaliTest extends IntegrationTest {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean compileSmali(File input, File output) {
|
||||
private static boolean compileSmali(File input, File output) {
|
||||
List<String> args = new ArrayList<String>();
|
||||
args.add(input.getAbsolutePath());
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
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")));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user