Quantcast
Channel: 看雪安全论坛
Viewing all articles
Browse latest Browse all 9556

调试逆向 【原创】[15Pb培训第三阶段课后小项目]MFC 写的一个PEedit

$
0
0
前言
来论坛很长时间了,这是第一次发主题帖。最近学习了pe文件结构,所以就写了一个peedit,算是一个深入理解pe文件的过程吧,嘿嘿,写的一般,望大家多多指教。
Pe文件结构相对来说比较复杂。但是学习它也是有规律可循的。由于网上学习pe的文章如过江之鲫,而且有很多都是很不错的,为了避免重复造轮子,所以在这里不再赘述,只在关键的地方说明下。下面这是pe文件格式和相关的资料查询链接。
1. http://bbs.pediy.com/showthread.php?t=98202
  2.http://bbs.pediy.com/showthread.php?threadid=22892
  3.PE文件格式,qduwg翻译http://bbs.pediy.com/showthread.php? threadid=19618
4.《黑客免杀攻防》第七章
  5.《Windows Pe权威指南》相关章节
  这是pe文件结构图,相对于其他的pe文件结构图来说,本人觉得这图很不错。这样会对pe文件结构有一个感性的认识。
http://bbs.pediy.com/attachment.php?attachmentid=84796&stc=1&d=1385996350

==========================================
正如前面所说,pe文件结构的资料资料很多,所以写这个的目的主要是为了加深自己对pe文件结构的理解与认识和用MFC开发编写peedit的能力。需要说明的是,写pe文件相关的程序不难,那么其区别就在于能不能将程序写像一件艺术品,或者有自己独到的之处。比如用了巧妙的方法,而不是看前人怎么写,自己拿过来用用就了事,所以写程序并不是说只要有功能在就o了。这是我们程序员应该遵守的准则我觉得(呵呵,我知道我也有很多不足的地方,我会慢慢的改正的)。
不费话了,下面就介绍下我的项目吧;
主要功能类的安排
因为pe文件结构有许许多多的表,使用父类与子类配合来解析各个表;
http://bbs.pediy.com/attachment.php?attachmentid=84797&stc=1&d=1385996405

这是结构体,通过成员函数返回给各个需要此结构体的子类
http://bbs.pediy.com/attachment.php?attachmentida=84762&stc=1&d=1385988139
一些关键的函数
1. rva转化为映射到内存的绝对地址
//rva就是内存相对偏移地址这里直接转化为加载进内存中的·绝对地址
代码:

DWORD RVA2Memaddr( DWORD dwVA,DWORD lpiamge,PIMAGE_NT_HEADERS32 pNT32 )
{
    PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT32);
    for ( DWORD i=0; i<=pNT32->FileHeader.NumberOfSections; i++ )
    {
        DWORD dwFileAddr=0;

        if ( dwVA < pSection[i].VirtualAddress )
        {
            DWORD dwAddr= dwVA - pSection[i-1].VirtualAddress-lpiamge;
            dwMemAddr=dwAddr+ pSection[i-1].PointerToRawData;
            return dwMemAddr;
        }
        else  if(dwVA>= pSection[pNT32->FileHeader.NumberOfSections-1].VirtualAddress)
        {
            DWORD dwAddr= dwVA - pSection[pNT32->FileHeader.NumberOfSections-1].VirtualAddress-lpiamge;
            dwMemAddr= dwAddr+ pSection[pNT32->FileHeader.NumberOfSections-1].PointerToRawData;
            return dwMemAddr;
        }
    }
    return 0;
}

2.pe映像文件的载入
代码:

