简体   繁体   English

如何用Java调用Smali

[英]How to call Smali in Java

I want to use Java to smali plugin , but I have to compile Java to class first, this is impossible for project like this 我想使用Java来smali插件 ,但是我必须先编译Java才能进行类化,这对于像这样的项目是不可能的

在此处输入图片说明

The hm is hm

在此处输入图片说明

Javac don't understand this, but I just want to compile this java code to class, so I can convert it to smali. Javac不理解这一点,但是我只想将此Java代码编译为类,因此可以将其转换为smali。

This project is decode by apktool d my.apk , I try to inject some code in it, writing smali is harder than java.But I alread done the Inject part,just want to know how to compile java to class. 这个项目是由apktool d my.apk解码的,我试图在其中注入一些代码,写smali比java难。但是我已经完成了Inject部分,只是想知道如何将Java编译为类。

$ 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

EDIT 编辑

The original title is In Jetbrain can I just compile Java to class and ignore all error? 原始标题是In Jetbrain can I just compile Java to class and ignore all error? ,but want I want is How to call Smali in Java , so I rename the title. ,但是我想要的是How to call Smali in Java ,所以我重命名了标题。

No. 没有。

Java requires the definitions of the classes/methods/fields being used in a java program to be able to compile it. Java 要求 Java程序中使用的类/方法/字段的定义能够对其进行编译。 Without this information, it doesn't have enough information to be able to produce a class file. 没有这些信息,它就没有足够的信息来生成类文件。

For example, let's say you're trying to compile this program: 例如,假设您正在尝试编译此程序:

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

The exact bytecode that is produced depends on the definition of the Blort.blarg method. 产生的确切字节码取决于Blort.blarg方法的定义。

If blarg is defined like this: 如果blarg是这样定义的:

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

Then the method call to blarg would be complied to: 然后,对blarg的方法调用将被遵循:

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

However, if the blarg method is defined differently: 但是,如果blarg方法的定义不同:

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

Then the method call would be compiled to: 然后将方法调用编译为:

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

These two method calls refer to different methods and are not interchangable. 这两个方法调用引用不同的方法,并且不能互换。 And if the compiler doesn't know at least the declaration of the blarg method, then it can't know the correct method signature to use. 而且,如果编译器至少不知道blarg方法的声明,那么它也将不知道要使用的正确方法签名。

And that's just 1 small example of why the compiler needs to know the definitions of all classes that are being referred to in a java program. 这只是编译器需要知道Java程序中引用的所有类的定义的一个小例子。 There are many other reasons. 还有许多其他原因。

Java can not do that, but here is a workaround that will work perfectly well. Java无法做到这一点,但是这里有一个解决方法,可以很好地工作。

  1. Find the classes.dex 找到classes.dex
  2. Use dex2jar convert it to jar 使用dex2jar将其转换为jar
  3. Add jar to project 将jar添加到项目
  4. Now you can call smali code directly in your code. 现在,您可以直接在代码中调用smali代码。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM