当前位置: 首页 > news >正文

【Windows】获取进程缓解策略设置情况

目录

一、前言

二、主要概念

三、实现步骤

四、总结


原文出处链接:[https://blog.csdn.net/qq_59075481/article/details/142234952]

一、前言

在现代操作系统中,进程缓解策略(Process Mitigation Policy)提供了一种防御机制,可以防止潜在的攻击对系统中的进程进行利用。通过分析进程的缓解策略设置,开发人员和系统管理员可以更好地了解当前进程的安全状态以及应用了哪些安全措施。

本文介绍一种通过编程方式获取进程的缓解策略设置的方法。我们将利用 Windows 提供的 GetProcessMitigationPolicy 函数来获取不同类型的缓解策略,并使用 C 示例来演示如何实现这一功能。

警告:我们将在下一篇讲解如何远程修改部分安全缓解策略以及缓解策略的绕过技术。

二、主要概念

在 Windows 操作系统中,每个进程都可以设置多种缓解策略,这些策略可以增强系统安全性。常见的缓解策略包括:

进程缓解策略是操作系统用来防止恶意软件或攻击者利用进程漏洞的安全机制。以下是一些常见的缓解策略:

  1. 数据执行防护 (DEP, Data Execution Prevention):DEP 是一种安全功能,旨在防止恶意代码执行非代码区域的内容(如堆栈或堆)。启用 DEP 后,如果在数据区中检测到代码执行,将导致进程异常终止。
  2. 地址空间布局随机化 (ASLR, Address Space Layout Randomization):ASLR 通过随机化程序的内存地址来增加攻击者预测这些地址的难度。通过随机化可执行文件、DLLs、堆、栈和其他内存区域的位置,ASLR 可以有效防止缓冲区溢出和其他内存攻击。
  3. 动态代码执行限制 (Dynamic Code Policy):该策略限制进程生成动态代码或修改现有的可执行代码,防止恶意代码注入和代码覆盖攻击。
  4. 控制流保护 (CFG, Control Flow Guard):CFG 是一种防御机制,用于防止间接调用的目标被篡改,从而保护程序免受控制流劫持攻击。CFG 可通过在运行时检查目标地址是否安全来防止攻击。
  5. 结构化异常处理覆盖保护 (SEHOP, Structured Exception Handling Overwrite Protection):SEHOP 保护 Windows 应用程序免受结构化异常处理(SEH)覆盖攻击,这是堆栈缓冲区溢出攻击的一种形式。
  6. 系统调用禁用 (System Call Disable Policy):该策略可以禁止进程进行特定的系统调用,以限制进程与操作系统内核的交互,降低进程被利用的风险。
  7. 子进程创建策略 (Child Process Policy):限制进程创建子进程的能力,防止恶意软件通过子进程传播或执行进一步的攻击。
  8. 映像加载策略 (Image Load Policy):该策略控制哪些类型的可执行文件可以映射到进程地址空间,防止从不受信任的来源加载恶意代码。

进程缓解策略有哪些?(进程缓解策略从 Win 8 开始引入,下面的版本是目前 Win10/11 上的枚举)。

typedef enum _PROCESS_MITIGATION_POLICY {ProcessDEPPolicy,ProcessASLRPolicy,ProcessDynamicCodePolicy,ProcessStrictHandleCheckPolicy,ProcessSystemCallDisablePolicy,ProcessMitigationOptionsMask,ProcessExtensionPointDisablePolicy,ProcessControlFlowGuardPolicy,ProcessSignaturePolicy,ProcessFontDisablePolicy,ProcessImageLoadPolicy,ProcessSystemCallFilterPolicy,ProcessPayloadRestrictionPolicy,ProcessChildProcessPolicy,ProcessSideChannelIsolationPolicy,ProcessUserShadowStackPolicy,ProcessRedirectionTrustPolicy,ProcessUserPointerAuthPolicy,ProcessSEHOPPolicy,ProcessActivationContextTrustPolicy,MaxProcessMitigationPolicy
} PROCESS_MITIGATION_POLICY, *PPROCESS_MITIGATION_POLICY;

三、实现步骤

以下步骤描述了如何获取和显示进程的缓解策略:

  1. 获取目标进程的句柄: 使用 OpenProcess 函数以 PROCESS_QUERY_LIMITED_INFORMATION 权限打开目标进程。
  2. 启用SE_DEBUG_NAME特权: 调用 EnableDebugPrivilege 函数启用调试特权,使得当前进程能够访问所有进程的信息。
  3. 获取进程的路径和描述信息: 使用 QueryFullProcessImageNameW 函数获取进程的完整路径,并调用 GetProcessDescription 函数获取PE文件的描述信息。
  4. 获取并显示缓解策略: 使用 GetProcessMitigationPolicy 函数依次获取不同类型的缓解策略(如 DEP、ASLR、CFG 等),并打印每个策略的二进制表示和详细分析。

代码示例

获取进程缓解策略的前提:当前线程对目标进程至少能打开有限信息查询访问句柄。

查询进程缓解策略的需求:至少以 PROCESS_QUERY_LIMITED_INFORMATION 访问权限打开进程。部分进程的访问可能需要至少需要管理员身份。

描述:目前 win11 上面有 20 组缓解策略,每个策略占一个 32 位二进制位(DWORD),但结构中有很多保留位暂未使用。

以下是核心代码实现,它展示了如何获取和打印进程的缓解策略:

#include <tchar.h>
#include <stdio.h>
#include <Windows.h>
#include <Processthreadsapi.h>
#include <winver.h>#pragma comment(lib, "Version.lib")// 打印 DWORD 类型的 Flags 的二进制表示,每一位之间用 | 分隔
static void PrintBinaryFlags(DWORD flags)
{printf(" Policy Flags: \n");// 打印位偏移(从 0 到 31)for (int i = 31; i >= 0; i--){printf("%2d", i);if (i != 0) {printf(" | ");}}printf("\n");// 打印 Flags 的二进制表示for (int i = 31; i >= 0; i--){printf(" %d", (flags >> i) & 1);  // 右移并与 1 进行按位与操作,提取该位if (i != 0) {printf(" | ");}}printf("\n");
}static void show_mitigations(HANDLE hProc) {PROCESS_MITIGATION_DEP_POLICY dep = { 0 };PROCESS_MITIGATION_ASLR_POLICY aslr = { 0 };PROCESS_MITIGATION_DYNAMIC_CODE_POLICY dynamic_code = { 0 };PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY strict_handle_check = { 0 };PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY system_call_disable = { 0 };ULONG64 mitigation_options = { 0 };PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY extension_point_disable = { 0 };PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY cfg = { 0 };PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY signature = { 0 };PROCESS_MITIGATION_FONT_DISABLE_POLICY font = { 0 };PROCESS_MITIGATION_IMAGE_LOAD_POLICY image_load = { 0 };PROCESS_MITIGATION_SYSTEM_CALL_FILTER_POLICY syscall_filter = { 0 };  // win11 NewPROCESS_MITIGATION_PAYLOAD_RESTRICTION_POLICY payload_rtict = { 0 };   // win11 NewPROCESS_MITIGATION_CHILD_PROCESS_POLICY child_proc = { 0 };            // win11 NewPROCESS_MITIGATION_SIDE_CHANNEL_ISOLATION_POLICY side_cnl_isan = { 0 };PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY usw_stack = { 0 };PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY trust_redc = { 0 };PROCESS_MITIGATION_USER_POINTER_AUTH_POLICY upt_auth = { 0 };PROCESS_MITIGATION_SEHOP_POLICY seh_op_policy = { 0 };PROCESS_MITIGATION_ACTIVATION_CONTEXT_TRUST_POLICY activ_ctx_truct = { 0 };  // win11 New/*描述:数据执行防护 (DEP) 的进程缓解策略。typedef struct _PROCESS_MITIGATION_DEP_POLICY {union {DWORD Flags;struct {DWORD Enable : 1;DWORD DisableAtlThunkEmulation : 1;DWORD ReservedFlags : 30;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;BOOLEAN Permanent;} PROCESS_MITIGATION_DEP_POLICY, *PPROCESS_MITIGATION_DEP_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessDEPPolicy, &dep, sizeof(dep));printf("ProcessDEPPolicy:\n");PrintBinaryFlags(dep.Flags);printf("\n Analysis:\n");printf("   Enable                                     %u\n", dep.Enable);printf("   DisableAtlThunkEmulation                   %u\n", dep.DisableAtlThunkEmulation);printf("\n");/*描述:地址空间布局随机化 (ASLR) 的进程缓解策略。typedef struct _PROCESS_MITIGATION_ASLR_POLICY {union {DWORD Flags;struct {DWORD EnableBottomUpRandomization : 1;DWORD EnableForceRelocateImages : 1;DWORD EnableHighEntropy : 1;DWORD DisallowStrippedImages : 1;DWORD ReservedFlags : 28;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_ASLR_POLICY, *PPROCESS_MITIGATION_ASLR_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessASLRPolicy, &aslr, sizeof(aslr));printf("ProcessASLRPolicy:\n");PrintBinaryFlags(aslr.Flags);printf("\n Analysis:\n");printf("   EnableBottomUpRandomization                %u\n", aslr.EnableBottomUpRandomization);printf("   EnableForceRelocateImages                  %u\n", aslr.EnableForceRelocateImages);printf("   EnableHighEntropy                          %u\n", aslr.EnableHighEntropy);printf("   DisallowStrippedImages                     %u\n", aslr.DisallowStrippedImages);printf("\n");/*描述:动态代码执行进程缓解策略。启用后,进程无法生成动态代码或修改现有的可执行代码。typedef struct _PROCESS_MITIGATION_DYNAMIC_CODE_POLICY {union {DWORD Flags;struct {DWORD ProhibitDynamicCode : 1;DWORD AllowThreadOptOut : 1;DWORD AllowRemoteDowngrade : 1;DWORD AuditProhibitDynamicCode : 1;DWORD ReservedFlags : 28;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_DYNAMIC_CODE_POLICY, *PPROCESS_MITIGATION_DYNAMIC_CODE_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessDynamicCodePolicy, &dynamic_code, sizeof(dynamic_code));printf("ProcessStrictHandleCheckPolicy:\n");PrintBinaryFlags(dynamic_code.Flags);printf("\n Analysis:\n");printf("   ProhibitDynamicCode                        %u\n", dynamic_code.ProhibitDynamicCode);printf("   AllowThreadOptOut                          %u\n", dynamic_code.AllowThreadOptOut);printf("   AllowRemoteDowngrade                       %u\n", dynamic_code.AllowRemoteDowngrade);printf("   AuditProhibitDynamicCode                   %u\n", dynamic_code.AuditProhibitDynamicCode);printf("\n");/*描述:如果进程操作无效的句柄,则会收到严重错误。typedef struct _PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY {union {DWORD Flags;struct {DWORD RaiseExceptionOnInvalidHandleReference : 1;DWORD HandleExceptionsPermanentlyEnabled : 1;DWORD ReservedFlags : 30;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY, *PPROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessStrictHandleCheckPolicy, &strict_handle_check, sizeof(strict_handle_check));printf("ProcessStrictHandleCheckPolicy:\n");PrintBinaryFlags(strict_handle_check.Flags);printf("\n Analysis:\n");printf("   RaiseExceptionOnInvalidHandleReference     %u\n", strict_handle_check.RaiseExceptionOnInvalidHandleReference);printf("   HandleExceptionsPermanentlyEnabled         %u\n", strict_handle_check.HandleExceptionsPermanentlyEnabled);printf("\n");/*描述:禁用在最底层使用 NTUser/GDI 函数的功能。typedef struct _PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY {union {DWORD Flags;struct {DWORD DisallowWin32kSystemCalls : 1;DWORD AuditDisallowWin32kSystemCalls : 1;DWORD ReservedFlags : 30;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY, *PPROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessSystemCallDisablePolicy, &system_call_disable, sizeof(system_call_disable));printf("ProcessSystemCallDisablePolicy:\n");PrintBinaryFlags(system_call_disable.Flags);printf("\n Analysis:\n");printf("   DisallowWin32kSystemCalls                  %u\n", system_call_disable.DisallowWin32kSystemCalls);printf("   AuditDisallowWin32kSystemCalls             %u\n", system_call_disable.AuditDisallowWin32kSystemCalls);printf("\n");/** 描述:返回系统上所有缓解选项的有效位掩码(3333333333333303,看样子第四位是没用到还是啥意思?)。*       掩码:*		      1011110101111010011000100101010000000101010100110111* *       应用程序可以设置许多缓解选项,而无需查询操作系统的缓解选项,*       方法是将按位与掩码组合在一起,一次排除所有不支持的位。*        lpBuffer 参数指向掩码的 ULONG64 位向量,或 ULONG64 位向量的双元素数组。*/GetProcessMitigationPolicy(hProc, ProcessMitigationOptionsMask, &mitigation_options, sizeof(mitigation_options));printf("ProcessMitigationOptionsMask:\n");printf("   MitigationOptions                          %llx\n", mitigation_options);printf("\n");/*描述:阻止启用某些内置第三方扩展点,从而阻止将旧扩展点 DLL 加载到进程中。typedef struct _PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY {union {DWORD Flags;struct {DWORD DisableExtensionPoints : 1;DWORD ReservedFlags : 31;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY, *PPROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessExtensionPointDisablePolicy, &extension_point_disable, sizeof(extension_point_disable));printf("ProcessExtensionPointDisablePolicy:\n");PrintBinaryFlags(extension_point_disable.Flags);printf("\n Analysis:\n");printf("   DisableExtensionPoints                     %u\n", extension_point_disable.DisableExtensionPoints);printf("\n");/*描述:控制流防护 (CFG) 的进程缓解策略。typedef struct _PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY {union {DWORD Flags;struct {DWORD EnableControlFlowGuard : 1;DWORD EnableExportSuppression : 1;DWORD StrictMode : 1;DWORD EnableXfg : 1;DWORD EnableXfgAuditMode : 1;DWORD ReservedFlags : 27;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY, *PPROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessControlFlowGuardPolicy, &cfg, sizeof(cfg));printf("ProcessControlFlowGuardPolicy:\n");PrintBinaryFlags(cfg.Flags);printf("\n Analysis:\n");printf("   EnableControlFlowGuard                     %u\n", cfg.EnableControlFlowGuard);printf("   EnableExportSuppression                    %u\n", cfg.EnableExportSuppression);printf("   StrictMode                                 %u\n", cfg.StrictMode);printf("   EnableXfg                                  %u\n", cfg.EnableXfg);printf("   EnableXfgAuditMode                         %u\n", cfg.EnableXfgAuditMode);printf("\n");/*描述:可以将映像加载限制为由 Microsoft、Windows 应用商店或Microsoft、Windows 应用商店和 Windows 硬件质量实验室 (WHQL) 签名的映像的进程缓解策略。typedef struct _PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY {union {DWORD Flags;struct {DWORD MicrosoftSignedOnly : 1;DWORD StoreSignedOnly : 1;DWORD MitigationOptIn : 1;DWORD AuditMicrosoftSignedOnly : 1;DWORD AuditStoreSignedOnly : 1;DWORD ReservedFlags : 27;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY, *PPROCESS_MITIGATION_BINARY_SIGNATURE_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessSignaturePolicy, &signature, sizeof(signature));printf("ProcessSignaturePolicy:\n");PrintBinaryFlags(signature.Flags);printf("\n Analysis:\n");printf("   MicrosoftSignedOnly                        %u\n", signature.MicrosoftSignedOnly);printf("   StoreSignedOnly                            %u\n", signature.StoreSignedOnly);printf("   MitigationOptIn                            %u\n", signature.MitigationOptIn);printf("   AuditMicrosoftSignedOnly                   %u\n", signature.AuditMicrosoftSignedOnly);printf("   AuditStoreSignedOnly                       %u\n", signature.AuditStoreSignedOnly);printf("\n");/*描述:有关进程的字体加载的缓解策略。启用后,进程无法加载非系统字体。typedef struct _PROCESS_MITIGATION_FONT_DISABLE_POLICY {union {DWORD Flags;struct {DWORD DisableNonSystemFonts     : 1;DWORD AuditNonSystemFontLoading : 1;DWORD ReservedFlags             : 30;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_FONT_DISABLE_POLICY, *PPROCESS_MITIGATION_FONT_DISABLE_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessFontDisablePolicy, &font, sizeof(font));printf("ProcessFontDisablePolicy:\n");PrintBinaryFlags(font.Flags);printf("\n Analysis:\n");printf("   DisableNonSystemFonts                      %u\n", font.DisableNonSystemFonts);printf("   AuditNonSystemFontLoading                  %u\n", font.AuditNonSystemFontLoading);printf("\n");/*描述:有关进程映像加载的策略,该策略确定允许映射到进程的可执行映像的类型。启用后,无法从某些位置加载映像,例如具有低强制签名的远程设备或文件。typedef struct _PROCESS_MITIGATION_IMAGE_LOAD_POLICY {union {DWORD Flags;struct {DWORD NoRemoteImages : 1;DWORD NoLowMandatoryLabelImages : 1;DWORD PreferSystem32Images : 1;DWORD AuditNoRemoteImages : 1;DWORD AuditNoLowMandatoryLabelImages : 1;DWORD ReservedFlags : 27;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_IMAGE_LOAD_POLICY, *PPROCESS_MITIGATION_IMAGE_LOAD_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessImageLoadPolicy, &image_load, sizeof(image_load));printf("ProcessImageLoadPolicy:\n");PrintBinaryFlags(image_load.Flags);printf("\n Analysis:\n");printf("   NoRemoteImages                             %u\n", image_load.NoRemoteImages);printf("   NoLowMandatoryLabelImages                  %u\n", image_load.NoLowMandatoryLabelImages);printf("   PreferSystem32Images                       %u\n", image_load.PreferSystem32Images);printf("   AuditNoRemoteImages                        %u\n", image_load.AuditNoRemoteImages);printf("   AuditNoLowMandatoryLabelImages             %u\n", image_load.AuditNoLowMandatoryLabelImages);printf("\n");/*描述:关于系统调用的进程筛选器缓解策略。typedef struct _PROCESS_MITIGATION_SYSTEM_CALL_FILTER_POLICY {union {DWORD Flags;struct {DWORD FilterId: 4;DWORD ReservedFlags : 28;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_SYSTEM_CALL_FILTER_POLICY, *PPROCESS_MITIGATION_SYSTEM_CALL_FILTER_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessSystemCallFilterPolicy, &syscall_filter, sizeof(syscall_filter));printf("ProcessSystemCallFilterPolicy:\n");PrintBinaryFlags(syscall_filter.Flags);printf("\n Analysis:\n");printf("   FilterId                                   %u\n", syscall_filter.FilterId);printf("\n");/*描述:进行有效负载限制的进程缓解策略。typedef struct _PROCESS_MITIGATION_PAYLOAD_RESTRICTION_POLICY {union {DWORD Flags;struct {DWORD EnableExportAddressFilter     : 1;DWORD AuditExportAddressFilter      : 1;DWORD EnableExportAddressFilterPlus : 1;DWORD AuditExportAddressFilterPlus  : 1;DWORD EnableImportAddressFilter     : 1;DWORD AuditImportAddressFilter      : 1;DWORD EnableRopStackPivot           : 1;DWORD AuditRopStackPivot            : 1;DWORD EnableRopCallerCheck          : 1;DWORD AuditRopCallerCheck           : 1;DWORD EnableRopSimExec              : 1;DWORD AuditRopSimExec               : 1;DWORD ReservedFlags                 : 20;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_PAYLOAD_RESTRICTION_POLICY, *PPROCESS_MITIGATION_PAYLOAD_RESTRICTION_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessPayloadRestrictionPolicy, &payload_rtict, sizeof(payload_rtict));printf("ProcessPayloadRestrictionPolicy:\n");PrintBinaryFlags(payload_rtict.Flags);printf("\n Analysis:\n");printf("   EnableExportAddressFilter                  %u\n", payload_rtict.EnableExportAddressFilter);printf("   AuditExportAddressFilter                   %u\n", payload_rtict.AuditExportAddressFilter);printf("   EnableExportAddressFilterPlus              %u\n", payload_rtict.EnableExportAddressFilterPlus);printf("   AuditExportAddressFilterPlus               %u\n", payload_rtict.AuditExportAddressFilterPlus);printf("   EnableImportAddressFilter                  %u\n", payload_rtict.EnableImportAddressFilter);printf("   AuditImportAddressFilter                   %u\n", payload_rtict.AuditImportAddressFilter);printf("   EnableRopStackPivot                        %u\n", payload_rtict.EnableRopStackPivot);printf("   AuditRopStackPivot                         %u\n", payload_rtict.AuditRopStackPivot);printf("   EnableRopCallerCheck                       %u\n", payload_rtict.EnableRopCallerCheck);printf("   AuditRopCallerCheck                        %u\n", payload_rtict.AuditRopCallerCheck);printf("   EnableRopSimExec                           %u\n", payload_rtict.EnableRopSimExec);printf("   AuditRopSimExec                            %u\n", payload_rtict.AuditRopSimExec);printf("\n");/*描述:进程的子进程缓解策略。typedef struct _PROCESS_MITIGATION_CHILD_PROCESS_POLICY {union {DWORD Flags;struct {DWORD NoChildProcessCreation : 1;DWORD AuditNoChildProcessCreation : 1;DWORD AllowSecureProcessCreation : 1;DWORD ReservedFlags : 29;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_CHILD_PROCESS_POLICY, *PPROCESS_MITIGATION_CHILD_PROCESS_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessChildProcessPolicy, &child_proc, sizeof(child_proc));printf("ProcessChildProcessPolicy:\n");PrintBinaryFlags(child_proc.Flags);printf("\n Analysis:\n");printf("   NoChildProcessCreation                     %u\n", child_proc.NoChildProcessCreation);printf("   AuditNoChildProcessCreation                %u\n", child_proc.AuditNoChildProcessCreation);printf("   AllowSecureProcessCreation                 %u\n", child_proc.AllowSecureProcessCreation);printf("\n");/*描述:有关指定进程的侧信道隔离的策略。从 Windows 10 版本 1809 及更高版本开始支持。typedef struct _PROCESS_MITIGATION_SIDE_CHANNEL_ISOLATION_POLICY {union {DWORD Flags;struct {//// 在用户模式下防止分支目标污染 交错/同时多线程 (cross-SMT)。//DWORD SmtBranchTargetIsolation : 1;// // 将此进程隔离到一个不同的安全域中,甚至与作为相同安全上下文// 运行的其他进程隔离。这可以防止通过跨进程实施的分支目标注入(// 通常这种分支目标注入仅在不同的安全上下文中被禁止)。//// 页面合并仅限于同一安全域内的进程。因此,此标志也有效地将进程// 限制为只能在进程本身内部组合,但公共页面除外(除非受到//   DisablePageCombine 策略的进一步限制)。// DWORD IsolateSecurityDomain : 1;// // 禁用此进程的所有页面组合,即使是进程本身的内部,但常见页面// (0 或 1)除外。// DWORD DisablePageCombine : 1;//// 禁用内存歧义消除 (Memory Disambiguation)//DWORD SpeculativeStoreBypassDisable : 1;// // 防止将此进程的线程与其安全域外的线程安排在同一核心上。// DWORD RestrictCoreSharing : 1;DWORD ReservedFlags : 27;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_SIDE_CHANNEL_ISOLATION_POLICY, *PPROCESS_MITIGATION_SIDE_CHANNEL_ISOLATION_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessSideChannelIsolationPolicy, &side_cnl_isan, sizeof(side_cnl_isan));printf("ProcessSideChannelIsolationPolicy:\n");PrintBinaryFlags(side_cnl_isan.Flags);printf("\n Analysis:\n");printf("   SmtBranchTargetIsolation                   %u\n", side_cnl_isan.SmtBranchTargetIsolation);printf("   IsolateSecurityDomain                      %u\n", side_cnl_isan.IsolateSecurityDomain);printf("   DisablePageCombine                         %u\n", side_cnl_isan.DisablePageCombine);printf("   SpeculativeStoreBypassDisable              %u\n", side_cnl_isan.SpeculativeStoreBypassDisable);printf("   RestrictCoreSharing                        %u\n", side_cnl_isan.RestrictCoreSharing);printf("\n");/*描述:有关进程的用户模式硬件强制 Stack 保护的策略。自 Windows 10 版本 2004 及更高版本开始支持。typedef struct _PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY {union {DWORD Flags;struct {DWORD EnableUserShadowStack : 1;DWORD AuditUserShadowStack : 1;DWORD SetContextIpValidation : 1;DWORD AuditSetContextIpValidation : 1;DWORD EnableUserShadowStackStrictMode : 1;DWORD BlockNonCetBinaries : 1;DWORD BlockNonCetBinariesNonEhcont : 1;DWORD AuditBlockNonCetBinaries : 1;DWORD CetDynamicApisOutOfProcOnly : 1;DWORD SetContextIpValidationRelaxedMode : 1;DWORD ReservedFlags : 22;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY, *PPROCESS_MITIGATION_USER_SHADOW_STACK_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessUserShadowStackPolicy, &usw_stack, sizeof(usw_stack));printf("ProcessUserShadowStackPolicy:\n");PrintBinaryFlags(usw_stack.Flags);printf("\n Analysis:\n");printf("   EnableUserShadowStack                      %u\n", usw_stack.EnableUserShadowStack);printf("   AuditUserShadowStack                       %u\n", usw_stack.AuditUserShadowStack);printf("   SetContextIpValidation                     %u\n", usw_stack.SetContextIpValidation);printf("   AuditSetContextIpValidation                %u\n", usw_stack.AuditSetContextIpValidation);printf("   EnableUserShadowStackStrictMode            %u\n", usw_stack.EnableUserShadowStackStrictMode);printf("   BlockNonCetBinaries                        %u\n", usw_stack.BlockNonCetBinaries);printf("   BlockNonCetBinariesNonEhcont               %u\n", usw_stack.BlockNonCetBinariesNonEhcont);printf("   AuditBlockNonCetBinaries                   %u\n", usw_stack.AuditBlockNonCetBinaries);printf("   CetDynamicApisOutOfProcOnly                %u\n", usw_stack.CetDynamicApisOutOfProcOnly);printf("   SetContextIpValidationRelaxedMode          %u\n", usw_stack.SetContextIpValidationRelaxedMode);printf("\n");/*描述:进程的重定向卫士 (RedirectionGuard) 策略。typedef struct _PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY {union {DWORD Flags;struct {DWORD EnforceRedirectionTrust : 1;DWORD AuditRedirectionTrust : 1;DWORD ReservedFlags : 30;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY, *PPROCESS_MITIGATION_REDIRECTION_TRUST_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessRedirectionTrustPolicy, &trust_redc, sizeof(trust_redc));printf("ProcessRedirectionTrustPolicy:\n");PrintBinaryFlags(trust_redc.Flags);printf("\n Analysis:\n");printf("   EnforceRedirectionTrust                    %u\n", trust_redc.EnforceRedirectionTrust);printf("   EnforceRedirectionTrust                    %u\n", trust_redc.AuditRedirectionTrust);printf("\n");/*描述:进程的用户指针身份验证策略。typedef struct _PROCESS_MITIGATION_USER_POINTER_AUTH_POLICY {union {DWORD Flags;struct {DWORD EnablePointerAuthUserIp : 1;DWORD ReservedFlags : 31;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_USER_POINTER_AUTH_POLICY, *PPROCESS_MITIGATION_USER_POINTER_AUTH_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessUserPointerAuthPolicy, &upt_auth, sizeof(upt_auth));printf("ProcessUserPointerAuthPolicy:\n");PrintBinaryFlags(upt_auth.Flags);printf("\n Analysis:\n");printf("   EnablePointerAuthUserIp                    %u\n", upt_auth.EnablePointerAuthUserIp);printf("\n");/*描述:结构化异常处理覆盖保护 (SEHOP) 策略。typedef struct _PROCESS_MITIGATION_SEHOP_POLICY {union {DWORD Flags;struct {DWORD EnableSehop : 1;DWORD ReservedFlags : 31;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_SEHOP_POLICY, *PPROCESS_MITIGATION_SEHOP_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessSEHOPPolicy, &seh_op_policy, sizeof(seh_op_policy));printf("ProcessSEHOPPolicy:\n");PrintBinaryFlags(seh_op_policy.Flags);printf("\n Analysis:\n");printf("   EnableSehop                                %u\n", seh_op_policy.EnableSehop);printf("\n");/*描述:进程的激活上下文(ActivationContext) 保护策略。typedef struct _PROCESS_MITIGATION_ACTIVATION_CONTEXT_TRUST_POLICY {union {DWORD Flags;struct {DWORD AssemblyManifestRedirectionTrust : 1;DWORD ReservedFlags : 31;} DUMMYSTRUCTNAME;} DUMMYUNIONNAME;} PROCESS_MITIGATION_ACTIVATION_CONTEXT_TRUST_POLICY, *PPROCESS_MITIGATION_ACTIVATION_CONTEXT_TRUST_POLICY;*/GetProcessMitigationPolicy(hProc, ProcessActivationContextTrustPolicy, &activ_ctx_truct, sizeof(activ_ctx_truct));printf("ProcessActivationContextTrustPolicy:\n");PrintBinaryFlags(activ_ctx_truct.Flags);printf("\n Analysis:\n");printf("   AssemblyManifestRedirectionTrust           %u\n", activ_ctx_truct.AssemblyManifestRedirectionTrust);//printf("\n");
}BOOL EnableDebugPrivilege(BOOL fEnable) {BOOL fOk = FALSE;HANDLE hToken;if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {TOKEN_PRIVILEGES tp = { 0 };tp.PrivilegeCount = 1;LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);fOk = (GetLastError() == ERROR_SUCCESS);CloseHandle(hToken);}return(fOk);
}// 获取 PE 文件的描述信息
void GetProcessDescription(const wchar_t* filePath) {DWORD verHandle = 0;DWORD verSize = GetFileVersionInfoSizeW(filePath, &verHandle);if (verSize > 0) {LPVOID verData = malloc(verSize);if (GetFileVersionInfoW(filePath, verHandle, verSize, verData)) {LPVOID lpBuffer = NULL;UINT size = 0;if (VerQueryValueW(verData, L"\\StringFileInfo\\040904b0\\FileDescription", &lpBuffer, &size) && size > 0) {printf("[*] Description: %ws\n", (wchar_t*)lpBuffer);}else {printf("[!] No description available.\n");}}else {printf("[!] Unable to get version info, code %u\n", GetLastError());}free(verData);}else {printf("[!] Unable to get version size, code %u\n", GetLastError());}
}int main(int argc, const char* argv[]) {printf("\n");if (argc != 2) {printf("\nGetProcessMitigationPolicy for Win10/11.\n\n");printf("Usage:\n");printf("%s <pid>\n", argv[0]);return 0;}// 启用 SE_DEBUG 特权if (!EnableDebugPrivilege(TRUE)) {printf("[!] AdjustTokenPrivileges Failed.<%d>\n", GetLastError());}// 从命令行参数获取目标进程 PIDDWORD dwTargetPid = 0;dwTargetPid = atoi(argv[1]);printf("[*] TargetPid:%d\n", dwTargetPid);// 访问目标进程HANDLE hProcess;hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwTargetPid);if (hProcess == NULL) {printf("[!] Unable to open process %u, code %u\n", dwTargetPid, GetLastError());return 0;}// 获取进程名称wchar_t processPath[2048];ZeroMemory(processPath, sizeof(wchar_t) * 2048);DWORD dwSize = 2046;if (QueryFullProcessImageNameW(hProcess, 0, processPath, &dwSize)) {printf("[*] Process Path: %ws\n", processPath); // 输出进程路径// 从路径中提取进程名称wchar_t* processName = wcsrchr(processPath, '\\');if (processName) {printf("[*] Process Name: %ws\n", processName + 1); // 输出进程名称}else {printf("[*] Process Name: %ws\n", processPath); // 如果路径中没有分隔符,直接输出路径}// 获取并输出进程的描述信息GetProcessDescription(processPath);}else {printf("[!] Unable to get process path, code %u\n", GetLastError());}printf("\n");// 解析进程的缓解策略show_mitigations(hProcess);printf("\n");CloseHandle(hProcess);return 0;
}

