如何使用 JNA 调用 setProcessMitigationPolicy

How to call setProcessMitigationPolicy using JNA

我正在尝试通过 JNA 将这段 C++ 代码转换为 Java 代码:

PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY signaturePolicy = {};
signaturePolicy.MicrosoftSignedOnly = true;
SetProcessMitigationPolicy(ProcessSignaturePolicy, &signaturePolicy, sizeof(signaturePolicy));

我已经有 Kernel32.dll 的函数 SetProcessMitigationPolicy 并且我可以调用它,但是如何传递这些参数?

你能举个例子吗?

更新:

我试过下面的代码,但还是不行。函数声明是否正确?显然,函数 returns 为真,我没有收到任何错误。

// Main

private static final Kernel32 kernel32 = Kernel32.INSTANCE;

public static void main(String[] args) {
    PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY signaturePolicy = new PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY();
    signaturePolicy.MicrosoftSignedOnly = 1;

    signaturePolicy.write();

    BaseTSD.SIZE_T dwLength = new BaseTSD.SIZE_T(signaturePolicy.size());

    boolean success = kernel32.SetProcessMitigationPolicy(8, signaturePolicy.getPointer(), dwLength);

    System.out.println("Result: " + success);

    while (true);
}
// PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY

@Structure.FieldOrder({"MicrosoftSignedOnly"})
public final class PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY extends Structure {

    public int MicrosoftSignedOnly;

}

SetProcessMitigationPolicy 函数有三个参数。

BOOL SetProcessMitigationPolicy(
  PROCESS_MITIGATION_POLICY MitigationPolicy,
  PVOID                     lpBuffer,
  SIZE_T                    dwLength
);

第一个参数是 PROCESS_MITIGATION_POLICY 枚举。这是一个简单的整数(从 0 开始),指示要使用的策略。您的示例代码显示了枚举的 ProcessSignaturePolicy 成员。这只是整数 8.

int MitigationPolicy = 8;

您的示例代码显示您正在使用 PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY 结构作为第二个参数。这实际上被映射为一个 32 位联合,带有一个 DWORD(可以映射为一个 int)和一个位域总计 32 位的结构。 JNA 没有映射位字段的方法,因此您需要直接设置这些位。所以我会简化映射并将此结构映射为仅 Flags 字段:

@FieldOrder ({"Flags"})
class PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY extends Structure {
  public int Flags;
}

MS 文档指定位字段 start at the least significant bit。所以 signaturePolicy.MicrosoftSignedOnly = true; 相当于将最低有效位设置为 1.

PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY signaturePolicy 
    = new PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY();
signaturePolicy.Flags = 1;
// alternately, since Flags is initialized to 0, the direct
// counterpart to setting MicrosoftSignedOnly = true is:
// signaturePolicy.Flags |= 0x1;

第二个函数参数是一个指针(PVOID),你的例子显示的是结构的地址。因此,您应该为该参数传递 signaturePolicy.getPointer()

通常在将 Structure 传递给函数时,它会自动将 Java 值写入本机内存。我们只会将指针传递给结构,因此我们需要在传递之前手动 write() 将值传递给本机内存。

signaturePolicy.write();
// now pass signaturePolicy.getPointer()

第三个参数是结构的SIZE_T大小。

SIZE_T dwLength = new SIZE_T(signaturePolicy.size());

更新答案以解决问题中的更新。

根据答案映射是正确的;您为结构映射选择的变量名称可能会产生误导,因为您使用的是整个 32 位 Flags 值的位域名称。