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

posted @ 2012-05-20 11:52  little evil  阅读(860)  评论(1编辑  收藏  举报