自己正在学习PE结构,用文件目录下得Notepad.exe来练手,想给它注册下一个自己的dll。但是我在打印导入表的时候出现了问题,大家帮忙看下,谢谢各位。
我自己的代码如下:
int main()
{
//PrintNTHeaders();
//PrintExportTable();
PrintImportTable();
system("pause");
return 0;
}
size_t RVAToOffset(size_t stRVA, PVOID lpFileBuf)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpFileBuf;
size_t stPEHeadAddr = (size_t)lpFileBuf + pDos->e_lfanew;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)stPEHeadAddr;
//区段数
DWORD dwSectionCount = pNt->FileHeader.NumberOfSections;
//内存对齐大小
DWORD dwMemoruAil = pNt->OptionalHeader.SectionAlignment;
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNt);
//距离命中节的起始虚拟地址偏移
DWORD dwDiffer = 0;
for (DWORD i = 0;i < dwSectionCount;i++)
{
//模拟内存对齐机制
DWORD dwBlockCount = pSection[i].SizeOfRawData / dwMemoruAil;
dwBlockCount += pSection[i].SizeOfRawData % dwMemoruAil ? 1 : 0; //判断取整之后是否还有剩余,有则加1
DWORD dwBeginVA = pSection[i].VirtualAddress;
DWORD dwEndVA = pSection[i].VirtualAddress + dwBlockCount*dwMemoruAil;
//如果在stRVA在某个区段中
if (stRVA >= dwBeginVA && stRVA < dwEndVA)
{
dwDiffer = stRVA - dwBeginVA;
return pSection[i].PointerToRawData + dwDiffer;
}
else if(stRVA < dwBeginVA) //在文件头中直接返回
{
return stRVA;
}
}
return stRVA;
}
VOID PrintImportTable()
{
LPVOID pFileBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOpHeader = NULL;
ULONG Rva_OfImportTable = 0;
pFileBuffer = ReadFileINBuf(PATH);
if (!pFileBuffer)
{
printf("文件读取失败!\n");
return;
}
//判断是否是有效的MZ标志
if (*(PWORD(pFileBuffer)) != IMAGE_DOS_SIGNATURE)
{
printf("不是有效得MZ标志\n");
free(pFileBuffer);
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
pOpHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)(PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4) + IMAGE_SIZEOF_FILE_HEADER);
DWORD dwImage = pOpHeader->ImageBase;
Rva_OfImportTable = pOpHeader->DataDirectory[1].VirtualAddress;//导入表RVA
ULONG FOA_OfImportTable = RVAToOffset(Rva_OfImportTable, pFileBuffer); //导入表FOA
if (FOA_OfImportTable == 0)
{
printf("没有导入表\n");
}
else
{
//打印第一个Dll名称
PIMAGE_IMPORT_DESCRIPTOR pImageTable = (PIMAGE_IMPORT_DESCRIPTOR)FOA_OfImportTable;
DWORD dwName = pImageTable->Name; //存放第一个名字的地址
}
return;
}
按照上述代码运行后,dwName的值为0x000094A0
内存如下:
0x000094A0 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ................
0x000094B0 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ................
0x000094C0 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ................
引发了异常: 读取访问权限冲突。
pImageTable 是 0x94A0
是我哪里代码写错了还是有什么概念没有搞清?
各路大神帮忙支个招!!!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!