diff --git a/src/driver/loader/fortmm.c b/src/driver/loader/fortmm.c index 812fa0d8..19bf3abd 100644 --- a/src/driver/loader/fortmm.c +++ b/src/driver/loader/fortmm.c @@ -66,9 +66,53 @@ static NTSTATUS GetModuleInfoList(PAUX_MODULE_EXTENDED_INFO *outModules, DWORD * return status; } +static VOID CopyZeroSectionTable( + PUCHAR codeBase, const PIMAGE_NT_HEADERS pNtHeaders, const PIMAGE_SECTION_HEADER section) +{ + /* Section doesn't contain data in the dll itself, but may define uninitialized data. */ + const DWORD sectionSize = pNtHeaders->OptionalHeader.SectionAlignment; + if (sectionSize == 0) + return; /* Ignore the empty section. */ + + /* Always use position from file to support alignments smaller than page size. */ + const PUCHAR dest = codeBase + section->VirtualAddress; + RtlZeroMemory(dest, sectionSize); + + section->Misc.PhysicalAddress = (DWORD) (uintptr_t) dest; + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, + "FORT: Loader Module: Zero Section: offset=%d size=%d\n", section->VirtualAddress, + sectionSize); +} + +static NTSTATUS CopyDataSectionTable(PUCHAR codeBase, const PIMAGE_NT_HEADERS pNtHeaders, + const PUCHAR pData, SIZE_T size, const PIMAGE_SECTION_HEADER section) +{ + const DWORD sectionSize = section->SizeOfRawData; + if ((SIZE_T) section->PointerToRawData + sectionSize > size) + return STATUS_INVALID_IMAGE_FORMAT; + + /* Always use position from file to support alignments smaller than page size. */ + const PUCHAR dest = codeBase + section->VirtualAddress; + RtlCopyMemory(dest, pData + section->PointerToRawData, sectionSize); + + /* NOTE: On 64bit systems we truncate to 32bit here but expand + * again later when "PhysicalAddress" is used. + */ + section->Misc.PhysicalAddress = (DWORD) (uintptr_t) dest; + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, + "FORT: Loader Module: Copy Section: src-offset=%d offset=%d size=%d data=%x\n", + section->PointerToRawData, section->VirtualAddress, sectionSize, *(PDWORD) dest); + + return STATUS_SUCCESS; +} + static NTSTATUS CopySectionTable( PUCHAR codeBase, const PIMAGE_NT_HEADERS pNtHeaders, const PUCHAR pData, SIZE_T size) { + NTSTATUS status = STATUS_SUCCESS; + PIMAGE_NT_HEADERS pHeaders = fort_nt_headers(codeBase); PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pHeaders); @@ -76,42 +120,15 @@ static NTSTATUS CopySectionTable( for (int i = 0; i < numberOfSections; ++i, ++section) { if (section->SizeOfRawData == 0) { - /* Section doesn't contain data in the dll itself, but may define uninitialized data. */ - const DWORD sectionSize = pNtHeaders->OptionalHeader.SectionAlignment; - if (sectionSize == 0) - continue; /* Ignore the empty section. */ - - /* Always use position from file to support alignments smaller than page size. */ - const PUCHAR dest = codeBase + section->VirtualAddress; - RtlZeroMemory(dest, sectionSize); - - section->Misc.PhysicalAddress = (DWORD) (uintptr_t) dest; - - DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, - "FORT: Loader Module: Zero Section: offset=%d size=%d\n", - section->VirtualAddress, sectionSize); + CopyZeroSectionTable(codeBase, pNtHeaders, section); } else { - const DWORD sectionSize = section->SizeOfRawData; - if (size < (SIZE_T) section->PointerToRawData + sectionSize) - return STATUS_INVALID_IMAGE_FORMAT; - - /* Always use position from file to support alignments smaller than page size. */ - const PUCHAR dest = codeBase + section->VirtualAddress; - RtlCopyMemory(dest, pData + section->PointerToRawData, sectionSize); - - /* NOTE: On 64bit systems we truncate to 32bit here but expand - * again later when "PhysicalAddress" is used. - */ - section->Misc.PhysicalAddress = (DWORD) (uintptr_t) dest; - - DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, - "FORT: Loader Module: Copy Section: src-offset=%d offset=%d size=%d data=%x\n", - section->PointerToRawData, section->VirtualAddress, sectionSize, - *(PDWORD) dest); + status = CopyDataSectionTable(codeBase, pNtHeaders, pData, size, section); + if (!NT_SUCCESS(status)) + break; } } - return STATUS_SUCCESS; + return status; } /*