//载入pe文件
PeMisicInfo CPELoad::LoadPEFile(LPCTSTR lpszPath)
{
    DWORD PeFileSize=0;
    LPVOID DumpAddr=nullptr;
    BOOL CanBeRead;
    PIMAGE_NT_HEADERS32 Nt_headers;
    //创建文件映射
    HANDLE hFile=CreateFile(lpszPath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,OPEN_EXISTING,SECURITY_IMPERSONATION,NULL);
    if(!hFile) goto EndProcess;
    PeFileSize=GetFileSize(hFile,NULL);
    if(PeFileSize==0)goto EndProcess;

    DumpAddr=VirtualAlloc(NULL,PeFileSize,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
    if(!DumpAddr)goto EndProcess;
    DWORD dwRet;

    CanBeRead=ReadFile(hFile,DumpAddr,PeFileSize,&dwRet,NULL);
    int a=GetLastError();
    if(!CanBeRead)goto EndProcess;//判断是不是pe文件
    // 判断是不是pe文件
    BOOL isPeFile=IsPeFile(DumpAddr,PeFileSize,Nt_headers);
    if(!isPeFile) goto EndProcess;
    mypemisc.Dumpaddr=DumpAddr;
    mypemisc.nt_headeras=Nt_headers;
    mypemisc.hFile=hFile;
    mypemisc.lpPath=lpszPath;
    return mypemisc;

EndProcess:
    if(hFile)CloseHandle(hFile);
    ExitProcess(0);


}

具体的代码(展示一下关键的代码,工程源码见附件)
1.获取导出表信息
代码:

void CImportDir::ShowModuleInfo(vector<PIMAGE_SECTION_HEADER> Section)
{
    //删除掉模块栏的所有条目
    m_modulelist.DeleteAllItems();
    //删除所有vector中模块
    mymodulename.clear();
    PeMisicInfo miscinfo=ReturnMiscInfo();
    PIMAGE_NT_HEADERS32 LocalHeaders=miscinfo.nt_headeras;
    DWORD dumpaddr=(DWORD)miscinfo.Dumpaddr;
    m_dumpaddr=dumpaddr;
    WORD optional_header_size=LocalHeaders->FileHeader.SizeOfOptionalHeader;
    PIMAGE_OPTIONAL_HEADER32  Optional_header=&LocalHeaders->OptionalHeader;
    PIMAGE_DATA_DIRECTORY pDataDir = (PIMAGE_DATA_DIRECTORY)Optional_header->DataDirectory;
    //导入表的地址
    DWORD my_export_rva=pDataDir[1].VirtualAddress;
    DWORD Import_Table_Section_ShiftAddr;
    DWORD OA;
  //数据段的RVA
    for(int a=0;a<Section.size();a++)
    {
        if(Section[a]->VirtualAddress>my_export_rva)
        {
            m_OA=OA=Section[a-1]->VirtualAddress-Section[a-1]->PointerToRawData;
            Import_Table_Section_ShiftAddr=my_export_rva-OA;
            break;
        }

    }
    if(Import_Table_Section_ShiftAddr==0xcccccccc)
    {
        MessageBox(L"未初始化",L"错误",MB_OK);
        return;
    }
    //获取输入表信息
    IMAGE_IMPORT_DESCRIPTOR *my_Import_Data=(PIMAGE_IMPORT_DESCRIPTOR)(Import_Table_Section_ShiftAddr+(DWORD)dumpaddr);
 
    PIMAGE_THUNK_DATA32 pInt;
    //判断的条件是因为大多数情况IMAGE_THUNK_DATA 会指向一个IMPORT_BY_NAME 结束的时候会以一个
    //全零的IMAGE_THUNK_DATA结束
    if(pInt=(PIMAGE_THUNK_DATA32)my_Import_Data->OriginalFirstThunk)
    {

        while(my_Import_Data->Name)
        {
            MYIMAGE_IMPORT_DESCRIPTOR my_image_des={0};
            DWORD pszDllName_Addr=my_Import_Data->Name-OA+dumpaddr;
            my_image_des.dllname=pszDllName_Addr;
            my_image_des.my_image_descriptor.FirstThunk=my_Import_Data->FirstThunk;
            my_image_des.my_image_descriptor.OriginalFirstThunk=my_Import_Data->OriginalFirstThunk;
            my_image_des.my_image_descriptor.ForwarderChain=my_Import_Data->ForwarderChain;
            my_image_des.my_image_descriptor.Name=my_Import_Data->Name;
            mymodulename.push_back(my_image_des);
            my_Import_Data++;

        }

        for(int a=0;a<mymodulename.size();a++)
        {
            CString myid;
            myid.Format(L"%d",a);
            char* mychar;
            m_modulelist.InsertItem(LVIF_TEXT | LVIF_STATE,a, myid,(a % 2) == 0 ? LVIS_SELECTED : 0, LVIS_SELECTED,0,0);
            for(int i=1;i<6;i++)
            {
                LPCWCH OutputChar[4]={0};
                CString mymoduleinfo;
                switch (i)
                {
                case 1:
                    MyUtil.ConvertUtf8ToUnicode((char*)mymodulename[a].dllname,*OutputChar);
                    mymoduleinfo.Format(L"%s",*OutputChar);
                    m_modulelist.SetItemText(a,i,mymoduleinfo);
                    break;
                case 2:
mymoduleinfo.Format(L"0x%X",mymodulename[a].my_image_descriptor.OriginalFirstThunk);
                    m_modulelist.SetItemText(a,i,mymoduleinfo);
                    break;
                case 3:
                    mymoduleinfo.Format(L"0x%X",mymodulename[a].my_image_descriptor.ForwarderChain);
                    m_modulelist.SetItemText(a,i,mymoduleinfo);
                    break;
                case 4:
mymoduleinfo.Format(L"0x%X",mymodulename[a].my_image_descriptor.Name);
                    m_modulelist.SetItemText(a,i,mymoduleinfo);
                    break;
                case 5:
mymoduleinfo.Format(L"0x%X",mymodulename[a].my_image_descriptor.FirstThunk);
                    m_modulelist.SetItemText(a,i,mymoduleinfo);
                    break;
                default:
                    break;
                }
            }
        }
    }
}

2.导出表信息
代码:

void CExportDir::GetExportInfo()
{
    LPCWCH outputchar={0};
    LPCWCH outputchar1={0};
    m_exportlistcrl.DeleteAllItems();
    m_vec_myexportinfo.clear();
    PeMisicInfo miscinfo=ReturnMiscInfo();//获取pe基本信息
    PIMAGE_NT_HEADERS32  pNT32    = miscinfo.nt_headeras;
    PIMAGE_DATA_DIRECTORY pDataDir = (PIMAGE_DATA_DIRECTORY)pNT32->OptionalHeader.DataDirectory;
    PIMAGE_DATA_DIRECTORY  pExportDir      = &pDataDir[IMAGE_DIRECTORY_ENTRY_EXPORT];
    if(pExportDir->Size!=0)
    {
    DWORD                  dwExportOfffset = Rva2FileA(pExportDir->VirtualAddress, pNT32);//输出表地文件偏移
    PIMAGE_EXPORT_DIRECTORY pExport        = (PIMAGE_EXPORT_DIRECTORY)((DWORD)miscinfo.Dumpaddr+dwExportOfffset);
    PDWORD pEAT = (PDWORD)((DWORD)miscinfo.Dumpaddr + Rva2FileA(pExport->AddressOfFunctions, pNT32));
    PDWORD pENT = (PDWORD)((DWORD)miscinfo.Dumpaddr + Rva2FileA(pExport->AddressOfNames, pNT32));
    PWORD  pEIT = (PWORD)((DWORD)miscinfo.Dumpaddr  + Rva2FileA(pExport->AddressOfNameOrdinals, pNT32));
    PCHAR exenameaddr=(PCHAR)((DWORD)miscinfo.Dumpaddr + Rva2FileA(pExport->Name, pNT32)); 
    mysttring.ConvertUtf8ToUnicode((char*)exenameaddr,outputchar1);
    /////////////////////////////////////////////
    //格式化输出
    m_ExpDirFa.Format(L"0x%X",dwExportOfffset);
    m_funaddr.Format(L"0x%X",pExport->AddressOfFunctions);
    m_funnameaddr.Format(L"0x%X",pExport->AddressOfNames);
    m_funnamenums.Format(L"%d",pExport->NumberOfNames);
    m_char.Format(L"%d",pExport->Characteristics);
    m_exename.Format(L"%s",outputchar1);
    m_funordaddr.Format(L"0x%X",pExport->AddressOfNameOrdinals);
    m_funnums.Format(L"0x%X",pExport->NumberOfFunctions);
    m_baseaddr.Format(L"0x%X",pExport->Base);
    m_namerva.Format(L"0x%X",pExport->Name);
    for ( DWORD dwOrdinal=0; dwOrdinal<pExport->NumberOfFunctions; dwOrdinal++ )
    {
        if ( !pEAT[dwOrdinal] )
            continue;
        for ( DWORD dwIndex=0; dwIndex<pExport->NumberOfFunctions; dwIndex++ )
        {
        EXPORTINFO myexportinfo={0};

            if ( pEIT[dwIndex] == dwOrdinal )
            {
                PCHAR pszFunName = (PCHAR)((DWORD)miscinfo.Dumpaddr+Rva2FileA(pENT[dwIndex], pNT32));
                myexportinfo.Ordinal=pExport->Base+dwOrdinal;
                myexportinfo.FuncRva=pEAT[dwOrdinal];
                mysttring.ConvertUtf8ToUnicode(pszFunName,outputchar);
                myexportinfo.funcname=outputchar;
                m_vec_myexportinfo.push_back(myexportinfo);
                break;
            }
            else if ( dwIndex == pExport->NumberOfFunctions-1 )
            {
                myexportinfo.Ordinal=pExport->Base+dwOrdinal;
                myexportinfo.FuncRva=pEAT[dwOrdinal];
                myexportinfo.funcname=(LPCWCH) L"(Null)" ;
                m_vec_myexportinfo.push_back(myexportinfo);
                break;
            }
          /// free(myexportinfo);
         
        }

    }
    ///////////////////////////////////./////
    //显示信息
    ////////////////////////////////////////
    UpdateData(FALSE);
    Showinfo();
    }
    else
    {
        MessageBox(L"没有导出表!",L"错误",MB_OK|MB_ICONSTOP);
    }
}

3.资源表信息
这是插入时的一个细节问题大家结合图与代码看看就明白了
http://bbs.pediy.com/attachment.php?attachmentid=84788&stc=1&d=1385993310
代码:

void CSrc::ShowInfo()
{
    //这里用ID关联资源之间的关系,来显示层与层之间的关系
    int ID1=0;
    m_srcTreecrl.ModifyStyle(NULL,TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT);
    PeMisicInfo miscinfo=ReturnMiscInfo();
    PIMAGE_NT_HEADERS32 pNT32 = (PIMAGE_NT_HEADERS32)miscinfo.nt_headeras;
    // 1.2 获取数据目录表
    PIMAGE_DATA_DIRECTORY pDir = (PIMAGE_DATA_DIRECTORY)pNT32->OptionalHeader.DataDirectory;
    // 1.3 获取资源表的数据目录
    PIMAGE_DATA_DIRECTORY pDataDir = pDir+IMAGE_DIRECTORY_ENTRY_RESOURCE;
    // 1.4 获取资源表
    PIMAGE_RESOURCE_DIRECTORY pResource1 = (PIMAGE_RESOURCE_DIRECTORY)RVA2Memaddr(pDataDir->VirtualAddress, miscinfo.Dumpaddr, pNT32);
    // 2. 循环遍历资源表
    // 2.1 第一层目录遍历
    DWORD dwCount1 = pResource1->NumberOfIdEntries+pResource1->NumberOfNamedEntries;
    for ( DWORD i=0; i<dwCount1; i++ )
    {
        SRCSTRUCT mystc={0};
        ID1++;
        mystc.ID=ID1;
        LPCWCH* outputchar=new LPCWCH;
        PIMAGE_RESOURCE_DIRECTORY_ENTRY pDirEntry1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResource1+sizeof(IMAGE_RESOURCE_DIRECTORY));
        if ( pDirEntry1[i].NameIsString )
        {
            PIMAGE_RESOURCE_DIR_STRING_U pString = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResource1+pDirEntry1[i].NameOffset);
            mystc.str.Format(L"Type:%ls",pString->NameString);
            Level1.push_back(mystc);
        }
        else
        {
            if ( pDirEntry1[i].Name>0x10 )
            {
                mystc.str.Format(L"%04X",pDirEntry1[i].Name);
                Level1.push_back(mystc);
            }

            else
            {
                mystc.str.Format(L"%ls",szResourceType[pDirEntry1[i].Name] );
                Level1.push_back(mystc);
            }

        }
        if ( pDirEntry1[i].DataIsDirectory )
        {
            int secid=0;
            // 2.2 第二层目录的遍历
            PIMAGE_RESOURCE_DIRECTORY pResource2 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResource1+pDirEntry1[i].OffsetToDirectory);
            DWORD dwCount2 = pResource2->NumberOfIdEntries+pResource2->NumberOfNamedEntries;
            for ( DWORD j=0; j<dwCount2; j++ )
            {

                SRCSTRUCT mystc2={0};
                mystc2.ID=ID1;
                //第二级的id
                secid++;
                mystc2.secid=secid;
                PIMAGE_RESOURCE_DIRECTORY_ENTRY pDirEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResource2+sizeof(IMAGE_RESOURCE_DIRECTORY));
                if ( pDirEntry2[j].NameIsString )
                {
                    LPWSTR szBuffer[30];
                    PIMAGE_RESOURCE_DIR_STRING_U pString = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResource2+pDirEntry2[j].NameOffset);
                    mystc2.str.Format(L"ID:%ls",pString->NameString);
                    Level2.push_back(mystc2);

                }
                else
                {
                    mystc2.str.Format(L"ID:%X",pDirEntry2[j].Name);
                    Level2.push_back(mystc2);

                }
                if ( pDirEntry2[j].DataIsDirectory )
                {
                  DWORD subId=0;
                    // 2.3 第三层目录的遍历
                    PIMAGE_RESOURCE_DIRECTORY pResource3 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResource1+pDirEntry2[j].OffsetToDirectory);
                    DWORD dwCount3 = pResource3->NumberOfIdEntries+pResource3->NumberOfNamedEntries;
                    for ( DWORD k=0; k< dwCount3; k++ )
                    {
                        SRCSTRUCT mystc3={0};
                        mystc3.secid=secid;
                        mystc3.ID=ID1;
                        subId++;
                        mystc3.subID=subId;
                        PIMAGE_RESOURCE_DIRECTORY_ENTRY pDirEntry3 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResource3+sizeof(IMAGE_RESOURCE_DIRECTORY));
                        PIMAGE_RESOURCE_DATA_ENTRY pData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pResource1+pDirEntry3[k].OffsetToData);
                        mystc3.str.Format(L"Lng:%04X,RVA:0x%p Size:%04X Page:0x%p",pDirEntry3[k].Name,pData->OffsetToData, pData->Size, pData->CodePage);
                        Level3.push_back(mystc3);
                    }
                }
                else
                {
                    // ....
                }
         

            }
        }
        else
        {
            // ......
        }
    }
