PE文件常用数据目录遍历方法
说明:AppendStrData(char *):向RichEdit添加字符串
AppendSectionData(char *,RGB):向RichEdit添加有颜色的字符串
导入表:
void GetImportTable() { AppendSectionData("\n导入表:\r\n",RGB(00,0xBB,0)); if (pNtHeader->OptionalHeader.DataDirectory[1].VirtualAddress){ pImportDes=(IMAGE_IMPORT_DESCRIPTOR *)((BYTE *)lpBase + RVAToOffset(pNtHeader->OptionalHeader.DataDirectory[1].VirtualAddress)); while (pImportDes->Name) { char *dllname=(char *)((BYTE*)lpBase+RVAToOffset(pImportDes->Name)); AppendStrData("\t"); AppendSectionData(dllname,RGB(0,0,0xC6)); AppendStrData("\n\t-------------\n"); if (pImportDes->OriginalFirstThunk) pThunkData=(IMAGE_THUNK_DATA *)((BYTE *)lpBase + RVAToOffset(pImportDes->OriginalFirstThunk)); else pThunkData=(IMAGE_THUNK_DATA *)((BYTE *)lpBase + RVAToOffset(pImportDes->FirstThunk)); while (pThunkData->u1.Ordinal) { pImportByName=(IMAGE_IMPORT_BY_NAME *)((BYTE *)lpBase + RVAToOffset((DWORD)pThunkData->u1.AddressOfData)); if (!(pThunkData->u1.Ordinal&0x80000000)){ sprintf(szBuf,"\t0x%04X\t%-s\n",pImportByName->Hint,pImportByName->Name); } else{ sprintf(szBuf,"\t0x%04X\t(ImportByHint)\n",pThunkData->u1.Ordinal&0x0FFFFFFF); } AppendStrData(szBuf); pThunkData++; } AppendStrData("\r\n"); pImportDes++; } }else{ AppendStrData("无"); } }
导出表:
void GetExportTable() { AppendSectionData("导出表:\r\n",RGB(00,0xBB,0)); if(pNtHeader->OptionalHeader.DataDirectory[0].VirtualAddress) { DWORD NumOfFunc=0,NumOfFuncName=0; pExportDir=(IMAGE_EXPORT_DIRECTORY *)((BYTE *)lpBase + RVAToOffset(pNtHeader->OptionalHeader.DataDirectory[0].VirtualAddress)); AppendStrData("\t原始名称:\t"); AppendStrData((char *)((BYTE *)lpBase + RVAToOffset(pExportDir->Name))); NumOfFunc=(DWORD)pExportDir->NumberOfFunctions; NumOfFuncName=(DWORD)pExportDir->NumberOfNames; AppendStrData("\r\n\t函数个数:\t"); AppendHexData((LPVOID)NumOfFunc); AppendStrData("\r\n\tExportByName:\t"); AppendHexData((LPVOID)NumOfFuncName); AppendStrData("\r\n\t----------------------------\n\tHINT\tAddr\t\tName\r\n\n"); for (DWORD i=0;i<NumOfFuncName;i++) { sprintf(szBuf,"\t0x%04X\t0x%08X\t%s\n", LOWORD(*(DWORD *)((BYTE *)lpBase + RVAToOffset(pExportDir->AddressOfNameOrdinals)+i*2)), *(DWORD *)((BYTE *)lpBase + RVAToOffset(pExportDir->AddressOfFunctions) + i*4), (char *)((BYTE *)lpBase + RVAToOffset(*(DWORD *)((BYTE *)lpBase + RVAToOffset(pExportDir->AddressOfNames) + i*4))) ); AppendStrData(szBuf); } }else{ AppendStrData("\t无\r\n\r\n"); } }
资源表:
IMAGE_RESOURCE_DIRECTORY *pResHead1,*pResHead2,*pResHead3; IMAGE_RESOURCE_DIRECTORY_ENTRY *pResDirEntry1,*pResDirEntry2,*pResDirEntry3; IMAGE_RESOURCE_DIRECTORY_STRING *pResDir1Str,*pResDir2Str; IMAGE_RESOURCE_DATA_ENTRY *pResDataEntry; void GetResTable() { int NumOfIdEntries,NumOfNamedEntries; char *buffer; AppendSectionData("\n资源表结构:\r\n",RGB(00,0xBB,0)); if (!pNtHeader->OptionalHeader.DataDirectory[2].VirtualAddress) { AppendStrData("\t无\r\n"); return; } pResHead1=(IMAGE_RESOURCE_DIRECTORY *)((BYTE *)lpBase + RVAToOffset(pNtHeader->OptionalHeader.DataDirectory[2].VirtualAddress)); pResDirEntry1=(IMAGE_RESOURCE_DIRECTORY_ENTRY *)((DWORD)pResHead1 + sizeof(*pResHead1)); NumOfIdEntries=pResHead1->NumberOfIdEntries; NumOfNamedEntries=pResHead1->NumberOfNamedEntries; for (int i=0;i<NumOfIdEntries+NumOfNamedEntries;i++) { if (pResDirEntry1->NameIsString==0) { switch (pResDirEntry1->Name) { case 1:buffer="\t|----光标\r\n";break; case 2:buffer="\t|----位图\r\n";break; case 3:buffer="\t|----图标\r\n";break; case 4:buffer="\t|----菜单\r\n";break; case 5:buffer="\t|----对话框\r\n";break; case 6:buffer="\t|----字符串\r\n";break; case 7:buffer="\t|----字体目录\r\n";break; case 8:buffer="\t|----字体\r\n";break; case 9:buffer="\t|----加速键\r\n";break; case 10:buffer="\t|----RCDATA\r\n";break; case 11:buffer="\t|----消息表\r\n";break; case 12:buffer="\t|----光标组\r\n";break; case 14:buffer="\t|----图标组\r\n";break; case 16:buffer="\t|----版本\r\n";break; default:buffer="\t|----自定义\r\n";break; } AppendStrData(buffer); pResHead2 = (IMAGE_RESOURCE_DIRECTORY *)((DWORD)pResHead1 + pResDirEntry1->OffsetToData&0x7FFFFFFF); pResDirEntry2 = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)((DWORD)pResHead2 + sizeof(*pResHead2)); for (int j=0;j<pResHead2->NumberOfNamedEntries+pResHead2->NumberOfIdEntries;j++) { memset(&szBuf,0x00,512); AppendStrData("\t|\t|----"); if (pResDirEntry2->NameIsString==0){ AppendHexData((LPVOID)pResDirEntry2->Name); }else{ pResDir2Str = (IMAGE_RESOURCE_DIRECTORY_STRING *)((DWORD)pResHead1 + pResDirEntry2->Name&0x7FFFFFFF); WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,(USHORT *)pResDir2Str->NameString,pResDir2Str->Length,szBuf,512,NULL,NULL); AppendStrData(szBuf); } AppendStrData("\r\n"); pResHead3 = (IMAGE_RESOURCE_DIRECTORY *)((DWORD)pResHead1 + pResDirEntry2->OffsetToData&0x7FFFFFFF); pResDirEntry3=(IMAGE_RESOURCE_DIRECTORY_ENTRY *)((DWORD)pResHead3 + sizeof(*pResHead3)); int flag; for (int k=0;k<pResHead3->NumberOfNamedEntries+pResHead3->NumberOfIdEntries;k++) { flag=1; if (j==pResHead2->NumberOfNamedEntries+pResHead2->NumberOfIdEntries-1) flag=1; else flag=0; if (flag) AppendStrData("\t|\t\t|-语言:\t"); else AppendStrData("\t|\t|\t|-语言:\t"); AppendHexData((LPVOID)pResDirEntry3->Name); AppendStrData("\r\n"); pResDataEntry = (IMAGE_RESOURCE_DATA_ENTRY *)((DWORD)pResHead1 + pResDirEntry3->OffsetToData); if (flag) sprintf(szBuf,"\t|\t\t|文件偏移:\t0x%08X\r\n\t|\t\t|-资源大小:\t",RVAToOffset(pResDataEntry->OffsetToData)); else sprintf(szBuf,"\t|\t|\t|文件偏移:\t0x%08X\r\n\t|\t|\t|-资源大小:\t",RVAToOffset(pResDataEntry->OffsetToData)); AppendStrData(szBuf); AppendHexData((LPVOID)pResDataEntry->Size); AppendStrData("\r\n"); pResDirEntry3++; } pResDirEntry2++; } } else { pResDir1Str = (IMAGE_RESOURCE_DIRECTORY_STRING *)((DWORD)pResHead1 + pResDirEntry1->Name&0x7FFFFFFF); WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,(USHORT *)pResDir1Str->NameString,pResDir1Str->Length,szBuf,512,NULL,NULL); AppendStrData("\t|-"); AppendStrData(szBuf); AppendStrData("\t|\n"); } pResDirEntry1++; } AppendStrData("\r\n"); }
重定位表:
IMAGE_BASE_RELOCATION *pBaseRelocation; void GetRelocationTable() { AppendSectionData("\n重定位表:\t(0xFFFFFF只作对齐用,不表示重定位)\r\n",RGB(00,0xBB,0)); DWORD Num=0; WORD *pNext; if (pNtHeader->OptionalHeader.DataDirectory[5].VirtualAddress) { pBaseRelocation=(IMAGE_BASE_RELOCATION *)((BYTE *)lpBase+RVAToOffset(pNtHeader->OptionalHeader.DataDirectory[5].VirtualAddress)); while(pBaseRelocation->VirtualAddress) { Num=(pBaseRelocation->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2; sprintf(szBuf,"\r\n\t基址:0x%08X\r\n\t数量:0x%X\r\n\t--------------",pBaseRelocation->VirtualAddress,Num); AppendStrData(szBuf); pNext=(WORD *)((DWORD)pBaseRelocation+8); for (DWORD i=0;i<Num;i++) { if (i%8==0) AppendStrData("\r\n\t"); if ((*pNext&0x0F000)==0x3000){ sprintf(szBuf,"0x%08X ",*pNext&0x0FFF+pBaseRelocation->VirtualAddress); AppendStrData(szBuf); }else{ AppendStrData("0xFFFFFFFF "); } pNext++; } AppendStrData("\r\n\t"); pBaseRelocation=(IMAGE_BASE_RELOCATION *)(pNext); } } else { AppendStrData("\t无\r\n\n"); } }
感谢《Windows PE权威指南》,希望以后能看多更多这类优秀书籍。
附小作品一枚,以表感激:
http://115.com/file/e7iuyjga#PEInfo.rar