]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
memmod: fix protected delayed load the right way
authorJason A. Donenfeld <Jason@zx2c4.com>
Wed, 28 Jul 2021 23:27:40 +0000 (01:27 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Wed, 28 Jul 2021 23:27:40 +0000 (01:27 +0200)
The reason this was failing before is that dloadsup.h's
DloadObtainSection was doing a linear search of sections to find which
header corresponds with the IMAGE_DELAYLOAD_DESCRIPTOR section, and we
were stupidly overwriting the VirtualSize field, so the linear search
wound up matching the .text section, which then it found to not be
marked writable and failed with FAST_FAIL_DLOAD_PROTECTION_FAILURE.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
tun/wintun/memmod/memmod_windows.go
tun/wintun/memmod/syscall_windows.go

index 6eb022d841bd992b8947f07002f87da0ffb6567a..59450e785ff72c01e13c5818617f6eb67e1467fb 100644 (file)
@@ -166,6 +166,7 @@ func (module *Module) finalizeSections() error {
        sectionData.address = uintptr(sections[0].PhysicalAddress()) | imageOffset
        sectionData.alignedAddress = alignDown(sectionData.address, uintptr(module.headers.OptionalHeader.SectionAlignment))
        sectionData.size = module.realSectionSize(&sections[0])
+       sections[0].SetVirtualSize(uint32(sectionData.size))
        sectionData.characteristics = sections[0].Characteristics
 
        // Loop through all sections and change access flags.
@@ -173,6 +174,7 @@ func (module *Module) finalizeSections() error {
                sectionAddress := uintptr(sections[i].PhysicalAddress()) | imageOffset
                alignedAddress := alignDown(sectionAddress, uintptr(module.headers.OptionalHeader.SectionAlignment))
                sectionSize := module.realSectionSize(&sections[i])
+               sections[i].SetVirtualSize(uint32(sectionSize))
                // Combine access flags of all sections that share a page.
                // TODO: We currently share flags of a trailing large section with the page of a first small section. This should be optimized.
                if sectionData.alignedAddress == alignedAddress || sectionData.address+sectionData.size > alignedAddress {
@@ -491,15 +493,6 @@ 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 {
index 6d2d18e34c7c13d43f53608222f06094637ab5fe..b79be69e9e0e6a87dbdf626cfbd6dc7609e486bf 100644 (file)
@@ -332,6 +332,17 @@ func (imgimpdesc *IMAGE_IMPORT_DESCRIPTOR) OriginalFirstThunk() uint32 {
        return imgimpdesc.characteristicsOrOriginalFirstThunk
 }
 
+type IMAGE_DELAYLOAD_DESCRIPTOR struct {
+       Attributes                 uint32
+       DllNameRVA                 uint32
+       ModuleHandleRVA            uint32
+       ImportAddressTableRVA      uint32
+       ImportNameTableRVA         uint32
+       BoundImportAddressTableRVA uint32
+       UnloadInformationTableRVA  uint32
+       TimeDateStamp              uint32
+}
+
 type IMAGE_LOAD_CONFIG_CODE_INTEGRITY struct {
        Flags         uint16
        Catalog       uint16