NTSTATUS GetExeImageSize(LPWSTR ExeFullPath, PULONG SizeOfImage) { ULONG Size; NTSTATUS Status; NtFileDisk file; IMAGE_DOS_HEADER DosHeader; IMAGE_NT_HEADERS NtHeader; PIMAGE_OPTIONAL_HEADER OptionalHeader; PIMAGE_SECTION_HEADER SectionHeader; Status = file.Open(ExeFullPath); if (!NT_SUCCESS(Status)) return Status; Status = file.Read(&DosHeader, sizeof(DosHeader)); if (!NT_SUCCESS(Status)) return Status; if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE) return STATUS_INVALID_IMAGE_WIN_32; Status = file.Seek(DosHeader.e_lfanew, FILE_BEGIN); if (!NT_SUCCESS(Status)) return Status; Status = file.Read(&NtHeader, sizeof(NtHeader) - sizeof(NtHeader.OptionalHeader)); if (!NT_SUCCESS(Status)) return Status; if (NtHeader.Signature != IMAGE_NT_SIGNATURE) return STATUS_INVALID_IMAGE_WIN_32; if (NtHeader.FileHeader.SizeOfOptionalHeader > FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, SizeOfImage) + RTL_FIELD_SIZE(IMAGE_OPTIONAL_HEADER, SizeOfImage)) { OptionalHeader = (PIMAGE_OPTIONAL_HEADER)AllocStack(NtHeader.FileHeader.SizeOfOptionalHeader); Status = file.Read(OptionalHeader, NtHeader.FileHeader.SizeOfOptionalHeader); if (!NT_SUCCESS(Status)) return Status; *SizeOfImage = OptionalHeader->SizeOfImage; return STATUS_SUCCESS; } SectionHeader = (PIMAGE_SECTION_HEADER)AllocStack(NtHeader.FileHeader.NumberOfSections * sizeof(*SectionHeader)); Status = file.Read(SectionHeader, NtHeader.FileHeader.NumberOfSections * sizeof(*SectionHeader)); if (!NT_SUCCESS(Status)) return Status; Size = 0; for (ULONG NumberOfSections = NtHeader.FileHeader.NumberOfSections; NumberOfSections; --NumberOfSections) { Size += SectionHeader->Misc.VirtualSize; ++SectionHeader; } Size += ROUND_UP(file.GetCurrentPos(), MEMORY_PAGE_SIZE); *SizeOfImage = Size; return STATUS_SUCCESS; }