1、ImageNtHeader,IsBadReadPtr是我自己加的
PIMAGE_NT_HEADERS32 WINAPI ImageNtHeader(PVOID Base)
{
PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)Base;
if (IsBadReadPtr(pDosHdr, sizeof(IMAGE_DOS_HEADER)))
return NULL;
if (IMAGE_DOS_SIGNATURE != pDosHdr->e_magic)
return NULL;
PIMAGE_NT_HEADERS32 pNTHdr32 = (PIMAGE_NT_HEADERS32)((PBYTE)pDosHdr + pDosHdr->e_lfanew);
if (IsBadReadPtr(pNTHdr32, sizeof(IMAGE_NT_HEADERS32)))
return FALSE;
if (IMAGE_NT_SIGNATURE != pNTHdr32->Signature)
return FALSE;
return pNTHdr32;
}
2、ImageDirectoryEntryToDataEx,没Ex的懒得弄了直接把最后一个参数填0调用Ex
PVOID ImageDirectoryEntryToData32(ULONG_PTR BaseAddress, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size, PIMAGE_SECTION_HEADER *FoundHeader, PIMAGE_FILE_HEADER pFileHdr, PIMAGE_OPTIONAL_HEADER32 pOptHdr)
{
if (DirectoryEntry < pOptHdr->NumberOfRvaAndSizes)
{
ULONG_PTR Rva = pOptHdr->DataDirectory[DirectoryEntry].VirtualAddress;
if (Rva)
{
*Size = pOptHdr->DataDirectory[DirectoryEntry].Size;
if (!MappedAsImage && Rva >= pOptHdr->SizeOfHeaders)
{
int NumSections = pFileHdr->NumberOfSections;
PIMAGE_SECTION_HEADER pSecHdr = (PIMAGE_SECTION_HEADER)((PUCHAR)pOptHdr + pFileHdr->SizeOfOptionalHeader);
for (int i = 0; i < NumSections; ++i)
{
if (Rva >= pSecHdr->VirtualAddress && Rva < pSecHdr->SizeOfRawData + pSecHdr->VirtualAddress)
{
if (FoundHeader)
*FoundHeader = pSecHdr;
return (PVOID)(BaseAddress + (Rva - pSecHdr->VirtualAddress) + pSecHdr->PointerToRawData);
}
++pSecHdr;
}
return NULL;
}
if (FoundHeader)
*FoundHeader = NULL;
return (PVOID)(BaseAddress + Rva);
}
}
*Size = 0;
return NULL;
}
PVOID ImageDirectoryEntryToData64(ULONG_PTR BaseAddress, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size, PIMAGE_SECTION_HEADER *FoundHeader, PIMAGE_FILE_HEADER pFileHdr, PIMAGE_OPTIONAL_HEADER64 pOptHdr)
{
if (DirectoryEntry < pOptHdr->NumberOfRvaAndSizes)
{
ULONG_PTR Rva = pOptHdr->DataDirectory[DirectoryEntry].VirtualAddress;
if (Rva)
{
*Size = pOptHdr->DataDirectory[DirectoryEntry].Size;
if (!MappedAsImage && Rva >= pOptHdr->SizeOfHeaders)
{
int NumSections = pFileHdr->NumberOfSections;
PIMAGE_SECTION_HEADER pSecHdr = (PIMAGE_SECTION_HEADER)((PUCHAR)pOptHdr + pFileHdr->SizeOfOptionalHeader);
for (int i = 0; i < NumSections; ++i)
{
if (Rva >= pSecHdr->VirtualAddress && Rva < pSecHdr->SizeOfRawData + pSecHdr->VirtualAddress)
{
if (FoundHeader)
*FoundHeader = pSecHdr;
return (PVOID)(BaseAddress + (Rva - pSecHdr->VirtualAddress) + pSecHdr->PointerToRawData);
}
++pSecHdr;
}
return NULL;
}
if (FoundHeader)
*FoundHeader = NULL;
return (PVOID)(BaseAddress + Rva);
}
}
*Size = 0;
return NULL;
}
PVOID ImageDirectoryEntryToDataRom(ULONG_PTR BaseAddress, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size, PIMAGE_SECTION_HEADER *FoundHeader, PIMAGE_FILE_HEADER pFileHdr, PIMAGE_ROM_OPTIONAL_HEADER pOptHdr)
{
int NumSections = pFileHdr->NumberOfSections;
PIMAGE_SECTION_HEADER pSecHdr = (PIMAGE_SECTION_HEADER)((PUCHAR)pOptHdr + pFileHdr->SizeOfOptionalHeader);
for (int i = 0; i < NumSections; ++i)
{
if (DirectoryEntry == 6 && !_stricmp((const char *)pSecHdr->Name, ".rdata"))
{
*Size = 0;
for (ULONG_PTR j = (ULONG_PTR)((PUCHAR)BaseAddress + pSecHdr->PointerToRawData + 12); *(DWORD *)j; j += 28)
*Size += 28;
if (FoundHeader)
*FoundHeader = pSecHdr;
return (PVOID)(BaseAddress + pSecHdr->PointerToRawData);
}
if (DirectoryEntry == 3 && !_stricmp((const char *)pSecHdr->Name, ".pdata"))
{
if (FoundHeader)
*FoundHeader = pSecHdr;
return (PVOID)(BaseAddress + pSecHdr->PointerToRawData);
}
++pSecHdr;
}
*Size = 0;
return NULL;
}
PVOID WINAPI ImageDirectoryEntryToDataEx(PVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size, PIMAGE_SECTION_HEADER *FoundHeader)
{
ULONG_PTR BaseAddress = (ULONG_PTR)Base;
if (!BaseAddress)
{
SetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
if (BaseAddress & 1)
{
BaseAddress = BaseAddress & 0xFFFFFFFFFFFFFFFE;
MappedAsImage = FALSE;
}
PIMAGE_NT_HEADERS32 pNtHdr32 = ImageNtHeader(Base);
PIMAGE_FILE_HEADER pFileHdr;
PIMAGE_OPTIONAL_HEADER32 pOptHdr;
if (pNtHdr32)
{
pFileHdr = &pNtHdr32->FileHeader;
pOptHdr = &pNtHdr32->OptionalHeader;
}
else
{
pFileHdr = (PIMAGE_FILE_HEADER)BaseAddress;
pOptHdr = (PIMAGE_OPTIONAL_HEADER32)(BaseAddress + sizeof(IMAGE_FILE_HEADER));
}
if (pOptHdr->Magic == 267)
{
return ImageDirectoryEntryToData32(BaseAddress, MappedAsImage, DirectoryEntry, Size, FoundHeader, pFileHdr, pOptHdr);
}
if (pOptHdr->Magic == 523)
{
PIMAGE_OPTIONAL_HEADER64 pOptHdr64 = (PIMAGE_OPTIONAL_HEADER64)pOptHdr;
return ImageDirectoryEntryToData64(BaseAddress, MappedAsImage, DirectoryEntry, Size, FoundHeader, pFileHdr, pOptHdr64);
}
if (pOptHdr->Magic == 263)
{
PIMAGE_ROM_OPTIONAL_HEADER pOptHdrRom = (PIMAGE_ROM_OPTIONAL_HEADER)pOptHdr;
return ImageDirectoryEntryToDataRom(BaseAddress, MappedAsImage, DirectoryEntry, Size, FoundHeader, pFileHdr, pOptHdrRom);
}
*Size = 0;
return NULL;
}
3、ImageRvaToVa
PIMAGE_SECTION_HEADER WINAPI ImageRvaToSection(PIMAGE_NT_HEADERS NtHeaders, PVOID Base, ULONG Rva)
{
if (!NtHeaders)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0i64;
}
PIMAGE_SECTION_HEADER pSecHdr = (PIMAGE_SECTION_HEADER)((PUCHAR)&NtHeaders->OptionalHeader + NtHeaders->FileHeader.SizeOfOptionalHeader);
int NumSections = NtHeaders->FileHeader.NumberOfSections;
for(int i = 0;i < NumSections; ++i)
{
if (Rva >= pSecHdr->VirtualAddress && Rva < pSecHdr->SizeOfRawData + pSecHdr->VirtualAddress)
{
(PIMAGE_SECTION_HEADER)pSecHdr;
}
}
return NULL;
}
PVOID WINAPI ImageRvaToVa(PIMAGE_NT_HEADERS NtHeaders, PVOID Base, ULONG Rva, PIMAGE_SECTION_HEADER *LastRvaSection)
{
PIMAGE_SECTION_HEADER pSecHdr;
if (!LastRvaSection)
{
pSecHdr = ImageRvaToSection(NtHeaders, Base, Rva);
}
else
{
pSecHdr = *LastRvaSection;
if (!pSecHdr || !(Rva >= pSecHdr->VirtualAddress && Rva < pSecHdr->VirtualAddress + pSecHdr->SizeOfRawData))
pSecHdr = ImageRvaToSection(NtHeaders, Base, Rva);
}
if (pSecHdr)
{
if (LastRvaSection)
*LastRvaSection = pSecHdr;
return (PUCHAR)Base + Rva - pSecHdr->VirtualAddress + pSecHdr->PointerToRawData;
}
return NULL;
}