You need to enable JavaScript to run this app. PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON的十六进制值及C#中IntPtr转换实现
优惠活动
大模型
产品
解决方案
定价
更多

PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON的十六进制值及C#中IntPtr转换实现

核心实现逻辑

首先理清两个容易卡壳的关键认知,避免走弯路:

  • 官方给出的常量定义根本不需要到处搜十六进制值,直接复用文档里的移位逻辑在C#里定义,就能得到完全等价的结果
  • PInvoke.net上写的IntPtr类型参数本身没问题,但这个类型是用来表示通用内存指针的,不是直接用来存要设置的策略值本身,搞反了指针和值的关系是90%的人调用失败的原因

第一步:定义和官方完全匹配的常量

直接照搬文档的移位逻辑写常量,从根源上避免手动换算十六进制算错的问题:

// 对应PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON
public const ulong BlockNonMicrosoftBinariesAlwaysOnPolicy = 1UL << 44;
// 对应UpdateProcThreadAttribute的缓解策略属性标识
public const IntPtr ProcThreadAttributeMitigationPolicy = (IntPtr)0x00020007;

如果需要准确的十六进制参考,1UL << 44 换算后的实际值为 0x0010000000000000,和官方定义完全一致。

第二步:匹配API的参数要求

当你要设置进程缓解策略时,API对这个属性的固定要求是:

  • lpValue 传入的是指向8字节ULONG64类型策略值的指针,不是把值强转成IntPtr直接传
  • cbSize 参数固定填8字节,和当前进程的位宽没有关系

第三步:可直接复用的调用代码

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UpdateProcThreadAttribute(
    IntPtr lpAttributeList,
    uint dwFlags,
    IntPtr Attribute,
    IntPtr lpValue,
    nuint cbSize,
    IntPtr lpPreviousValue,
    IntPtr lpReturnSize
);

// 已通过InitializeProcThreadAttributeList拿到合法属性列表句柄后,调用该方法设置策略
void ConfigureMitigationPolicy(IntPtr attributeListHandle)
{
    // 分配能容纳8字节策略值的非托管内存
    IntPtr pPolicyBuffer = Marshal.AllocHGlobal(sizeof(ulong));
    try
    {
        // 把要设置的策略值写入分配的内存
        Marshal.WriteInt64(pPolicyBuffer, (long)BlockNonMicrosoftBinariesAlwaysOnPolicy);
        
        bool isSuccess = UpdateProcThreadAttribute(
            lpAttributeList: attributeListHandle,
            dwFlags: 0,
            Attribute: ProcThreadAttributeMitigationPolicy,
            lpValue: pPolicyBuffer,
            cbSize: (nuint)sizeof(ulong), // 固定传8字节,不要偷懒用IntPtr.Size
            lpPreviousValue: IntPtr.Zero,
            lpReturnSize: IntPtr.Zero
        );

        if (!isSuccess)
        {
            throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
        }
    }
    finally
    {
        // 用完必须释放内存,避免泄漏
        Marshal.FreeHGlobal(pPolicyBuffer);
    }
}

高频踩坑提醒

  • 千万别直接把策略值强转成IntPtr当lpValue传:这种写法相当于把策略值当成内存地址传给API,要么直接触发内存访问违规崩溃,要么读到随机内存值,完全达不到设置策略的效果
  • 别把cbSize设成IntPtr.Size:32位进程下IntPtr大小是4字节,和API要求的8字节固定长度不匹配,会直接返回参数错误
  • 该缓解策略从Windows 10 1709版本才开始支持,在更早的系统上调会直接返回不支持的错误
  • 除了用Marshal.AllocHGlobal分配内存,也可以用GCHandle钉住托管的字节数组传指针,只要保证传入的内存长度、值正确就行

内容的提问来源于stack exchange,提问作者Anonymous-User

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 04:45:04