Skip to content
Advertisement

How to call setProcessMitigationPolicy using JNA

I’m trying to convert this piece of C++ code into Java code via JNA:

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

I already have the function SetProcessMitigationPolicy from Kernel32.dll and I’m able to call it, but how to pass such parameters?

Can you please provide an example of it?

UPDATE:

I have tried the following code, but it is still not working. Is the function declaration correct? Apparently, the function returns true and I’m not getting any error.

// 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;

}

Advertisement

Answer

The SetProcessMitigationPolicy function has three arguments.

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

The first argument is a PROCESS_MITIGATION_POLICY enumeration. This is a simple integer (starting at 0) indicating which policy to use. Your sample code shows the ProcessSignaturePolicy member of the enumeration. This is just the integer 8.

int MitigationPolicy = 8;

Your example code shows you’re using the PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY structure as the second argument. This is actually mapped as a 32-bit union with either a DWORD (can be mapped as an int) and a structure with bit fields totalling 32 bits. JNA does not have a means to map bit fields so you need to directly set those bits. So I’d simplify the mapping and just map this structure as only the Flags field:

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

MS Docs specify bit fields start at the least significant bit. So the equivalent of signaturePolicy.MicrosoftSignedOnly = true; is to set the least significant bit to 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;

The second function parameter is a pointer (PVOID) which your example shows is the address of the structure. So you should pass signaturePolicy.getPointer() for that parameter.

Normally when passing a Structure to a function it autowrites the Java value to the native memory. We’ll only be passing the pointer to the structure so we need to manually write() the value to the native memory before passing it.

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

The third parameter is a SIZE_T size of the structure.

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

Updating the answer to address the update in the question.

The mapping is correct per the answer; your variable name choice for the structure mapping could be misleading since you’re using the name of a bit field for the entire 32-bit Flags value.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement