44 if (NULL == VirtualSize)
49 if (NULL == EntryPoint)
57 ERROR(
"[ERROR] IntPeValidateHeader failed: 0x%08x\n", status);
68 if (0 == memcmp(pSec->
Name,
"ENTRYP",
sizeof(
"ENTRYP")))
70 TRACE(
"[INFO] Found 'ENTRYP' section at 0x%08x, will use it as an EP!\n", pSec->
VirtualAddress);
115 if (NULL == RawImage)
120 if (NULL == VirtualImage)
125 if (NULL == Sections)
131 memset(VirtualImage, 0, VirtualImageSize);
134 minSection = 0xFFFFFFFF;
138 for (i = 0; i < NumberOfSections; i++)
140 if (Sections[i].PointerToRawData < minSection &&
143 minSection = Sections[i].PointerToRawData;
147 if (RawImageSize < minSection)
149 ERROR(
"[ERROR] The headers span outside the image: 0x%08x\n", minSection);
153 if (VirtualImageSize < minSection)
155 ERROR(
"[ERROR] The first section starts beyond the end of the image!: 0x%08x\n", minSection);
159 memcpy(VirtualImage, RawImage, minSection);
162 for (i = 0; i < NumberOfSections; i++)
165 if ((RawImageSize < Sections[i].PointerToRawData + Sections[i].SizeOfRawData) ||
166 (RawImageSize < Sections[i].SizeOfRawData) ||
167 (RawImageSize <= Sections[i].PointerToRawData))
169 ERROR(
"[ERROR] Section %d at 0x%08x:0x%08x overflows the raw image!\n",
170 i, Sections[i].PointerToRawData, Sections[i].SizeOfRawData);
175 if ((VirtualImageSize < Sections[i].VirtualAddress + Sections[i].Misc.VirtualSize) ||
176 (VirtualImageSize < Sections[i].Misc.VirtualSize) ||
177 (VirtualImageSize <= Sections[i].VirtualAddress))
179 ERROR(
"[ERROR] Section %d at 0x%08x:0x%08x overflows the virtual image!\n",
180 i, Sections[i].VirtualAddress, Sections[i].Misc.VirtualSize);
184 if (VirtualImage + Sections[i].VirtualAddress + Sections[i].SizeOfRawData > VirtualImage + VirtualImageSize)
186 ERROR(
"[ERROR] Section %d does not fit inside the virtual image [%p, %p): " 187 "va = 0x%08x raw data size = 0x%08x\n", i, VirtualImage, VirtualImage + VirtualImageSize,
188 Sections[i].VirtualAddress, Sections[i].SizeOfRawData);
192 if (RawImage + Sections[i].PointerToRawData + Sections[i].SizeOfRawData > RawImage + RawImageSize)
194 ERROR(
"[ERROR] Section %d does not fit inside the raw image [%p, %p): " 195 "pointer to raw data = 0x%08x raw data size = 0x%08x\n", i, RawImage, RawImage + RawImageSize,
196 Sections[i].PointerToRawData, Sections[i].SizeOfRawData);
201 memcpy(VirtualImage + Sections[i].VirtualAddress,
202 RawImage + Sections[i].PointerToRawData,
203 Sections[i].SizeOfRawData);
232 QWORD relocRva, relocSize;
234 if (NULL == VirtualImage)
239 if (NULL == BaseRelocations)
247 relocRva = BaseRelocations->VirtualAddress;
248 relocSize = BaseRelocations->Size;
251 if ((0 == relocRva ) || (0 == relocSize))
259 if ((VirtualImageSize <= relocRva) || (VirtualImageSize < relocSize) || (VirtualImageSize < relocRva + relocSize))
290 if (VirtualImageSize < relocRva + i + reloc.
SizeOfBlock)
305 WARNING(
"Invalid relocation for RVA 0x%016llxx: SizeOfBlock is: 0x%08x\n", relocRva, reloc.
SizeOfBlock);
318 WORD desc, type, offset;
322 type = (desc >> 12) & 0xF;
324 offset = desc & 0xFFF;
326 TRACE(
"[LOADER] -> Relocationg offset 0x%08x of type %d...\n", offset, type);
386 QWORD importsRva, importsSize, i;
388 if (NULL == VirtualImage)
393 if (NULL == ImportTable)
401 importsRva = ImportTable->VirtualAddress;
402 importsSize = ImportTable->Size;
405 if ((0 == importsRva) || (0 == importsSize))
411 if ((VirtualImageSize < importsRva) || (VirtualImageSize < importsRva + importsSize))
428 QWORD modBase, namesBase, iatBase, count;
434 if (pImpDesc->
Name >= VirtualImageSize)
436 ERROR(
"[ERROR] Import name outside the image: 0x%08x\n", pImpDesc->
Name);
441 modName = (
char *)(VirtualImage + pImpDesc->
Name);
443 len = strnlen(modName, VirtualImageSize - pImpDesc->
Name);
446 if (len >= 512 || len >= VirtualImageSize - pImpDesc->
Name)
453 if (NULL == wModuleName)
462 wModuleName[j] = modName[j];
467 TRACE(
"[LOADER] Fixing imports for imported library %s...\n", modName);
469 if (0 == strcmp(modName,
"ntoskrnl.exe"))
474 ERROR(
"[ERROR] IntWinDriverFindByLoadOrder failed for %s\n", modName);
479 modBase = pDriver->
BaseVa;
481 else if (0 == strcmp(modName,
"hal.dll"))
486 ERROR(
"[ERROR] IntWinDriverFindByLoadOrder failed for %s\n", modName);
491 modBase = pDriver->
BaseVa;
498 ERROR(
"[ERROR] IntWinDriverFindByName failed for %s\n", modName);
503 modBase = pDriver->
BaseVa;
531 while ((namesBase + count * 4 + 4 <= VirtualImageSize) && (iatBase + count * 4 + 4 <= VirtualImageSize) &&
540 if ((VirtualImageSize < *names32) && (0 == (*names32 & 0x80000000)))
546 if (0 != (*names32 & 0x80000000))
566 while ((*names32 + 2 + l < VirtualImageSize) && (pImpName->
Name[l] != 0))
571 if (*names32 + 2 + l >= VirtualImageSize)
579 ERROR(
"[ERROR] IntPeFindExportByName failed: 0x%08x\n", status);
582 impAddr = (
DWORD)modBase + rva;
596 while ((namesBase + count * 8 + 8 <= VirtualImageSize) && (iatBase + count * 8 + 8 <= VirtualImageSize) &&
605 if ((VirtualImageSize < *names64) && (0 == (*names64 & 0x8000000000000000ULL)))
611 if (0 != (*names64 & 0x8000000000000000ULL))
630 while ((*names64 + 2 + k < VirtualImageSize) && (pImpName->
Name[k] != 0))
635 if (*names64 + 2 + k >= VirtualImageSize)
643 ERROR(
"[ERROR] IntPeFindExportByName failed: 0x%08x\n", status);
646 impAddr = modBase + rva;
711 if (NULL == LoadedPe)
719 ERROR(
"[ERROR] IntPeValidateHeader failed: 0x%08x\n", status);
723 TRACE(
"[LOADER] Preparing image for execution...\n");
743 ERROR(
"[ERROR] IntLdrPreLoadImage failed: 0x%08x\n", status);
751 delta = GuestVirtualAddress - peInfo.
ImageBase;
756 ERROR(
"[ERROR] IntPeGetDirectory failed: 0x%08x\n", status);
762 ERROR(
"[ERROR] IntLdrFixRelocations failed: 0x%08x\n", status);
773 ERROR(
"[ERROR] IntPeGetDirectory failed: 0x%08x\n", status);
779 ERROR(
"[ERROR] IntLdrFixImports failed: 0x%08x\n", status);
800 ERROR(
"[ERROR] IntLdrPreLoadImage failed: 0x%08x\n", status);
808 delta = GuestVirtualAddress - peInfo.
ImageBase;
813 ERROR(
"[ERROR] IntPeGetDirectory failed: 0x%08x\n", status);
819 ERROR(
"[ERROR] IntLdrFixRelocations failed: 0x%08x\n", status);
830 ERROR(
"[ERROR] IntPeGetDirectory failed: 0x%08x\n", status);
836 ERROR(
"[ERROR] IntLdrFixImports failed: 0x%08x\n", status);
842 ERROR(
"[ERROR] Unsupported machine type: %d\n", peInfo.
Machine);
847 TRACE(
"[LOADER] The image should be loaded & prepared for execution!\n");
KERNEL_DRIVER * IntDriverFindByLoadOrder(DWORD LoadOrder)
Searches a driver by its module load order.
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
INTSTATUS IntPeGetDirectory(QWORD ImageBase, BYTE *ImageBaseBuffer, DWORD DirectoryEntry, IMAGE_DATA_DIRECTORY *Directory)
Validate & return the indicated image data directory.
#define LDR_FLAG_FIX_RELOCATIONS
If flag is set, the relocations will be applied.
#define INT_STATUS_SUCCESS
#define IMAGE_SUBSYSTEM_NATIVE
#define IMAGE_FILE_MACHINE_I386
static INTSTATUS IntLdrFixRelocations(PBYTE VirtualImage, DWORD VirtualImageSize, QWORD Delta, PIMAGE_DATA_DIRECTORY BaseRelocations)
This function will parse the relocations of the PE and apply them where needed.
#define IMAGE_REL_BASED_HIGHLOW
INTSTATUS IntPeFindExportByName(QWORD ImageBase, BYTE *ImageBaseBuffer, CHAR *Name, DWORD *ExportRva)
Find the export name a Rva lies in.
QWORD BaseVa
The guest virtual address of the kernel module that owns this driver object.
#define INT_SUCCESS(Status)
QWORD SectionOffset
Offset of the first section header.
#define HpAllocWithTag(Len, Tag)
int INTSTATUS
The status data type.
#define INT_STATUS_NOT_FOUND
#define LDR_FLAG_FIX_IMPORTS
If flag is set, the imports will be fixed.
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
Describes a kernel driver.
KERNEL_DRIVER * IntDriverFindByName(const void *Name)
Searches for a driver by its name.
static INTSTATUS IntLdrFixImports(PBYTE VirtualImage, DWORD VirtualImageSize, BOOLEAN Is64, PIMAGE_DATA_DIRECTORY ImportTable)
Fix the imports of the provided PE image.
union _IMAGE_IMPORT_DESCRIPTOR::@223 u
INTSTATUS IntLdrGetImageSizeAndEntryPoint(PBYTE RawPe, DWORD RawSize, DWORD *VirtualSize, DWORD *EntryPoint)
Returns the entry point and the virtual size for the provided module.
#define IMAGE_REL_BASED_ABSOLUTE
WORD Machine
Machine type.
IMAGE_IMPORT_DESCRIPTOR * PIMAGE_IMPORT_DESCRIPTOR
#define INT_STATUS_INVALID_PARAMETER_4
static INTSTATUS IntLdrPreLoadImage(PBYTE RawImage, DWORD RawImageSize, PBYTE VirtualImage, DWORD VirtualImageSize, DWORD NumberOfSections, PIMAGE_SECTION_HEADER Sections)
Pre-load the given raw PE image at the indicated virtual address.
QWORD NumberOfSections
Number of sections.
#define HpFreeAndNullWithTag(Add, Tag)
#define IMAGE_FILE_MACHINE_AMD64
#define IMAGE_REL_BASED_DIR64
INTSTATUS IntLdrLoadPEImage(PBYTE RawPe, DWORD RawPeSize, QWORD GuestVirtualAddress, PBYTE LoadedPe, DWORD VirtualPeSize, DWORD Flags)
Load the provided PE image at the provided guest virtual address, and return it in LoadedPe...
DWORD EntryPoint
Entry point (RVA).
INTSTATUS IntPeValidateHeader(QWORD ImageBase, BYTE *ImageBaseBuffer, DWORD ImageBaseBufferSize, INTRO_PE_INFO *PeInfo, QWORD Cr3)
Validates a PE header.
#define INT_STATUS_INVALID_PARAMETER_6
#define INT_STATUS_INVALID_OBJECT_TYPE
QWORD ImageBase
Image base.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA
struct _IMAGE_SECTION_HEADER * PIMAGE_SECTION_HEADER
IMAGE_BASE_RELOCATION * PIMAGE_BASE_RELOCATION
#define INT_STATUS_INVALID_PARAMETER_1
#define INT_STATUS_NOT_SUPPORTED
UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]
DWORD SizeOfImage
Size of the image.
#define IMAGE_DIRECTORY_ENTRY_IMPORT
#define INT_STATUS_INSUFFICIENT_RESOURCES
#define INT_STATUS_INVALID_PARAMETER_3