RealShowInfo();
 }

导入表信息
获取模块信息
代码:

void CImportDir::ShowModuleInfo(vector<PIMAGE_SECTION_HEADER> Section)
{
    //删除掉模块栏的所有条目
    m_modulelist.DeleteAllItems();
    //删除所有vector中模块
    mymodulename.clear();
    PeMisicInfo miscinfo=ReturnMiscInfo();
    PIMAGE_NT_HEADERS32 LocalHeaders=miscinfo.nt_headeras;
    DWORD dumpaddr=(DWORD)miscinfo.Dumpaddr;
    m_dumpaddr=dumpaddr;
    WORD optional_header_size=LocalHeaders->FileHeader.SizeOfOptionalHeader;
    PIMAGE_OPTIONAL_HEADER32  Optional_header=&LocalHeaders->OptionalHeader;
    PIMAGE_DATA_DIRECTORY pDataDir = (PIMAGE_DATA_DIRECTORY)Optional_header->DataDirectory;
    //导入表的地址
    DWORD my_export_rva=pDataDir[1].VirtualAddress;
    DWORD Import_Table_Section_ShiftAddr;
    DWORD OA;
  //数据段的RVA
    for(int a=0;a<Section.size();a++)
    {
        if(Section[a]->VirtualAddress>my_export_rva)
        {
            m_OA=OA=Section[a-1]->VirtualAddress-Section[a-1]->PointerToRawData;
            Import_Table_Section_ShiftAddr=my_export_rva-OA;
            break;
        }

    }
    if(Import_Table_Section_ShiftAddr==0xcccccccc)
    {
        MessageBox(L"未初始化",L"错误",MB_OK);
        return;
    }
    //获取输入表信息
    IMAGE_IMPORT_DESCRIPTOR *my_Import_Data=(PIMAGE_IMPORT_DESCRIPTOR)(Import_Table_Section_ShiftAddr+(DWORD)dumpaddr);
 
    PIMAGE_THUNK_DATA32 pInt;
    //判断的条件是因为大多数情况IMAGE_THUNK_DATA 会指向一个IMPORT_BY_NAME 结束的时候会以一个
    //全零的IMAGE_THUNK_DATA结束
    if(pInt=(PIMAGE_THUNK_DATA32)my_Import_Data->OriginalFirstThunk)
    {

        while(my_Import_Data->Name)
        {
            MYIMAGE_IMPORT_DESCRIPTOR my_image_des={0};
            DWORD pszDllName_Addr=my_Import_Data->Name-OA+dumpaddr;
            my_image_des.dllname=pszDllName_Addr;
            my_image_des.my_image_descriptor.FirstThunk=my_Import_Data->FirstThunk;
            my_image_des.my_image_descriptor.OriginalFirstThunk=my_Import_Data->OriginalFirstThunk;
            my_image_des.my_image_descriptor.ForwarderChain=my_Import_Data->ForwarderChain;
            my_image_des.my_image_descriptor.Name=my_Import_Data->Name;
            mymodulename.push_back(my_image_des);
            my_Import_Data++;

        }
        for(int a=0;a<mymodulename.size();a++)
        {
            CString myid;
            myid.Format(L"%d",a);
            char* mychar;
            m_modulelist.InsertItem(LVIF_TEXT | LVIF_STATE,a, myid,(a % 2) == 0 ? LVIS_SELECTED : 0, LVIS_SELECTED,0,0);
            for(int i=1;i<6;i++)
            {
                LPCWCH OutputChar[4]={0};
                CString mymoduleinfo;
                switch (i)
                {
                case 1:
                    MyUtil.ConvertUtf8ToUnicode((char*)mymodulename[a].dllname,*OutputChar);
                    mymoduleinfo.Format(L"%s",*OutputChar);
                    m_modulelist.SetItemText(a,i,mymoduleinfo);
                    break;
                case 2:
                    mymoduleinfo.Format(L"0x%X",mymodulename[a].my_image_descriptor.OriginalFirstThunk);
                    m_modulelist.SetItemText(a,i,mymoduleinfo);
                    break;
                case 3:
                    mymoduleinfo.Format(L"0x%X",mymodulename[a].my_image_descriptor.ForwarderChain);
                    m_modulelist.SetItemText(a,i,mymoduleinfo);
                    break;
                case 4:
                    mymoduleinfo.Format(L"0x%X",mymodulename[a].my_image_descriptor.Name);
                    m_modulelist.SetItemText(a,i,mymoduleinfo);
                    break;
                case 5:
                    mymoduleinfo.Format(L"0x%X",mymodulename[a].my_image_descriptor.FirstThunk);
                    m_modulelist.SetItemText(a,i,mymoduleinfo);
                    break;
                default:
                    break;
                }
            }
        }
    }
}

