C语言编写控制台下PE分析工具(三)

七、获取输出表信息

1、获取数据目录中元素的入口
LPVOID GetDirectoryEntryToData(LPVOID ImageBase, USHORT DirectoryEntry)
{
DWORD dwDataStartRVA;
PIMAGE_NT_HEADERS pNtH = nullptr;
PIMAGE_OPTIONAL_HEADER pOH = nullptr;
LPVOID pData = nullptr;
pNtH = GetNtHeaders(ImageBase);
if (!pNtH)
{
return nullptr;
}

pOH = GetOptionalHeader(ImageBase);
if (!pOH)
{
return nullptr;
}

dwDataStartRVA = pOH->DataDirectory[DirectoryEntry].VirtualAddress;
pData = ImageRvaToVa(pNtH, ImageBase, dwDataStartRVA, NULL);    
if (!pData)
{
return nullptr;
}
return pData;
}

其中,  ImageRvaToVa()用于从相对虚拟地址向磁盘地址的转换,返回一个指向磁盘地址的指针。这个函数定义在imagehlp.h中,使用时需要手动引用imagehlp.lib:

#include <imagehlp.h>
#pragma comment ( lib, "imagehlp.lib" ) 


2、获取输出表在磁盘文件中的位置

PIMAGE_EXPORT_DIRECTORY GetExportDirectory(LPVOID ImageBase)
{
if (!ImageBase)
{
return nullptr;
}

PIMAGE_EXPORT_DIRECTORY pED = (PIMAGE_EXPORT_DIRECTORY)GetDirectoryEntryToData(ImageBase, IMAGE_DIRECTORY_ENTRY_EXPORT);
if (!pED)
{
return nullptr;
}


return pED;
}


3、获取输出表信息

void ShowExportDirectory(PMAP_FILE_STRUCT stMapFile)
{
char data[9][48] = {
"Characteristics:            ",
"TimeDateStamp:              ",
"Name:                       ",
"Base:                       ",
"NumberOfFunctions:          ",
"NumberOfNames:              ",
"AddressOfFunctions:         ",
"AddressOfNames:             ",
"AddressOfNameOrdinals:      "
};

PIMAGE_EXPORT_DIRECTORY pED = GetExportDirectory(stMapFile->ImageBase);
if (!pED)
{
printf("Can't get Export Table\n");
return;
}
char *szName = nullptr;
szName = (char *)ImageRvaToVa(GetNtHeaders(stMapFile->ImageBase), stMapFile->ImageBase, pED->Name, NULL);

//时间转换
time_t t = pED->TimeDateStamp;
char strTime[26] = { 0 };
tm* ptmBegin = localtime(&t);
strftime(strTime, 26, "%Y/%m/%d %H:%M:%S", ptmBegin);

printf("\n\n[Export Table]\n");
printf("%s %08lX\n", data[0], pED->Characteristics);
printf("%s %08lX (%s)\n", data[1], pED->TimeDateStamp, strTime);
printf("%s %08lX (%s)\n", data[2], pED->Name, szName);
printf("%s %08lX\n", data[3], pED->Base);
printf("%s %08lX\n", data[4], pED->NumberOfFunctions);
printf("%s %08lX\n", data[5], pED->NumberOfNames);
printf("%s %08lX\n", data[6], pED->AddressOfFunctions);
printf("%s %08lX\n", data[7], pED->AddressOfNames);
printf("%s %08lX\n", data[8], pED->AddressOfNameOrdinals);
}

结果如图所示:



4、获取输出函数:

void  ShowExportFuncsInfo(LPVOID ImageBase)
{
if (!ImageBase)
{
return;
}
UINT iNumOfName = 0;
PDWORD pdwFuncs = nullptr;
PDWORD pdwNames = nullptr;
PWORD  pwOrds = nullptr;
bool bIsByName = false;
PIMAGE_NT_HEADERS pNtH = nullptr;
PIMAGE_EXPORT_DIRECTORY pED = nullptr;
char cBuff[10] = { 0 };
char *szFuncName = nullptr;
pNtH = GetNtHeaders(ImageBase);
if (!pNtH)
{
return;
}


pED = GetExportDirectory(ImageBase);
if (!pED)
{
return;
}


iNumOfName = pED->NumberOfNames;
pwOrds = (PWORD)ImageRvaToVa(pNtH, ImageBase, pED->AddressOfNameOrdinals, NULL);
pdwFuncs = (PDWORD)ImageRvaToVa(pNtH, ImageBase, pED->AddressOfFunctions, NULL);


pdwNames = (PDWORD)ImageRvaToVa(pNtH, ImageBase, pED->AddressOfNames, NULL);
if (!pdwFuncs)
{
return;
}



printf("\n\nOrdinal     RVA          Function Name\n");

for (UINT i = 0; i < pED->NumberOfFunctions; i++)
{
if (pdwFuncs[i])
{
for (UINT j = 0; j < iNumOfName; j++)
{
if (i == pwOrds[j])
{
bIsByName = true;
szFuncName = (char *)ImageRvaToVa(pNtH, ImageBase, pdwNames[i], NULL);
break;
}
bIsByName = false;
}
printf("%04lX       %08lX      %s\n", (UINT)(pED->Base + i), pdwFuncs[i], szFuncName);
}
}
}


结果如图所示:


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值