JNI proguard混淆

cec*_*n89 6 obfuscation java-native-interface android native

我有混淆的问题.为了更好的想象力:

JAVA CODE

class JniTest...

public void test()
{
    //some code
}

public void runJniCode()
{
    //here I call native code
}
Run Code Online (Sandbox Code Playgroud)

本地代码

JNIEXPORT void JNICALL
Java_path_to_class_test(JNIEnv* env, jobject  obj)
{
    //here I call test method from Java

}
Run Code Online (Sandbox Code Playgroud)

一切正常,直到我想发布一个混淆版本.此类中的Java类(JniTest例如)和方法test的名称由proguard重命名为"a"和"a()"(这可能并不总是相同),但在本机代码中,方法和类的原始名称保持,因为它被硬编码为字符串,如:

jmethodID mid = env->GetMethodID(cls, "test", "someSignature");
Run Code Online (Sandbox Code Playgroud)

...有没有办法动态设置方法名称?

And*_*wJC 6

在研究这个完全相同的问题时,我遇到了一个我认为合理的解决方案.不幸的是,该解决方案不会按要求自动模糊本机Java代码和JNI方法,但我仍然认为值得分享.

从来源引用:

我在这里介绍一个简单的技巧,它允许混淆JNI层,在Java和本机端将方法名称重命名为无意义的名称,同时保持源代码相对可读和可维护,并且不影响性能.

让我们考虑一个例子,初始情况:

class Native {
    native static int rotateRGBA(int rgb, int w, int h);
}

extern "C" int Java_pakage_Native_rotateRGBA(JNIEnv *env, jclass, int rgb, int w, int h);
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,Proguard无法模糊方法名称rotateRGBA,它在Java端和本机端仍然可见.

解决方案是在源代码中直接使用无意义的方法名称,同时注意尽可能地降低代码的可读性和可维护性.

class Native {
    private native static int a(int rgb, int w, int h); //rotateRGBA

    static int rotateRGBA(int rgb, int w, int h) {
        return a(rgb, w, h);
    }
}

// rotateRGBA
extern "C" int Java_pakage_Native_a(JNIEnv *env, jclass, int rgb, int w, int h);
Run Code Online (Sandbox Code Playgroud)

JNI方法被重命名为无意义的a.但Java方面的调用由有意义的方法rotateRGBA包装.Java客户端继续像以前一样调用Native.rotateRGBA(),而不会受到重命名的影响.

有趣的是,新的Native.rotateRGBA方法不再是原生的,因此可以由Proguard随意重命名.结果是,名称rotateRGBA完全从混淆代码中消失,在Dalvik和本机端.更重要的是,Proguard优化了包装器方法,从而消除了包装本机调用的(可忽略的)性能影响.

结论:从混淆代码(Dalvik字节码和本机库)中消除了JNI方法名称,对可读性的影响最小,没有性能影响.

来源:混淆JNI表面层

我仍然在寻找一种可以自动混淆原生Java代码和相关JNI的工具.

  • 请在您的答案中引用链接页面,以防目标页面发生变化 (2认同)

nul*_*dev 6

基于 AndrewJC 的答案,如果您的应用程序使用 Kotlin,您还可以使用@JvmName注释而不是使用包装方法,例如:

object Native {
    @JvmName("a")
    private external fun rotateRGBA(rgb: Int, w: Int, h: Int): Int
}

// rotateRGBA
extern "C" int Java_mypackage_Native_a(JNIEnv *env, jclass, int rgb, int w, int h);
Run Code Online (Sandbox Code Playgroud)

现在您可以在 Kotlin 中调用 JNI 方法,Native.rotateRGBA(0, 200, 400)但是编译时,Kotlin 会自动将您的方法调用重命名为:Native.a