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 <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2021-07-29 01:01:46 +02:00
parent 15b24b6179
commit c89f5ca665
4 changed files with 155 additions and 2 deletions

View file

@ -41,12 +41,12 @@ func (module *Module) headerDirectory(idx int) *IMAGE_DATA_DIRECTORY {
return &module.headers.OptionalHeader.DataDirectory[idx] 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() sections := module.headers.Sections()
for i := range sections { for i := range sections {
if sections[i].SizeOfRawData == 0 { if sections[i].SizeOfRawData == 0 {
// Section doesn't contain data in the dll itself, but may define uninitialized data. // 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 { if sectionSize == 0 {
continue continue
} }
@ -491,6 +491,15 @@ func LoadLibrary(data []byte) (module *Module, err error) {
return 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". // Mark memory pages depending on section headers and release sections that are marked as "discardable".
err = module.finalizeSections() err = module.finalizeSections()
if err != nil { if err != nil {

View file

@ -174,6 +174,21 @@ func (ishdr *IMAGE_SECTION_HEADER) SetVirtualSize(addr uint32) {
ishdr.physicalAddressOrVirtualSize = addr 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 ( const (
// Section characteristics. // Section characteristics.
IMAGE_SCN_TYPE_REG = 0x00000000 // Reserved. IMAGE_SCN_TYPE_REG = 0x00000000 // Reserved.
@ -317,6 +332,33 @@ func (imgimpdesc *IMAGE_IMPORT_DESCRIPTOR) OriginalFirstThunk() uint32 {
return imgimpdesc.characteristicsOrOriginalFirstThunk 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 ( const (
DLL_PROCESS_ATTACH = 1 DLL_PROCESS_ATTACH = 1
DLL_THREAD_ATTACH = 2 DLL_THREAD_ATTACH = 2

View file

@ -43,3 +43,54 @@ type IMAGE_OPTIONAL_HEADER struct {
} }
const IMAGE_ORDINAL_FLAG uintptr = 0x80000000 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
}

View file

@ -42,3 +42,54 @@ type IMAGE_OPTIONAL_HEADER struct {
} }
const IMAGE_ORDINAL_FLAG uintptr = 0x8000000000000000 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
}