summaryrefslogtreecommitdiffhomepage
path: root/tun
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-07-29 01:27:40 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2021-07-29 01:27:40 +0200
commitbad6caeb82edd0e22bdbcfa1ca544a5805109e14 (patch)
tree653e9a40390d7c6e1f34a3ade107809323ab3433 /tun
parentc89f5ca665bdab39cdc695c171e0eedd6baf03e8 (diff)
memmod: fix protected delayed load the right way
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>
Diffstat (limited to 'tun')
-rw-r--r--tun/wintun/memmod/memmod_windows.go11
-rw-r--r--tun/wintun/memmod/syscall_windows.go11
2 files changed, 13 insertions, 9 deletions
diff --git a/tun/wintun/memmod/memmod_windows.go b/tun/wintun/memmod/memmod_windows.go
index 6eb022d..59450e7 100644
--- a/tun/wintun/memmod/memmod_windows.go
+++ b/tun/wintun/memmod/memmod_windows.go
@@ -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 {
diff --git a/tun/wintun/memmod/syscall_windows.go b/tun/wintun/memmod/syscall_windows.go
index 6d2d18e..b79be69 100644
--- a/tun/wintun/memmod/syscall_windows.go
+++ b/tun/wintun/memmod/syscall_windows.go
@@ -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