然后是通过点击模块,获取具体模块的api信息
代码:

void CImportDir::ShowImportFuncInfo(PIMAGE_IMPORT_DESCRIPTOR my_Import_Data,DWORD OA,DWORD dumpaddr)
{
    m_funlist.DeleteAllItems();
    //先清空Func vector
    myfunlist.clear();
    //指向输入名称地址表(INT) 绝对地址
    DWORD pInt=my_Import_Data->OriginalFirstThunk-OA;
    DWORD pInt_addr=pInt+dumpaddr;
    PIMAGE_THUNK_DATA32 Pint=(PIMAGE_THUNK_DATA32)pInt_addr;
    //循环打印INT的内容
    if (Pint->u1.Ordinal)
    {
        while (Pint->u1.Ordinal)
        {
            DWORD i=0;
            if(!IMAGE_SNAP_BY_ORDINAL32(Pint->u1.Ordinal))
            {
                MYFUNCINFO myfun={0};
                DWORD  my_import_rva_data=(DWORD)Pint->u1.AddressOfData;
                DWORD  My_importFunciton_name_addr=my_import_rva_data-OA+dumpaddr;
                PIMAGE_IMPORT_BY_NAME My_importFunciton_name_struct=(PIMAGE_IMPORT_BY_NAME)(My_importFunciton_name_addr);
                myfun.FunName=(LPCTSTR)My_importFunciton_name_struct->Name;
                myfun.ThunkRVA=my_Import_Data->OriginalFirstThunk+i*4;
                myfun.Hint=My_importFunciton_name_struct->Hint;
                myfun.ThunkValue=my_import_rva_data;
                myfunlist.push_back(myfun);
                Pint++;
                i++;
                continue;
            }
            Pint++;

        }
        for(int a=0;a<myfunlist.size();a++)
        {
            CString myid;
            myid.Format(L"%d",a+1);
            m_funlist.InsertItem(LVIF_TEXT | LVIF_STATE,a, myid,(a % 2) == 0 ? LVIS_SELECTED : 0, LVIS_SELECTED,0,0);
            for(int i=1;i<6;i++)
            {
                LPCWCH outputfun[8]={0};
                CString mymoduleinfo;
                switch (i)
                {
                case 1:
                    MyUtil.ConvertUtf8ToUnicode((char*)myfunlist[a].FunName,*outputfun);
                    mymoduleinfo.Format(L"%s",*outputfun);
                    m_funlist.SetItemText(a,i,mymoduleinfo);
                    break;
                case 2:
                    mymoduleinfo.Format(L"0x%X",myfunlist[a].ThunkRVA+4*a);
                    m_funlist.SetItemText(a,i,mymoduleinfo);
                    break;
                case 3:
           
                    mymoduleinfo.Format(L"0x%X",myfunlist[a].ThunkRVA-OA+4*a);
                    m_funlist.SetItemText(a,i,mymoduleinfo);
                    break;
                case 4:
                    mymoduleinfo.Format(L"0x%X",myfunlist[a].ThunkValue);
                    m_funlist.SetItemText(a,i,mymoduleinfo);
                    break;
                case 5:
                    mymoduleinfo.Format(L"0X%X",myfunlist[a].Hint);
                    m_funlist.SetItemText(a,i,mymoduleinfo);
                    break;
                default:
                    break;

                }
         
            }
       
        }
    }
}

