如何在 Java 中调用 Smali

How to call Smali in Java

我想用Java to smali plugin,但是我必须先把Java编译成class,像这样的项目是不可能的

h.m

Javac这个看不懂,只是想把这段java代码编译成class,这样就可以转成smali了。

这个项目是由apktool d my.apk解码的,我尝试在其中注入一些代码,写smali比java.But难我已经完成了注入部分,只是想知道如何编译java 到 class.

$ adb logcat -s "Injected"
--------- beginning of main
--------- beginning of system
07-10 19:32:24.013  7689  7689 W Injected: Started
07-10 19:32:24.015  7689  7689 W Injected: Init

编辑

原来的标题是In Jetbrain can I just compile Java to class and ignore all error?,但我想要的是How to call Smali in Java,所以我重命名了标题。

没有

Java 需要 在 java 程序中使用的 classes/methods/fields 的定义才能编译它。如果没有此信息,它就没有足够的信息来生成 class 文件。

例如,假设您要编译这个程序:

public class Main {
    public static int main(String[] args) {
        Blort blort = new Blort();
        blort.blarg("blurg!");
        return 0;
    }
}

生成的确切字节码取决于 Blort.blarg 方法的定义。

如果 blarg 是这样定义的:

public class Blort {
    public void blarg(String blah) {
        System.out.println(blah);
    }
}

那么对 blarg 的方法调用将符合:

invoke-virtual {v0, v1}, LBlort;->blarg(Ljava/lang/String;)V

但是,如果 blarg 方法定义不同:

public class Blort {
    public void blarg(CharSequence blah) {
        System.out.println(blah);
    }
}

然后方法调用将被编译为:

invoke-virtual {v0, v1}, LBlort;->blarg(Ljava/lang/CharSequence;)V

这两个方法调用指的是不同的方法,不可互换。如果编译器至少不知道 blarg 方法的声明,那么它就无法知道要使用的正确方法签名。

这只是为什么编译器需要知道在 java 程序中引用的所有 classes 的定义的一个小例子。还有很多其他原因。

Java 无法做到这一点,但这里有一个非常有效的解决方法。

  1. 找到classes.dex
  2. 使用dex2jar将其转换为jar
  3. 将 jar 添加到项目
  4. 现在可以直接在代码中调用smali代码了

    unzip my.apk -d apk
    d2j-dex2jar my/classes.dex
    # Add classes-dex2jar.jar to project