我有以下界面,映射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
时的函数。
答案 0 :(得分: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