===============
代码就贴这些了,
================
这写是软件界面的截图
主界面
http://bbs.pediy.com/attachment.php?attachmentid=84789&stc=1&d=1385995081
导入表
http://bbs.pediy.com/attachment.php?attachmentid=84790&stc=1&d=1385995081
导出表
http://bbs.pediy.com/attachment.php?attachmentid=84791&stc=1&d=1385995081
资源表
http://bbs.pediy.com/attachment.php?attachmentid=84794&stc=1&d=1385995313
16Edit
这个是调用的16edit的库,本人表示再次被yoda大牛所折服。。。。;):
http://bbs.pediy.com/attachment.php?attachmentid=84792&stc=1&d=1385995081


总结
通过学习pe文件,给我的感觉就是微软那帮人真是厉害,那数据结构搞的如此复杂,当然复杂不是他们的目的,而是更好的更加稳定的让程序在windows上运行。另一个就是绝知此事要躬行,pe文件虽然不是很复杂,但是能掌握到何种程度是另一回事,而且学完之后,你能思考为什么会这样安排某一数据层次,就是另一个层次。思考问题外的问题往往我们会收获更多,这也许就是大牛与菜鸟的区别吧,呵呵。源码见附件,稍后会补上文档,大家先看看源码吧。这样会有更多的思考的机会,也希望大家能指出其中的错误,愿与大家共同成长。
附件密码是:kanxue123:p:
附件 84795

上传的图像
文件类型: png srcstrutc.png (35.8 KB)
文件类型: png main2.png (32.0 KB)
文件类型: png import.png (52.7 KB)
文件类型: png export.png (46.7 KB)
文件类型: png 16进制编辑.png (38.5 KB)
文件类型: png srca.png (35.3 KB)
文件类型: png src2.png (36.0 KB)
文件类型: jpg 图片1.jpg (80.6 KB)
文件类型: png class.png (36.7 KB)
上传的附件
文件类型: zip PEEdit.zip (175.9 KB)

Viewing all articles
Browse latest Browse all 9556

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>