测试效果截图:

测试效果截图

四、总结

通过本文的介绍和代码示例,开发人员可以有效地获取和分析 Windows 进程的缓解策略设置。通过使用 ​​​​​​​GetProcessMitigationPolicy 函数,可以有效地分析和显示目标进程的各项安全设置。

这些方法在系统安全和软件开发中非常有用,特别是在需要确保应用程序或系统服务的安全性时。开发者可以将这些方法集成到调试工具或安全扫描工具中,进一步增强系统的安全性和稳定性。


原文出处链接:[https://blog.csdn.net/qq_59075481/article/details/142234952]。

本文发布于:2024.09.13,更新于:2024.09.13.

相关文章:

【Windows】获取进程缓解策略设置情况

目录 一、前言 二、主要概念 三、实现步骤 四、总结 原文出处链接&#xff1a;[https://blog.csdn.net/qq_59075481/article/details/142234952] 一、前言 在现代操作系统中&#xff0c;进程缓解策略&#xff08;Process Mitigation Policy&#xff09;提供了一种防御机制…...

语音识别相关概念

声音如何保存成数字信号&#xff1f; 声音是听觉对声波产生的感知&#xff0c;而声波是一种在时间和振幅上连续的模拟量&#xff0c;本质是介质的振动&#xff0c;&#xff0c;比如空气的振动。那么只需要把这个振动信号记录下来&#xff0c;并用一串数字来表达振动信号振动的…...

Iceberg与SparkSQL查询操作整合

前言 spark操作iceberg之前先要配置spark catalogs,详情参考Iceberg与Spark整合环境配置。 Iceberg使用Apache Spark的DataSourceV2 API来实现数据源和catalog。 使用SQL查询 查询的时候表要按照:catalog.数据库.表名的格式 SELECT * FROM prod.db.table; -- catalog: p…...

Linux 上安装 PostgreSQL

Linux 上安装 PostgreSQL PostgreSQL 是一款功能强大的开源关系数据库管理系统,因其稳定性、可扩展性和先进的功能而广受欢迎。在 Linux 系统上安装 PostgreSQL 是一个相对直接的过程,但具体步骤可能会因您使用的 Linux 发行版而异。本文将介绍在几种流行的 Linux 发行版上安…...

WRF-LES与PALM微尺度气象大涡模拟、PALM静态数据预备、PALM驱动数据预报、PALM模拟

查看原文>>>WRF-LES与PALM微尺度气象大涡模拟及ChatGPT在大气科学领域应用 针对微尺度气象的复杂性&#xff0c;大涡模拟&#xff08;LES&#xff09;提供了一种无可比拟的解决方案。微尺度气象学涉及对小范围内的大气过程进行精确模拟&#xff0c;这些过程往往与天气…...

需求分析概述

为什么要进行需求分析呢&#xff1f; 笑话&#xff1a;富翁娶妻 某富翁想要娶老婆&#xff0c;有三个人选&#xff0c;富翁给了三个女孩各一千元&#xff0c;请 她们把房间装满。第一个女孩买了很多棉花&#xff0c;装满房间的1/2。第 二个女孩买了很多气球&#xff0c;装满…...

Java | Leetcode Java题解之第391题完美矩形

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isRectangleCover(int[][] rectangles) {long area 0;int minX rectangles[0][0], minY rectangles[0][1], maxX rectangles[0][2], maxY rectangles[0][3];Map<Point, Integer> cnt new HashM…...

java项目之基于web的人力资源管理系统的设计与实现(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的基于web的人力资源管理系统的设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; …...

Linux 防火墙:iptables (二)

文章目录 SNAT 原理与应用SNAT 应用环境SNAT 原理SNAT 转换前提条件SNAT 格式SNAT 转换规则配置 DNAT 原理与应用DNAT 应用环境DNAT 原理DNAT 转换前提条件DNAT 格式DNAT 转换规则配置 iptables 规则的备份和还原导出&#xff08;备份&#xff09;所有表的规则导入&#xff08;…...

小目标检测顶会新思路!最新成果刷爆遥感SOTA,参数小了18倍

遥感领域的小目标检测一直是个具有挑战性和趣味性的研究方向&#xff0c;同时也是顶会顶刊的常客。但不得不说&#xff0c;今年关于遥感小目标检测的研究热情尤其高涨&#xff0c;已经出现了很多非常优秀的成果。 比如SuperYOLO方法&#xff0c;通过融合多模态数据并执行高分辨…...

【Ubuntu】虚拟机安装USB摄像头ROS驱动 usb_cam(最新方法)

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…...

免费的成绩查询微信小程序,让家长轻松掌握学生表现

传统的教学方式在不断地被革新。在成绩查询这一环节&#xff0c;老师们曾经面临着繁琐的手工操作和信息安全的风险。可现如今有一个让成绩查询变得轻松、高效且安全的新工具——易查分。 过去需要花费大量时间来整理成绩&#xff0c;然后通过短信或者打电话的方式告知给家长。以…...

[含视频和源码]CRUD的最佳实践,联动前后端,包含微信小程序,API,HTML等(三)

关说不练假把式&#xff0c;在上一&#xff0c;二篇中介绍了我心目中的CRUD的样子 基于之前的理念&#xff0c;我开发了一个命名为PasteTemplate的项目&#xff0c;这个项目呢后续会转化成项目模板&#xff0c;转化成项目模板后&#xff0c;后续需要开发新的项目就可以基于这…...

如何把我另一个分支上的commit拿过来

在开源过程中&#xff0c;每一次PR都是要经过严格的review的&#xff0c;这期间可能会进行多次修改&#xff0c;补充提交&#xff0c;而且这一般来说不是一个很迅速的过程&#xff0c;此时我们可能会先往后进行开发。我一般会把项目分模块逐步建立分支&#xff0c;当前一个pr合…...

【rpg像素角色】俯视角-行走动画

制作像素角色的俯视角行走动画并不像看上去那么复杂&#xff0c;尤其是在你已经完成了角色的4个方向站立姿势之后&#xff08;其中左右方向可以通过水平翻转实现&#xff09;。接下来&#xff0c;我会一步步为你讲解如何制作行走动画。 1. 理解行走规律 在制作行走动画之前&am…...

Python时间序列分析新技能,轻松掌握时间索引

大家好&#xff0c;在数据分析领域&#xff0c;时间序列数据分析是一项非常重要的技能。Pandas作为Python中强大的数据处理库&#xff0c;在处理时间序列数据时提供了丰富的功能&#xff0c;其中时间索引的应用是时间序列分析中的关键。本文将介绍如何在Pandas中使用时间索引进…...

sklearn-逻辑回归-特征工程示例

sklearn-逻辑回归-特征工程示例 在实际应用场景中&#xff0c;有时候特征的数量会很多&#xff0c;我们出于业务考虑&#xff0c;也出于计算量的考虑&#xff0c;希望对逻辑回归进行特征选择来降维。比如在判断一个人是否会患乳腺癌的时候&#xff0c;医生如果看58个指标来确诊…...

RTMP播放器延迟最低可以做到多少?

技术背景 RTMP播放器的延迟可以受到多种因素的影响&#xff0c;包括网络状况、推流设置、播放器配置以及CDN分发等。因此&#xff0c;RTMP播放器的延迟并不是一个固定的数值&#xff0c;而是可以在一定范围内变化的。 正常情况下&#xff0c;网上大多看到的&#xff0c;针对R…...

细致刨析JDBC ① 基础篇

目录 一、JDBC概述 1.JDBC的概念 ​编辑2.JDBC的核心组成 ① 接口规范: ② 实现规范: 二、JDBC快速入门 1.JDBC搭建步骤 三、核心API理解 1.注册驱动 2.Connection 3.Statement 4.PreparedStatement 5.ResultSet 四、基于Preparedment实现CRUD 1.查询单行单列 2.查询单行…...

Reactive 编程-Loom 项目(虚拟线程)

Reactive 编程与 Loom 项目&#xff08;虚拟线程&#xff09; Java 项目 Loom 是 Oracle 在 JVM 上的一项重大变革&#xff0c;旨在引入 虚拟线程&#xff08;Virtual Threads&#xff09;&#xff0c;以简化并发编程。传统的 Java 线程是重量级的&#xff0c;由操作系统管理&…...

Windows下使用MinGW编译安装zmq的步骤

背景&#xff1a; 在开发过程中&#xff0c;需要使用zmq库进行数据交互&#xff0c;因此需要编译zmq库。 安装步骤 软件下载 https://github.com/zeromq/libzmq.git 下载&#xff0c;将代码切换到git checkout 4c6cff6391分支 软件编译 cd .\libzmq\ mkdir build cd .\bu…...

电商云账户分账系统:打造高效资金流转体系

在当今的电子商务时代&#xff0c;随着消费者购物习惯的转变和在线交易量的激增&#xff0c;电商平台的运营模式也日趋复杂。为了满足多商家共存、利益共享的需求&#xff0c;电商分账成为了一个至关重要的环节。 电商分账是指电商平台在销售商品或服务后&#xff0c;根据事先…...

设计模式 -- 单例设计模式

1.1 单例 创建一个单例对象 SingleModel , SingleModel 类有它的私有构造函数和本身的一个静态实例。 SingleModel 类提供了一个静态方法&#xff0c;供外界获取它的静态实例。 DesignTest 我们的演示类使用 SingleModel 类来获取 SingleModel 对象。 创建 Single…...

python fastapi 打包exe

创建虚拟环境 python -m venv 国内依赖仓库 # 换源 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip config set install.trusted-host mirrors.aliyun.com 安装nuitka pip install nuitka 生成exe nuitka --mingw64 --show-progress --s…...

【测试开岗面试】知识点总结

1.知识点总结 Q:请你分别介绍一下单元测试、集成测试、系统测试、验收测试、回归测试 单元测试 (Unit Testing) 单元测试是对软件中最小可测试单元&#xff08;通常是函数或方法&#xff09;进行验证的过程。它的目的是确保每个单元在设计时的功能能够正常运行。单元测试通常由…...

【高级编程】synchronized 解决并发问题 类的线程安全类型

文章目录 并发问题同步方法同步代码块 线程安全类型ArrayListHashtableHashMapVector 多线程共享数据引发的问题 模拟 “A” “B” “C” 三人抢票&#xff0c;总票数10张&#xff0c;打印抢票情况以及剩余票数。 public class Site implements Runnable {int count 10; // …...

Speculative RAG:为知识密集型数据服务的RAG

论文链接 RAG的一个棘手问题是不知道该召回多少chunk&#xff0c;少了可能丢信息&#xff0c;多了会引入噪声信息。虽然有self-reasoning等自我反思的解决办法&#xff0c;但是整体链路太长&#xff0c;延迟高&#xff0c;不利于工业落地。 虽然无法面对整个服务场景&#xff…...

[Go]-抢购类业务方案

文章目录 要点&#xff1a;1. 抢购/秒杀业务的关键挑战2. 技术方案3.关键实现点4.性能优化建议5.其他考虑因素 细节拆分&#xff1a;1. **高并发处理**2.**限流与防护**3.**库存控制**4. **异步处理**5. **数据一致性**6. **常用架构设计**7. **代码示例**8. 进一步优化9. 注意…...

Android 源码多个Launcher设置默认Launcher

目录 第一部分、android10之前 一.多个launcher 启动设置默认launcher的核心类 二 在自定义服务里面设置默认Launcher 第二部分、android10之后 一、Launcher应用内置并设置为默认Launcher 1.通过ResolverActivity.java设置为默认Launcher 改法一&#xff1a; 改法二&am…...

计算机毕业设计 网上体育商城系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...