首先,我们需要找到包含指定内存地址的映像的基地址。这可以通过RtlPcToFileHeader函数来完成。
然后我们需要通过说ImageDirectoryEntryToData从Dbghelp.dll或通过RtlImageDirectoryEntryToData从ntdll.dll获取它的导出目录并枚举所有导出函数。先看名字。如果没有此类地址的名称 - 查找序号。
void FromAddress(LPCVOID Address)
{
PVOID BaseOfImage = RtlPcToFileHeader(Address, &BaseOfImage);
if (!BaseOfImage)
{
return;
}
ULONG Size;
PIMAGE_EXPORT_DIRECTORY pied = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData(BaseOfImage, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &Size);
ULONG NumberOfFunctions, NumberOfNames;
if (!pied || !(NumberOfFunctions = pied->NumberOfFunctions))
{
return;
}
NumberOfNames = pied->NumberOfNames;
PULONG AddressOfFunctions = (PULONG)RtlOffsetToPointer(BaseOfImage, pied->AddressOfFunctions);
PULONG AddressOfNames = (PULONG)RtlOffsetToPointer(BaseOfImage, pied->AddressOfNames);
PUSHORT AddressOfNameOrdinals = (PUSHORT)RtlOffsetToPointer(BaseOfImage, pied->AddressOfNameOrdinals);
bool bFound = false;
if (NumberOfNames)
{
do
{
ULONG rva = *AddressOfNames++;
if (RtlOffsetToPointer(BaseOfImage, AddressOfFunctions[*AddressOfNameOrdinals++]) == Address)
{
DbgPrint("%s\n", RtlOffsetToPointer(BaseOfImage, rva));
bFound = true;
}
} while (--NumberOfNames);
}
if (!bFound)
{
DWORD Base = pied->Base;
do
{
if (Address == RtlOffsetToPointer(BaseOfImage, *AddressOfFunctions++))
{
DbgPrint("#%u\n", Base);
}
} while (Base++, --NumberOfFunctions);
}
}