提交 b52f3525 编写于 作者: S Skylot

core: support 'not-int' and 'not-long' instructions

上级 20bf85b1
......@@ -9,6 +9,7 @@ dependencies {
compile 'com.intellij:annotations:12.0'
compile 'uk.com.robust-it:cloning:1.9.2'
testCompile 'org.smali:smali:2.0.3'
testCompile 'org.smali:smali:2.2.2'
testCompile 'org.smali:baksmali:2.2.2'
}
......@@ -270,18 +270,13 @@ public class InsnGen {
makeArith((ArithNode) insn, code, state);
break;
case NEG: {
boolean wrap = state.contains(Flags.BODY_ONLY);
if (wrap) {
code.add('(');
}
code.add('-');
addArg(code, insn.getArg(0));
if (wrap) {
code.add(')');
}
case NEG:
oneArgInsn(code, insn, state, '-');
break;
case NOT:
oneArgInsn(code, insn, state, '~');
break;
}
case RETURN:
if (insn.getArgsCount() != 0) {
......@@ -525,6 +520,18 @@ public class InsnGen {
}
}
private void oneArgInsn(CodeWriter code, InsnNode insn, Set<Flags> state, char op) throws CodegenException {
boolean wrap = state.contains(Flags.BODY_ONLY);
if (wrap) {
code.add('(');
}
code.add(op);
addArg(code, insn.getArg(0));
if (wrap) {
code.add(')');
}
}
private void fallbackOnlyInsn(InsnNode insn) throws CodegenException {
if (!fallback) {
throw new CodegenException(insn.getType() + " can be used only in fallback mode");
......
......@@ -324,6 +324,11 @@ public class InsnDecoder {
case Opcodes.NEG_DOUBLE:
return neg(insn, ArgType.DOUBLE);
case Opcodes.NOT_INT:
return not(insn, ArgType.INT);
case Opcodes.NOT_LONG:
return not(insn, ArgType.LONG);
case Opcodes.INT_TO_BYTE:
return cast(insn, ArgType.INT, ArgType.BYTE);
case Opcodes.INT_TO_CHAR:
......@@ -699,6 +704,13 @@ public class InsnDecoder {
return inode;
}
private InsnNode not(DecodedInstruction insn, ArgType type) {
InsnNode inode = new InsnNode(InsnType.NOT, 1);
inode.setResult(InsnArg.reg(insn, 0, type));
inode.addArg(InsnArg.reg(insn, 1, type));
return inode;
}
private InsnNode insn(InsnType type, RegisterArg res) {
InsnNode node = new InsnNode(type, 0);
node.setResult(res);
......
......@@ -8,6 +8,7 @@ public enum InsnType {
ARITH,
NEG,
NOT,
MOVE,
CAST,
......
......@@ -81,26 +81,10 @@ public class ErrorsCounter {
}
public static String formatErrorMsg(ClassNode cls, String msg) {
return msg + " in class: " + cls;
return msg + " in class: " + cls + ", dex: " + cls.dex().getDexFile().getName();
}
public static String formatErrorMsg(MethodNode mth, String msg) {
return msg + " in method: " + mth;
}
private String formatException(Throwable e) {
if (e == null || e.getMessage() == null) {
return "";
} else {
return "\n error: " + e.getMessage();
}
}
public String formatErrorMsg(ClassNode cls, String msg, Throwable e) {
return formatErrorMsg(cls, msg) + formatException(e);
}
public String formatErrorMsg(MethodNode mth, String msg, Throwable e) {
return formatErrorMsg(mth, msg) + formatException(e);
return msg + " in method: " + mth + ", dex: " + mth.dex().getDexFile().getName();
}
}
......@@ -35,7 +35,6 @@ import jadx.tests.api.compiler.StaticCompiler;
import jadx.tests.api.utils.TestUtils;
import static jadx.core.utils.files.FileUtils.addFileToJar;
import static jadx.core.utils.files.FileUtils.close;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.is;
......@@ -261,11 +260,11 @@ public abstract class IntegrationTest extends TestUtils {
assertThat("File list is empty", list, not(empty()));
File temp = createTempFile(".jar");
JarOutputStream jo = new JarOutputStream(new FileOutputStream(temp));
for (File file : list) {
addFileToJar(jo, file, path + "/" + file.getName());
try (JarOutputStream jo = new JarOutputStream(new FileOutputStream(temp))) {
for (File file : list) {
addFileToJar(jo, file, path + "/" + file.getName());
}
}
close(jo);
return temp;
}
......@@ -336,13 +335,7 @@ public abstract class IntegrationTest extends TestUtils {
outTmp.deleteOnExit();
List<File> files = StaticCompiler.compile(compileFileList, outTmp, withDebugInfo);
// remove classes which are parents for test class
Iterator<File> iterator = files.iterator();
while (iterator.hasNext()) {
File next = iterator.next();
if (!next.getName().contains(cls.getSimpleName())) {
iterator.remove();
}
}
files.removeIf(next -> !next.getName().contains(cls.getSimpleName()));
for (File clsFile : files) {
clsFile.deleteOnExit();
}
......
package jadx.tests.api;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.jf.smali.main;
import org.jf.smali.Smali;
import org.jf.smali.SmaliOptions;
import jadx.core.dex.nodes.ClassNode;
import static org.junit.Assert.fail;
public abstract class SmaliTest extends IntegrationTest {
private static final String SMALI_TESTS_PROJECT = "jadx-core";
private static final String SMALI_TESTS_DIR = "src/test/smali";
private static final String SMALI_TESTS_EXT = ".smali";
protected ClassNode getClassNodeFromSmali(String clsName) {
File smaliFile = getSmaliFile(clsName);
protected ClassNode getClassNodeFromSmali(String file, String clsName) {
File smaliFile = getSmaliFile(file);
File outDex = createTempFile(".dex");
compileSmali(smaliFile, outDex);
return getClassNodeFromFile(outDex, clsName);
}
protected ClassNode getClassNodeFromSmaliWithPath(String path, String clsName) {
return getClassNodeFromSmali(path + File.separatorChar + clsName, clsName);
}
protected ClassNode getClassNodeFromSmali(String clsName) {
return getClassNodeFromSmali(clsName, clsName);
}
private static File getSmaliFile(String clsName) {
File smaliFile = new File(SMALI_TESTS_DIR, clsName + SMALI_TESTS_EXT);
if (smaliFile.exists()) {
......@@ -32,18 +37,17 @@ public abstract class SmaliTest extends IntegrationTest {
if (smaliFile.exists()) {
return smaliFile;
}
fail("Smali file not found: " + SMALI_TESTS_DIR + "/" + clsName + SMALI_TESTS_EXT);
return null;
throw new AssertionError("Smali file not found: " + SMALI_TESTS_DIR + "/" + clsName + SMALI_TESTS_EXT);
}
private static boolean compileSmali(File input, File output) {
List<String> args = new ArrayList<>();
args.add(input.getAbsolutePath());
args.add("-o");
args.add(output.getAbsolutePath());
main.main(args.toArray(new String[args.size()]));
try {
SmaliOptions params = new SmaliOptions();
params.outputDexFile = output.getAbsolutePath();
Smali.assemble(params, input.getAbsolutePath());
} catch (Exception e) {
throw new AssertionError("Smali assemble error", e);
}
return true;
}
}
......@@ -22,7 +22,7 @@ import static javax.tools.JavaCompiler.CompilationTask;
public class StaticCompiler {
private static final List<String> COMMON_ARGS = Arrays.asList("-source 1.7 -target 1.7".split(" "));
private static final List<String> COMMON_ARGS = Arrays.asList("-source 1.8 -target 1.8".split(" "));
public static List<File> compile(List<File> files, File outDir, boolean includeDebugInfo) throws IOException {
......
package jadx.tests.smali;
package jadx.tests.integration.arith;
import org.junit.Test;
......@@ -13,7 +13,7 @@ public class TestArithConst extends SmaliTest {
@Test
public void test() {
noDebugInfo();
ClassNode cls = getClassNodeFromSmali("TestArithConst");
ClassNode cls = getClassNodeFromSmaliWithPath("arith", "TestArithConst");
String code = cls.getCode().toString();
assertThat(code, containsOne("return i + CONST_INT;"));
......
package jadx.tests.integration.arith;
import org.junit.Test;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.SmaliTest;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
public class TestArithNot extends SmaliTest {
/*
Smali Code equivalent:
public static class TestCls {
public int test1(int a) {
return ~a;
}
public long test2(long b) {
return ~b;
}
}
*/
@Test
public void test() {
ClassNode cls = getClassNodeFromSmaliWithPath("arith", "TestArithNot");
String code = cls.getCode().toString();
assertThat(code, containsString("return ~a;"));
assertThat(code, containsString("return ~b;"));
assertThat(code, not(containsString("^")));
}
}
.class public LTestArithNot;
.super Ljava/lang/Object;
.method private test1(I)I
.registers 2
.param p1, "a"
not-int v0, p1
return v0
.end method
.method private test2(J)J
.registers 4
.param p1, "b"
not-long v0, p1
return v0
.end method
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册