前言:
在CVE-2017-5715漏洞曝出之后,微软做了一系列的措施来缓解,并在win10 1809(17763)之后会默认启用了Retpoline或导入优化,这取决于用户设置或cpu支持情况,也有两个都不启动的,但KASLR总是启动的,启动KASLR,会替换pte的旧值到随机化后的值,不过即使不能启用Retpoline,也会启动导入优化(1809之后),启用RetPoline或导入优化之后,winload.exe在加载ntos和hal.dll时,会替换一些指令,pe格式也发生了部分改变(win8.1已改变,后续只是增加).获取启用状态可调用ZwQuerySystemInformation的201号功能查询(>=1803版本),结构体定义如下:
typedef struct _SYSTEM_SPECULATION_CONTROL_INFORMATION
{
struct
{
ULONG BpbEnabled : 1;
ULONG BpbDisabledSystemPolicy : 1;
ULONG BpbDisabledNoHardwareSupport : 1;
ULONG SpecCtrlEnumerated : 1;
ULONG SpecCmdEnumerated : 1;
ULONG IbrsPresent : 1;
ULONG StibpPresent : 1;
ULONG SmepPresent : 1;
ULONG SpeculativeStoreBypassDisableAvailable : 1;
ULONG SpeculativeStoreBypassDisableSupported : 1;
ULONG SpeculativeStoreBypassDisabledSystemWide : 1;
ULONG SpeculativeStoreBypassDisabledKernel : 1;
ULONG SpeculativeStoreBypassDisableRequired : 1;
ULONG BpbDisabledKernelToUser : 1;
ULONG SpecCtrlRetpolineEnabled : 1;
ULONG SpecCtrlImportOptimizationEnabled : 1;
ULONG Reserved : 24;
} SpeculationControlFlags;
} SYSTEM_SPECULATION_CONTROL_INFORMATION, *PSYSTEM_SPECULATION_CONTROL_INFORMATION;
DVRT:
全名Dynamic Value Relocation Table,此表记录需要替换的指令的指针,当然,系统也可以选择不进行替换,因为这些镜像在编译时,会留出一些空隙,比如:
call qword ptr[__imp__func]
nop
即使不替换,也不会影响正常执行.
在开启pchunter,windows kernel explorer 内核钩子扫描时,会扫出大量钩子(pchunter最新版已不再扫ntos).
查看sdk 1909 ntimage.h(win8.1时就存在一些),可发现有新的结构体,如下
typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64 {
xxxxxxxxxxxxx
DWORD GuardFlags;
IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity;
ULONGLONG GuardAddressTakenIatEntryTable; // VA
ULONGLONG GuardAddressTakenIatEntryCount;
ULONGLONG GuardLongJumpTargetTable; // VA
ULONGLONG GuardLongJumpTargetCount;
ULONGLONG DynamicValueRelocTable; // VA
ULONGLONG CHPEMetadataPointer; // VA
ULONGLONG GuardRFFailureRoutine; // VA
ULONGLONG GuardRFFailureRoutineFunctionPointer; // VA
DWORD DynamicValueRelocTableOffset;
WORD DynamicValueRelocTableSection;
WORD Reserved2;
ULONGLONG GuardRFVerifyStackPointerFunctionPointer; // VA
DWORD HotPatchTableOffset;
DWORD Reserved3;
ULONGLONG EnclaveConfigurationPointer; // VA
ULONGLONG VolatileMetadataPointer; // VA
ULONGLONG GuardEHContinuationTable; // VA
ULONGLONG GuardEHContinuationCount;
} IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64;
typedef struct _IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER {
BYTE PrologueByteCount;
// BYTE PrologueBytes[PrologueByteCount];
} IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER;
typedef IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER UNALIGNED * PIMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER;
typedef struct _IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER {
DWORD EpilogueCount;
BYTE EpilogueByteCount;
BYTE BranchDescriptorElementSize;
WORD BranchDescriptorCount;
// BYTE BranchDescriptors[...];
// BYTE BranchDescriptorBitMap[...];
} IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER;
typedef IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER UNALIGNED * PIMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER;
typedef struct _IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION {
DWORD PageRelativeOffset : 12;
DWORD IndirectCall : 1;
DWORD IATIndex : 19;
} IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION;
typedef IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION UNALIGNED * PIMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION;
typedef struct _IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION {
WORD PageRelativeOffset : 12;
WORD IndirectCall : 1;
WORD RexWPrefix : 1;
WORD CfgCheck : 1;
WORD Reserved : 1;
} IM