是否可以注释导出的函数名称?

问题描述 投票:3回答:1

我有以下接口,映射DLL的导出函数:

interface Foo extends Library {
    int ProcessBytes(byte[] bytes, int size);
}

我正在使用Proguard来混淆我的应用程序。而且,目前我正在使用-keep配置来维护上面的接口代码。所以,JNA可以找到该函数并调用它。

我也想混淆界面。如果我删除-keep配置,我的界面将如下所示:

interface a extends Library {
    int a(byte[] a, int b);
}

并且JNA无法处理它,因为导出的函数中不存在a函数。所以,我的问题是:是否可以注释导出的函数名称?像这样的东西:

interface Foo extends Library {  
   @Function("ProcessBytes")
   int anyname(byte[] bytes, int size);
}

就像“我不关心你的方法的名字,我会在调用方法ProcessBytes时调用”anyname“函数。

java jna
1个回答
1
投票

您可以创建自定义注释并使用FunctionMapper来解析函数名称。使用loadLibrary加载库时,可以将此类传递给JNA。

@Target(value = ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
@interface NativeFunctionName {
    String name() default "";
}

class FunctionNameAnnotationMapper implements FunctionMapper {
    @Override
    public String getFunctionName(NativeLibrary nativeLibrary, Method method) {
        NativeFunctionName annotation = method.getAnnotation(NativeFunctionName.class);
        // just return the function's name if the annotation is not applied
        return annotation == null ? method.getName() : annotation.name();
    }
}

用法如下:

public class Program {
    public static void main(String... args) {
        Map<String, Object> opts = new HashMap<>();
        opts.put(Library.OPTION_FUNCTION_MAPPER, new FunctionNameAnnotationMapper());

        Obfuscated lib = Native.loadLibrary("my-library", Obfuscated.class, opts);
        lib.obfuscated1(0, null);
    }
}

interface Obfuscated extends Library {
    @NativeFunctionName(name = "main")
    public int obfuscated1(int argc, Pointer argv);
}

请注意,JVM将需要在运行时访问这些注释值,因此它们将包含在输出中。确保您的混淆器保留这些注释。

如果您已经在使用函数映射器,请考虑创建一个“聚合”函数映射器类,它允许您传递多个映射器。

更多关于函数映射的信息:http://java-native-access.github.io/jna/4.5.0/javadoc/overview-summary.html#function-mapping

© www.soinside.com 2019 - 2024. All rights reserved.