如何在 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 无法做到这一点,但这里有一个非常有效的解决方法。
- 找到
classes.dex
- 使用dex2jar将其转换为jar
- 将 jar 添加到项目
现在可以直接在代码中调用smali代码了
unzip my.apk -d apk
d2j-dex2jar my/classes.dex
# Add classes-dex2jar.jar to project
我想用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 无法做到这一点,但这里有一个非常有效的解决方法。
- 找到
classes.dex
- 使用dex2jar将其转换为jar
- 将 jar 添加到项目
现在可以直接在代码中调用smali代码了
unzip my.apk -d apk d2j-dex2jar my/classes.dex # Add classes-dex2jar.jar to project