From c89f5ca665bdab39cdc695c171e0eedd6baf03e8 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 29 Jul 2021 01:01:46 +0200 Subject: [PATCH] memmod: disable protected delayed load for now Probably a bad idea, but we don't currently support it, and those huge windows.NewCallback trampolines make juicer targets anyway. Signed-off-by: Jason A. Donenfeld --- tun/wintun/memmod/memmod_windows.go | 13 ++++++- tun/wintun/memmod/syscall_windows.go | 42 ++++++++++++++++++++ tun/wintun/memmod/syscall_windows_32.go | 51 +++++++++++++++++++++++++ tun/wintun/memmod/syscall_windows_64.go | 51 +++++++++++++++++++++++++ 4 files changed, 155 insertions(+), 2 deletions(-) diff --git a/tun/wintun/memmod/memmod_windows.go b/tun/wintun/memmod/memmod_windows.go index c75de5a..6eb022d 100644 --- a/tun/wintun/memmod/memmod_windows.go +++ b/tun/wintun/memmod/memmod_windows.go @@ -41,12 +41,12 @@ func (module *Module) headerDirectory(idx int) *IMAGE_DATA_DIRECTORY { return &module.headers.OptionalHeader.DataDirectory[idx] } -func (module *Module) copySections(address uintptr, size uintptr, old_headers *IMAGE_NT_HEADERS) error { +func (module *Module) copySections(address uintptr, size uintptr, oldHeaders *IMAGE_NT_HEADERS) error { sections := module.headers.Sections() for i := range sections { if sections[i].SizeOfRawData == 0 { // Section doesn't contain data in the dll itself, but may define uninitialized data. - sectionSize := old_headers.OptionalHeader.SectionAlignment + sectionSize := oldHeaders.OptionalHeader.SectionAlignment if sectionSize == 0 { continue } @@ -491,6 +491,15 @@ func LoadLibrary(data []byte) (module *Module, err error) { return } + // Disable protected delayed load for now. TODO: We should support this properly at some point. + if IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG < module.headers.OptionalHeader.NumberOfRvaAndSizes { + directory := module.headerDirectory(IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG) + if directory.Size != 0 && directory.VirtualAddress != 0 { + loadConfig := (*IMAGE_LOAD_CONFIG_DIRECTORY)(a2p(module.codeBase + uintptr(directory.VirtualAddress))) + loadConfig.GuardFlags &^= IMAGE_GUARD_PROTECT_DELAYLOAD_IAT + } + } + // Mark memory pages depending on section headers and release sections that are marked as "discardable". err = module.finalizeSections() if err != nil { diff --git a/tun/wintun/memmod/syscall_windows.go b/tun/wintun/memmod/syscall_windows.go index 31dd0b5..6d2d18e 100644 --- a/tun/wintun/memmod/syscall_windows.go +++ b/tun/wintun/memmod/syscall_windows.go @@ -174,6 +174,21 @@ func (ishdr *IMAGE_SECTION_HEADER) SetVirtualSize(addr uint32) { ishdr.physicalAddressOrVirtualSize = addr } +const ( + // Dll characteristics. + IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020 + IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040 + IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080 + IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100 + IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200 + IMAGE_DLL_CHARACTERISTICS_NO_SEH = 0x0400 + IMAGE_DLL_CHARACTERISTICS_NO_BIND = 0x0800 + IMAGE_DLL_CHARACTERISTICS_APPCONTAINER = 0x1000 + IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000 + IMAGE_DLL_CHARACTERISTICS_GUARD_CF = 0x4000 + IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000 +) + const ( // Section characteristics. IMAGE_SCN_TYPE_REG = 0x00000000 // Reserved. @@ -317,6 +332,33 @@ func (imgimpdesc *IMAGE_IMPORT_DESCRIPTOR) OriginalFirstThunk() uint32 { return imgimpdesc.characteristicsOrOriginalFirstThunk } +type IMAGE_LOAD_CONFIG_CODE_INTEGRITY struct { + Flags uint16 + Catalog uint16 + CatalogOffset uint32 + Reserved uint32 +} + +const ( + IMAGE_GUARD_CF_INSTRUMENTED = 0x00000100 + IMAGE_GUARD_CFW_INSTRUMENTED = 0x00000200 + IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT = 0x00000400 + IMAGE_GUARD_SECURITY_COOKIE_UNUSED = 0x00000800 + IMAGE_GUARD_PROTECT_DELAYLOAD_IAT = 0x00001000 + IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION = 0x00002000 + IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT = 0x00004000 + IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION = 0x00008000 + IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT = 0x00010000 + IMAGE_GUARD_RF_INSTRUMENTED = 0x00020000 + IMAGE_GUARD_RF_ENABLE = 0x00040000 + IMAGE_GUARD_RF_STRICT = 0x00080000 + IMAGE_GUARD_RETPOLINE_PRESENT = 0x00100000 + IMAGE_GUARD_EH_CONTINUATION_TABLE_PRESENT = 0x00400000 + IMAGE_GUARD_XFG_ENABLED = 0x00800000 + IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK = 0xF0000000 + IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT = 28 +) + const ( DLL_PROCESS_ATTACH = 1 DLL_THREAD_ATTACH = 2 diff --git a/tun/wintun/memmod/syscall_windows_32.go b/tun/wintun/memmod/syscall_windows_32.go index a96d81b..7abbac9 100644 --- a/tun/wintun/memmod/syscall_windows_32.go +++ b/tun/wintun/memmod/syscall_windows_32.go @@ -43,3 +43,54 @@ type IMAGE_OPTIONAL_HEADER struct { } const IMAGE_ORDINAL_FLAG uintptr = 0x80000000 + +type IMAGE_LOAD_CONFIG_DIRECTORY struct { + Size uint32 + TimeDateStamp uint32 + MajorVersion uint16 + MinorVersion uint16 + GlobalFlagsClear uint32 + GlobalFlagsSet uint32 + CriticalSectionDefaultTimeout uint32 + DeCommitFreeBlockThreshold uint32 + DeCommitTotalFreeThreshold uint32 + LockPrefixTable uint32 + MaximumAllocationSize uint32 + VirtualMemoryThreshold uint32 + ProcessHeapFlags uint32 + ProcessAffinityMask uint32 + CSDVersion uint16 + DependentLoadFlags uint16 + EditList uint32 + SecurityCookie uint32 + SEHandlerTable uint32 + SEHandlerCount uint32 + GuardCFCheckFunctionPointer uint32 + GuardCFDispatchFunctionPointer uint32 + GuardCFFunctionTable uint32 + GuardCFFunctionCount uint32 + GuardFlags uint32 + CodeIntegrity IMAGE_LOAD_CONFIG_CODE_INTEGRITY + GuardAddressTakenIatEntryTable uint32 + GuardAddressTakenIatEntryCount uint32 + GuardLongJumpTargetTable uint32 + GuardLongJumpTargetCount uint32 + DynamicValueRelocTable uint32 + CHPEMetadataPointer uint32 + GuardRFFailureRoutine uint32 + GuardRFFailureRoutineFunctionPointer uint32 + DynamicValueRelocTableOffset uint32 + DynamicValueRelocTableSection uint16 + Reserved2 uint16 + GuardRFVerifyStackPointerFunctionPointer uint32 + HotPatchTableOffset uint32 + Reserved3 uint32 + EnclaveConfigurationPointer uint32 + VolatileMetadataPointer uint32 + GuardEHContinuationTable uint32 + GuardEHContinuationCount uint32 + GuardXFGCheckFunctionPointer uint32 + GuardXFGDispatchFunctionPointer uint32 + GuardXFGTableDispatchFunctionPointer uint32 + CastGuardOsDeterminedFailureMode uint32 +} diff --git a/tun/wintun/memmod/syscall_windows_64.go b/tun/wintun/memmod/syscall_windows_64.go index 521262c..10c6533 100644 --- a/tun/wintun/memmod/syscall_windows_64.go +++ b/tun/wintun/memmod/syscall_windows_64.go @@ -42,3 +42,54 @@ type IMAGE_OPTIONAL_HEADER struct { } const IMAGE_ORDINAL_FLAG uintptr = 0x8000000000000000 + +type IMAGE_LOAD_CONFIG_DIRECTORY struct { + Size uint32 + TimeDateStamp uint32 + MajorVersion uint16 + MinorVersion uint16 + GlobalFlagsClear uint32 + GlobalFlagsSet uint32 + CriticalSectionDefaultTimeout uint32 + DeCommitFreeBlockThreshold uint64 + DeCommitTotalFreeThreshold uint64 + LockPrefixTable uint64 + MaximumAllocationSize uint64 + VirtualMemoryThreshold uint64 + ProcessAffinityMask uint64 + ProcessHeapFlags uint32 + CSDVersion uint16 + DependentLoadFlags uint16 + EditList uint64 + SecurityCookie uint64 + SEHandlerTable uint64 + SEHandlerCount uint64 + GuardCFCheckFunctionPointer uint64 + GuardCFDispatchFunctionPointer uint64 + GuardCFFunctionTable uint64 + GuardCFFunctionCount uint64 + GuardFlags uint32 + CodeIntegrity IMAGE_LOAD_CONFIG_CODE_INTEGRITY + GuardAddressTakenIatEntryTable uint64 + GuardAddressTakenIatEntryCount uint64 + GuardLongJumpTargetTable uint64 + GuardLongJumpTargetCount uint64 + DynamicValueRelocTable uint64 + CHPEMetadataPointer uint64 + GuardRFFailureRoutine uint64 + GuardRFFailureRoutineFunctionPointer uint64 + DynamicValueRelocTableOffset uint32 + DynamicValueRelocTableSection uint16 + Reserved2 uint16 + GuardRFVerifyStackPointerFunctionPointer uint64 + HotPatchTableOffset uint32 + Reserved3 uint32 + EnclaveConfigurationPointer uint64 + VolatileMetadataPointer uint64 + GuardEHContinuationTable uint64 + GuardEHContinuationCount uint64 + GuardXFGCheckFunctionPointer uint64 + GuardXFGDispatchFunctionPointer uint64 + GuardXFGTableDispatchFunctionPointer uint64 + CastGuardOsDeterminedFailureMode uint64 +}