在使用 ProGuard 对 JNA 结构进行混淆时,在 getFieldOrder() 中出现异常。

huangapple go评论107阅读模式
英文:

Exception in getFieldOrder() when obfuscating JNA Structure using progaurd

问题

我的未混淆代码是正常工作的。

但是当通过 Proguard 混淆后——只进行了一次优化——我得到了以下错误:

Exception in thread "main" java.lang.Error: Structure.getFieldOrder() 在类 com.sun.jna.platform.mac.SystemB$Timeval 上未提供足够的名称 [0] ([]) 以匹配已声明的字段 [2] ([tv_sec, tv_usec])
	at com.sun.jna.Structure.getFields(Unknown Source)
	at com.sun.jna.Structure.deriveLayout(Unknown Source)
	at com.sun.jna.Structure.calculateSize(Unknown Source)
	at com.sun.jna.Structure.allocateMemory(Unknown Source)
	at com.sun.jna.Structure.ensureAllocated(Unknown Source)
	at com.sun.jna.Structure.ensureAllocated(Unknown Source)
	at com.sun.jna.Structure.getPointer(Unknown Source)
	at oshi.util.platform.mac.SysctlUtil.sysctl(Unknown Source)
	at oshi.software.os.mac.MacOperatingSystem.<clinit>(Unknown Source)
	at oshi.SystemInfo.createOperatingSystem(Unknown Source)
	at oshi.util.Memoizer$1.get(Unknown Source)
	at oshi.SystemInfo.getOperatingSystem(Unknown Source)

我尝试了多种保留指令,如下所示:

-keep class com.sun.** { *; }

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class com.sun.jna.**{ *; }
-keep class * implements  com.sun.jna.**{ *; }

-keep class oshi.**{ *; }
-keep class * implements  oshi.**{ *; }

-keepclassmembers class * extends com.sun.jna.** {
    <fields>;
    <methods>;
}

-keepclassmembers class * extends oshi.** {
    <fields>;
    <methods>;
}

如何配置 Proguard 以避免此异常呢?

英文:

My un-obfuscated code works..

When run through Proguard obfuscation -- just 1 pass optimization
I am getting the following error:

Exception in thread &quot;main&quot; java.lang.Error: Structure.getFieldOrder() on class com.sun.jna.platform.mac.SystemB$Timeval does not provide enough names [0] ([]) to match declared fields [2] ([tv_sec, tv_usec])
	at com.sun.jna.Structure.getFields(Unknown Source)
	at com.sun.jna.Structure.deriveLayout(Unknown Source)
	at com.sun.jna.Structure.calculateSize(Unknown Source)
	at com.sun.jna.Structure.allocateMemory(Unknown Source)
	at com.sun.jna.Structure.ensureAllocated(Unknown Source)
	at com.sun.jna.Structure.ensureAllocated(Unknown Source)
	at com.sun.jna.Structure.getPointer(Unknown Source)
	at oshi.util.platform.mac.SysctlUtil.sysctl(Unknown Source)
	at oshi.software.os.mac.MacOperatingSystem.&lt;clinit&gt;(Unknown Source)
	at oshi.SystemInfo.createOperatingSystem(Unknown Source)
	at oshi.util.Memoizer$1.get(Unknown Source)
	at oshi.SystemInfo.getOperatingSystem(Unknown Source)

I tried several on keep directive as follows:

-keep class com.sun.** { *; }

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class com.sun.jna.**{ *; }
-keep class * implements  com.sun.jna.**{ *; }

-keep class oshi.**{ *; }
-keep class * implements  oshi.**{ *; }

-keepclassmembers class * extends com.sun.jna.** {
    &lt;fields&gt;;
   &lt;methods&gt;;
}

-keepclassmembers class * extends oshi.** {
    &lt;fields&gt;;
   &lt;methods&gt;;
}

How can I configure Proguard to avoid this exception?

答案1

得分: 1

Beginning with JNA 5.x, the Structure class fields are identified with the @FieldOrder annotation. For the Timeval structure causing your problem, it's defined like this:

@Structure.FieldOrder({ "tv_sec", "tv_usec" })
class Timeval extends Structure {
    public NativeLong tv_sec; // seconds
    public int tv_usec; // microseconds
}

The stack trace indicates it's finding the public fields (correctly) but not finding the field order declared by the annotation.

This question indicates that Proguard will obfuscate annotations, which is likely the source of the problem.

JNA's FAQ suggests the following syntax. It's possible the more broad wildcard definition is necessary rather than explicitly defining <fields> and <methods>.

-dontwarn java.awt.*
-keep class com.sun.jna.* { *; }
-keepclassmembers class * extends com.sun.jna.* { public *; }

Since the annotation is defined in JNA's Structure class as an @interface, the solution suggested by answers to this question indicate the following should fix the problem:

# Annotated interfaces (including methods which are also kept in implementing classes)
-keep @com.sun.jna.Structure.FieldOrder interface * {
    *;
}

Other solutions that may work, more broadly:

  • -keepattributes Annotation
  • -keepattributes *Annotation*
英文:

Beginning with JNA 5.x, the Structure class fields are identified with the @FieldOrder annotation. For the Timeval structure causing your problem, it's defined like this:

@Structure.FieldOrder({ &quot;tv_sec&quot;, &quot;tv_usec&quot; })
class Timeval extends Structure {
    public NativeLong tv_sec; // seconds
    public int tv_usec; // microseconds
}

The stack trace indicates it's finding the public fields (correctly) but not finding the field order declared by the annotation.

This question indicates that Proguard will obfuscate annotations, which is likely the source of the problem.

JNA's FAQ suggests the following syntax. It's possible the more broad wildcard definition is necessary rather than explicitly defining &lt;fields&gt; and &lt;methods&gt;.

-dontwarn java.awt.*
-keep class com.sun.jna.* { *; }
-keepclassmembers class * extends com.sun.jna.* { public *; }

Since the annotation is defined in JNA's Structure class as an @interface, the solution suggested by answers to this question indicate the following should fix the problem:

# Annotated interfaces (including methods which are also kept in implementing classes)
-keep @com.sun.jna.Structure.FieldOrder interface * {
    *;
}

Other solutions that may work, more broadly:

  • -keepattributes Annotation
  • -keepattributes *Annotation*

huangapple
  • 本文由 发表于 2020年10月5日 20:22:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/64208543.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定