mirror-ac/driver/pe.c
donnaskiez 197796d004 format
2024-08-01 14:21:53 +10:00

137 lines
No EOL
3.1 KiB
C

#include "pe.h"
#include "lib/stdlib.h"
PNT_HEADER_64
PeGetNtHeaderSafe(_In_ PVOID Image)
{
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)Image;
if (!MmIsAddressValid(Image))
return NULL;
if (dos->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
return RVA(PNT_HEADER_64, Image, dos->e_lfanew);
}
PNT_HEADER_64
PeGetNtHeader(_In_ PVOID Image)
{
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)Image;
if (dos->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
return RVA(PNT_HEADER_64, Image, dos->e_lfanew);
}
PIMAGE_DATA_DIRECTORY
PeGetExportDataDirectory(_In_ PVOID Image)
{
PNT_HEADER_64 nt = PeGetNtHeader(Image);
if (IMAGE_DIRECTORY_ENTRY_EXPORT >= nt->OptionalHeader.NumberOfRvaAndSizes)
return NULL;
return (PIMAGE_DATA_DIRECTORY)&nt->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
}
PIMAGE_DATA_DIRECTORY
PeGetExportDataDirectorySafe(_In_ PVOID Image)
{
PNT_HEADER_64 nt = PeGetNtHeader(Image);
if (!MmIsAddressValid(Image))
return NULL;
if (IMAGE_DIRECTORY_ENTRY_EXPORT >= nt->OptionalHeader.NumberOfRvaAndSizes)
return NULL;
return (PIMAGE_DATA_DIRECTORY)&nt->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
}
PIMAGE_EXPORT_DIRECTORY
PeGetExportDirectory(
_In_ PVOID Image, _In_ PIMAGE_DATA_DIRECTORY ExportDataDirectory)
{
if (!ExportDataDirectory->VirtualAddress || !ExportDataDirectory->Size)
return NULL;
return RVA(
PIMAGE_EXPORT_DIRECTORY,
Image,
ExportDataDirectory->VirtualAddress);
}
PIMAGE_EXPORT_DIRECTORY
PeGetExportDirectorySafe(
_In_ PVOID Image, _In_ PIMAGE_DATA_DIRECTORY ExportDataDirectory)
{
if (!MmIsAddressValid(Image))
return NULL;
if (!ExportDataDirectory->VirtualAddress || !ExportDataDirectory->Size)
return NULL;
return RVA(
PIMAGE_EXPORT_DIRECTORY,
Image,
ExportDataDirectory->VirtualAddress);
}
UINT32
GetSectionCount(_In_ PNT_HEADER_64 Header)
{
return Header->FileHeader.NumberOfSections;
}
UINT32
GetSectionCountSafe(_In_ PNT_HEADER_64 Header)
{
if (!MmIsAddressValid(Header))
return NULL;
return Header->FileHeader.NumberOfSections;
}
PVOID
PeFindExportByName(_In_ PVOID Image, _In_ PCHAR Name)
{
ANSI_STRING target = {0};
PNT_HEADER_64 nt = NULL;
PIMAGE_DATA_DIRECTORY data = NULL;
PIMAGE_EXPORT_DIRECTORY export = NULL;
RtlInitAnsiString(&target, Name);
nt = PeGetNtHeader(Image);
if (!nt)
return NULL;
data = PeGetExportDataDirectory(Image);
if (!data)
return NULL;
export = PeGetExportDirectory(Image, data);
if (!export)
return NULL;
PUINT32 functions = RVA(PUINT32, Image, export->AddressOfFunctions);
PUINT32 names = RVA(PUINT32, Image, export->AddressOfNames);
PUINT16 ordinals = RVA(PUINT16, Image, export->AddressOfNameOrdinals);
for (UINT32 index = 0; index < export->NumberOfNames; index++) {
PCHAR export = RVA(PCHAR, Image, names[index]);
if (!IntCompareString(Name, export))
return RVA(PVOID, Image, functions[ordinals[index]]);
}
return NULL;
}