首页
社区
课程
招聘
[原创][开源]LordPE框架设计之精简版
发表于: 2015-11-29 13:43 19654

[原创][开源]LordPE框架设计之精简版

2015-11-29 13:43
19654
首先表示拿到第一个精华很开心 感谢段老师  我会继续努力滴 
还有就是对于我所有发的帖子有不懂的地方 在帖子内回复即可  
我会给解答的 KX币不多 。伤不起。。。

--------------------------
推荐这个帖子 能帮助你更好理解
Win32控制台解析PE文件http://bbs.pediy.com/showthread.php?t=206060

已解析:

  • 基本PE头信息
  • 区段
  • 目录

  • -    输出表
  •     - 输入表 
  •     - 资源  
  •     - 重定位

  • 位置计算器

  • 与LordPE对照效果图:

  • 基本PE头信息



  • 区段



  • 目录



  • 输出表



  • 输入表



  • 资源



  • 重定位



  • 位置计算器



  • 贴出项目关键代码:

    计算偏移:
    AnalyticalPE.h  AnalyticalPE.cpp
    
    DWORD AnalyticalPE::CalcOffset(DWORD Rva)
    {
      //循环比较在那个区段  不在这个区段就继续循环  
      //PIMAGE_NT_HEADERS32 pnt=pNtH;
      PIMAGE_SECTION_HEADER pSecHTemp=IMAGE_FIRST_SECTION(pNtH);//区段头
      int index=0;
      while (!(Rva>=pSecHTemp->VirtualAddress&&
        Rva<pSecHTemp->VirtualAddress+pSecHTemp->SizeOfRawData))
      {
        //找完所有区段还没有找到
        if (index>pNtH->FileHeader.NumberOfSections)
        {
    
          return Rva;
        }
        ++index;
        ++pSecHTemp;
      }
      return Rva-pSecHTemp->VirtualAddress+pSecHTemp->PointerToRawData;;
    }
    


    显示基本PE头相关信息
    简易PEDlg.h  简易PEDlg.cpp
    
    void C简易PEDlg::ShowPeInfo()
    {
      //BaseOfCode;
      if (AnalPE.buf==NULL)
      {
        AfxMessageBox(L"请拖入PE文件");
        return ;
      }
      AnalPE.OutPutPeInfo(m_EntryPoint,AnalPE.pOptH->AddressOfEntryPoint);    //入口点
      AnalPE.OutPutPeInfo(m_ImageBase,AnalPE.pOptH->ImageBase);          //镜像地址
      AnalPE.OutPutPeInfo(m_SizeOfImage,AnalPE.pOptH->SizeOfImage);        //镜像大小
      AnalPE.OutPutPeInfo(m_BaseOfCode,AnalPE.pOptH->BaseOfCode);          //代码基址
      AnalPE.OutPutPeInfo(m_BaseOfData,AnalPE.pOptH->BaseOfData);          //数据基址
      AnalPE.OutPutPeInfo(m_SectionAlignment,AnalPE.pOptH->SectionAlignment);    //块对齐
      AnalPE.OutPutPeInfo(m_FileAlignment,AnalPE.pOptH->FileAlignment);      //文件块对齐
      AnalPE.OutPutPeInfo(m_Magic,AnalPE.pOptH->Magic);              //标志字
      //第二版
      AnalPE.OutPutPeInfo(m_Subsystem,AnalPE.pOptH->Subsystem);          //子系统
      AnalPE.OutPutPeInfo(m_NumberOfSections,AnalPE.pNtH->FileHeader.NumberOfSections);      //区段数目
      AnalPE.OutPutPeInfo(m_TimeDateStamp,AnalPE.pNtH->FileHeader.TimeDateStamp);        //日期时间标志
      AnalPE.OutPutPeInfo(m_SizeOfHeaders,AnalPE.pOptH->SizeOfHeaders);      //部首大小
      AnalPE.OutPutPeInfo(m_Characteristics,AnalPE.pNtH->FileHeader.Characteristics);      //特征值
      AnalPE.OutPutPeInfo(m_CheckSum,AnalPE.pOptH->CheckSum);            //校验和
      AnalPE.OutPutPeInfo(m_SizeOfOptionalHeader,AnalPE.pNtH->FileHeader.SizeOfOptionalHeader);  //可选头部大小
      AnalPE.OutPutPeInfo(m_NumberOfRvaAndSizes,AnalPE.pOptH->NumberOfRvaAndSizes);//RVA数及大小
      UpdateData(FALSE);
    }
    


    显示区段相关信息
    MyAreaTable.h  MyAreaTable.cpp
    
    void MyAreaTable::ShowAreaTable()
    {
      if (AnalPE.pSecH==NULL)
      {
        return;
      }
      PIMAGE_SECTION_HEADER pSecHTemp=AnalPE.pSecH;;//区段头
      int i=0;
      CString str;
      while (i<AnalPE.pNtH->FileHeader.NumberOfSections)  //区段数目
      {
        str=pSecHTemp->Name;
        m_AreaTabList.InsertItem(i,str);
        str.Format(L"%08X",pSecHTemp->VirtualAddress);
        m_AreaTabList.SetItemText(i,1,str);
        str.Format(L"%08X",pSecHTemp->Misc.VirtualSize);
        m_AreaTabList.SetItemText(i,2,str);
        str.Format(L"%08X",pSecHTemp->PointerToRawData);
        m_AreaTabList.SetItemText(i,3,str);
        str.Format(L"%08X",pSecHTemp->SizeOfRawData);
        m_AreaTabList.SetItemText(i,4,str);
        str.Format(L"%08X",pSecHTemp->Characteristics);
        m_AreaTabList.SetItemText(i,5,str);
        ++pSecHTemp;
        i++;
      }
    }
    


    显示目录相关信息
    MyCatalog.h  MyCatalog.cpp
    
    void MyCatalog::ShowPeInfo()
    {
      if (AnalPE.pNtH==NULL)
      {
        return;
      }
      
      AnalPE.OutPutPeInfo(m_ExportRva,    AnalPE.pDatD[0].VirtualAddress);
      AnalPE.OutPutPeInfo(m_ExportSize,    AnalPE.pDatD[0].Size);
      AnalPE.OutPutPeInfo(m_ImportRva,    AnalPE.pDatD[1].VirtualAddress);
      AnalPE.OutPutPeInfo(m_ImportSize,    AnalPE.pDatD[1].Size);
      AnalPE.OutPutPeInfo(m_ResourceRva,    AnalPE.pDatD[2].VirtualAddress);
      AnalPE.OutPutPeInfo(m_ResourceSize,    AnalPE.pDatD[2].Size);
      AnalPE.OutPutPeInfo(m_ExceptionRva,    AnalPE.pDatD[3].VirtualAddress);
      AnalPE.OutPutPeInfo(m_ExceptionSize,  AnalPE.pDatD[3].Size);
      AnalPE.OutPutPeInfo(m_SecurityRva,    AnalPE.pDatD[4].VirtualAddress);
      AnalPE.OutPutPeInfo(m_SecuritySize,    AnalPE.pDatD[4].Size);
      AnalPE.OutPutPeInfo(m_BaserelocRva,    AnalPE.pDatD[5].VirtualAddress);
      AnalPE.OutPutPeInfo(m_BaserelocSize,  AnalPE.pDatD[5].Size);
      AnalPE.OutPutPeInfo(M_DebugRva,      AnalPE.pDatD[6].VirtualAddress);
      AnalPE.OutPutPeInfo(M_DebugSize,    AnalPE.pDatD[6].Size);
      AnalPE.OutPutPeInfo(m_ArchitectureRva,  AnalPE.pDatD[7].VirtualAddress);
      AnalPE.OutPutPeInfo(m_ArchitectureSize,  AnalPE.pDatD[7].Size);
      AnalPE.OutPutPeInfo(m_GlobalptrRva,    AnalPE.pDatD[8].VirtualAddress);
      AnalPE.OutPutPeInfo(m_GlobalptrSize,  AnalPE.pDatD[8].Size);
      AnalPE.OutPutPeInfo(m_TlsRva,      AnalPE.pDatD[9].VirtualAddress);
      AnalPE.OutPutPeInfo(m_TlsSize,      AnalPE.pDatD[9].Size);
      AnalPE.OutPutPeInfo(m_LoadConfigRva,  AnalPE.pDatD[10].VirtualAddress);
      AnalPE.OutPutPeInfo(m_LoadConfigSize,  AnalPE.pDatD[10].Size);
      AnalPE.OutPutPeInfo(m_BoundImportRva,  AnalPE.pDatD[11].VirtualAddress);
      AnalPE.OutPutPeInfo(m_BoundImportSize,  AnalPE.pDatD[11].Size);
      AnalPE.OutPutPeInfo(m_IatRva,      AnalPE.pDatD[12].VirtualAddress);
      AnalPE.OutPutPeInfo(m_IatSize,      AnalPE.pDatD[12].Size);
      AnalPE.OutPutPeInfo(m_DelayImportRva,  AnalPE.pDatD[13].VirtualAddress);
      AnalPE.OutPutPeInfo(m_DelayImportSize,  AnalPE.pDatD[13].Size);
      AnalPE.OutPutPeInfo(m_ComDescriptorRva,  AnalPE.pDatD[14].VirtualAddress);
      AnalPE.OutPutPeInfo(m_ComDescriptorSize,AnalPE.pDatD[14].Size);
      UpdateData(FALSE);
    }
    


    显示输出表相关信息
    MyExporTable.h  MyExporTable.cpp
    
    void MyExporTable::ShowExportInfo()
    {
      //函数偏移表地址:
      AnalPE.OutPutPeInfo(m_ExportOffest,AnalPE.CalcOffset(AnalPE.pDatD->VirtualAddress));
      //函数地址:
      AnalPE.OutPutPeInfo(m_FunctionAddr,AnalPE.pExpD->AddressOfFunctions);
      //函数名序号地址:
      AnalPE.OutPutPeInfo(m_FunSerialNumberAddr,AnalPE.pExpD->AddressOfNameOrdinals);
      //函数名称地址:
      AnalPE.OutPutPeInfo(m_FunctionNameAddr,AnalPE.pExpD->AddressOfNames);
      //基址:
      AnalPE.OutPutPeInfo(m_Plot,AnalPE.CalcOffset(AnalPE.pExpD->Base));
      //特征值:
      AnalPE.OutPutPeInfo(m_Characteristic,AnalPE.CalcOffset(AnalPE.pExpD->Characteristics));
      //名称:
      AnalPE.OutPutPeInfo(m_Name,AnalPE.CalcOffset(AnalPE.pExpD->Name));
    
      //名称字串:
      m_NameString=AnalPE.PeFileName;
      int i=m_NameString.ReverseFind('\\');
      m_NameString.Delete(0,i+1);
      //("函数数量:
      AnalPE.OutPutPeInfo(m_FunctionNumber,AnalPE.CalcOffset(AnalPE.pExpD->NumberOfFunctions));
      //函数名数量:
      AnalPE.OutPutPeInfo(m_FunctionNameNumber,AnalPE.CalcOffset(AnalPE.pExpD->NumberOfNames));
      UpdateData(FALSE);
    }
    
    


    显示输入表相关信息(注意:这里就是响点点击并显示操作稍难,重定位比这个又要稍难一些,其它就没什么太难的地方了
    MyImport.h  MyImport.cpp 
    
    void MyImport::ShowImportList()
    {
      //获取导入表
      PIMAGE_IMPORT_DESCRIPTOR  pImpD;
      AnalPE.pDatD=&(  AnalPE.pOptH->DataDirectory[1]);
      pImpD=(PIMAGE_IMPORT_DESCRIPTOR)((long)AnalPE.buf+AnalPE.CalcOffset(AnalPE.pDatD->VirtualAddress));
      //第一层循环 每个导入的DLL依次解析
      int i=0;
      CString str;
      while(pImpD->Name)
      {
        //DLL名称相关
        //printf_s("DLL名称:%s  ",(AnalPE.buf+AnalPE.CalcOffset(pImpD->Name)));
        CString str((AnalPE.buf+AnalPE.CalcOffset(pImpD->Name)));
        //m_UpImport.InsertItem(i,L"(AnalPE.buf+AnalPE.CalcOffset(pImpD->Name))");
        m_UpImport.InsertItem(i,str);
        
        //printf_s("INT(输入名称表):%08X  ",pImpD->OriginalFirstThunk);
        str.Format(L"%08X",pImpD->OriginalFirstThunk);
        m_UpImport.SetItemText(i,1,str);
        //printf_s("日期时间标志:%08X  ",pImpD->TimeDateStamp);
        str.Format(L"%08X",pImpD->TimeDateStamp);
        m_UpImport.SetItemText(i,2,str);
      //  printf_s("ForwarderChain:%08X  ",pImpD->ForwarderChain);
        str.Format(L"%08X",pImpD->ForwarderChain);
        m_UpImport.SetItemText(i,3,str);
      //  printf_s("名称:%08X  ",pImpD->Name);
        str.Format(L"%08X",pImpD->Name);
        m_UpImport.SetItemText(i,4,str);
      //  printf_s("FirstThunk:%08X\n",pImpD->FirstThunk);
        str.Format(L"%08X",pImpD->FirstThunk);
        m_UpImport.SetItemText(i,5,str);
        m_VecImport.push_back(pImpD);
        i++;
        
        //system("pause");
        pImpD++;
      }
    }
    


    显示资源相关信息(有点长 但并不难
    MyResources.h  MyResources.cpp 
    
    void MyResources::ShowResourcesInfo()
    {
      RESSENCONDINFO ResSendInfo;
      RESTHIRDINFO ResThirdInfo;
      AnalPE.pDatD=&(  AnalPE.pOptH->DataDirectory[2]);
      PIMAGE_RESOURCE_DIRECTORY pResD=(PIMAGE_RESOURCE_DIRECTORY)(AnalPE.buf+  AnalPE.CalcOffset(AnalPE.pDatD->VirtualAddress));
      DWORD ReSize=pResD->NumberOfIdEntries+pResD->NumberOfNamedEntries;
      PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDE=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((long)pResD+sizeof(IMAGE_RESOURCE_DIRECTORY));
      //AnalPE.OutPutPeInfo(m_Name,pResDE->NameIsString);
      //AnalPE.OutPutPeInfo(m_Id,ReSize);
      //另一种写法
      m_Name.Format(L"%04X",pResDE->NameIsString);
      m_Id.Format(L"%04X",ReSize);
      HTREEITEM hItem ;
      HTREEITEM hSubItem ;
      //HTREEITEM hThirdItem;
      //此处也可使用std::map      喜欢什么用什么吧 
    
      CString str;
      for (DWORD FirstOrder=0;FirstOrder<ReSize;FirstOrder++)
      {
        //第一层 假如是字符串标识
        if (pResDE->NameIsString==1)
        {
          PIMAGE_RESOURCE_DIR_STRING_U pREsDStrU=(PIMAGE_RESOURCE_DIR_STRING_U)((long)pResD+pResDE->NameOffset);
          //printf_s("资源类型名:%s",pREsDStrU->NameString);
          hItem = m_ResTreeList.InsertItem(pREsDStrU->NameString,NULL,NULL);///root就是节点的标题
        }
        //假如是一直类型 用序号作为标识
        else
        {
          switch (pResDE->Name)
          {
          case 0x1:
            //printf_s("第一层:%s\n",ResourceName[0]);
            hItem = m_ResTreeList.InsertItem(L"鼠标指针",NULL,NULL);
            break;        
          case 0x2:        
            //printf_s("第一层:%s\n",ResourceName[1]);
            hItem = m_ResTreeList.InsertItem(L"位图",NULL,NULL);
            break;        
          case 0x3:        
            //printf_s("第一层:%s\n",ResourceName[2]);
            hItem = m_ResTreeList.InsertItem(L"图标",NULL,NULL);
            break;        
          case 0x4:        
            //printf_s("第一层:%s\n",ResourceName[3]);
            hItem = m_ResTreeList.InsertItem(L"菜单",NULL,NULL);
            break;        
          case 0x5:        
            //printf_s("第一层:%s\n",ResourceName[4]);
            hItem = m_ResTreeList.InsertItem(L"对话框",NULL,NULL);
            break;        
          case 0x6:        
            //printf_s("第一层:%s\n",ResourceName[5]);
            hItem = m_ResTreeList.InsertItem(L"字符串列表",NULL,NULL);
            break;        
          case 0x7:        
            //printf_s("第一层:%s\n",ResourceName[6]);
            hItem = m_ResTreeList.InsertItem(L"字体目录",NULL,NULL);
            break;        
          case 0x8:        
            //printf_s("第一层:%s\n",ResourceName[7]);
            hItem = m_ResTreeList.InsertItem(L"字体",NULL,NULL);
            break;        
          case 0x9:        
            //printf_s("第一层:%s\n",ResourceName[8]);
            hItem = m_ResTreeList.InsertItem(L"快捷键",NULL,NULL);
            break;        
          case 0xA:        
            //printf_s("第一层:%s\n",ResourceName[9]);
            hItem = m_ResTreeList.InsertItem(L"非格式化资源",NULL,NULL);
            break;        
          case 0xB:        
            //printf_s("第一层:%s\n",ResourceName[10]);
            hItem = m_ResTreeList.InsertItem(L"消息列表",NULL,NULL);
            break;        
          case 0xC:        
            //printf_s("第一层:%s\n",ResourceName[11]);
            hItem = m_ResTreeList.InsertItem(L"鼠标指针组",NULL,NULL);
            break;        
          case 0xE:        
            //printf_s("第一层:%s\n",ResourceName[12]);
            hItem = m_ResTreeList.InsertItem(L"图标组",NULL,NULL);
            break;        
          case 0x10:        
            //printf_s("第一层:%s\n",ResourceName[13]);
            hItem = m_ResTreeList.InsertItem(L"版本信息",NULL,NULL);
            break;        
          default:
            //printf_s("第一层:%d\n",pResDE->Name);
            str.Format(L"%d",pResDE->Name);
            hItem = m_ResTreeList.InsertItem(str,NULL,NULL);
            break;
          }
        }
        //找第二层 注意OFFEST 是相对于pResD也就是资源开始位置的偏移
        PIMAGE_RESOURCE_DIRECTORY pResD2=(PIMAGE_RESOURCE_DIRECTORY)((long)pResD+pResDE->OffsetToDirectory);
        DWORD ReSize2=pResD2->NumberOfIdEntries+pResD2->NumberOfNamedEntries;
        PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDE2=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((long)pResD2+sizeof(IMAGE_RESOURCE_DIRECTORY));
    
        m_ResTreeList.SetItemData(hItem, FirstOrder);
        //printf_s("第er层[名称条目]->:%04X   ",pResDE2->NameIsString);  
        //AnalPE.OutPutPeInfo(m_Name2,pResDE2->NameIsString);
        ResSendInfo.NameIsString=pResD2->NumberOfNamedEntries;
        ResSendInfo.ReSize2=pResD2->NumberOfIdEntries;
        m_VecResSedInfo.push_back(ResSendInfo);
        //printf_s("第er层[ID条目]->:%04X   \n",pResDE2->Id);
        //AnalPE.OutPutPeInfo(m_Id2,ReSize2);  
    
        DWORD SecondOrder=0;
        for (;SecondOrder<ReSize2;SecondOrder++)
        {
          if (pResDE2->DataIsDirectory==1)
          {
            //输出第二层资源的标识看是数字还是字符串
            if (pResDE2->NameIsString==1)
            {
              PIMAGE_RESOURCE_DIR_STRING_U pREsDStrU2=(PIMAGE_RESOURCE_DIR_STRING_U)((long)pResD+pResDE2->NameOffset);
              //输出资源类型名字
              //printf("第二层->资源类型名:%ls   ",pREsDStrU2->NameString);
              hSubItem = m_ResTreeList.InsertItem(pREsDStrU2->NameString,NULL,NULL,hItem);
              m_ResTreeList.SetItemData(hSubItem, SecondOrder);
            }
            else
            {
              //printf_s("第二层->资源类型名ID:%d   ",pResDE2->Id);  
              str.Format(L"%d",pResDE2->Id);
              hSubItem = m_ResTreeList.InsertItem(str,NULL,NULL,hItem);
              m_ResTreeList.SetItemData(hSubItem, SecondOrder);
            }
            //解析第三层 
            PIMAGE_RESOURCE_DIRECTORY pResD3=(PIMAGE_RESOURCE_DIRECTORY)((long)pResD+pResDE2->OffsetToDirectory);
            PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDE3=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((long)pResD3+sizeof(IMAGE_RESOURCE_DIRECTORY));
            PIMAGE_RESOURCE_DATA_ENTRY pResDataE=(PIMAGE_RESOURCE_DATA_ENTRY)((long)pResD+pResDE3->OffsetToData);
            //printf_s("第三层->RVA:%08X   ",pResDataE->OffsetToData);  
            //AnalPE.OutPutPeInfo()
            //根据第一层 也就是父节点 区分 
            ResThirdInfo.Rva=pResDataE->OffsetToData;
            ResThirdInfo.Offset=(AnalPE.CalcOffset(pResDataE->OffsetToData));
            ResThirdInfo.Size=pResDataE->Size;
            m_VecResthdInfo[FirstOrder].push_back(ResThirdInfo);
          //  str.Format(L"%08X",pResDataE->OffsetToData);
          //  m_ResTreeList.InsertItem(str,NULL,NULL,hSubItem);
          ////  printf_s("第三层->偏移:%08X   ",(AnalPE.CalcOffset(pResDataE->OffsetToData)));
          //  str.Format(L"%08X",(AnalPE.CalcOffset(pResDataE->OffsetToData)));
          //  m_ResTreeList.InsertItem(str,NULL,NULL,hSubItem);
          ////  printf_s("第三层->大小:%08X\n",pResDataE->Size);
          //  str.Format(L"%08X",pResDataE->Size);
          //  m_ResTreeList.InsertItem(str,NULL,NULL,hSubItem);
    
          }
          else
          {
            break;
          }
          pResDE2++;
        }
        //保存父节点的句柄
        m_VecHtreeItem.push_back(hItem);
        pResDE++;
      }
      m_Name2.Format(L"%04X",m_VecResSedInfo[0].NameIsString);
      m_Id2.Format(L"%04X",m_VecResSedInfo[0].ReSize2);
      UpdateData(FALSE);
    }
    


    显示重定向相关信息
    MyRelocation.h  MyRelocation.cpp
    
    void MyRelocation::ShowRelocation()
    {
      AnalPE.pDatD=&(AnalPE.pOptH->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]);//也就是5
      PIMAGE_BASE_RELOCATION pBasR=(PIMAGE_BASE_RELOCATION)((long)AnalPE.buf+AnalPE.CalcOffset(AnalPE.pDatD->VirtualAddress));
      RELOCAREAINFO Temp={0};
      int j=0;//索引
      CString str;
      while (pBasR->VirtualAddress)
      {
        //printf_s("索引:%d  ",j);
        str.Format(L"%d",j+1);
        m_FirstReloc.InsertItem(j,str);
        //区域的虚拟地址输出或获取到其他地方
        Temp.dwAreaRVA=pBasR->VirtualAddress;
    
        RelCalcOffset(Temp.dwAreaRVA,AnalPE.pNtH,AnalPE.buf,Temp.szSectionName,NULL);
      //  printf_s("%s   ",Temp.szSectionName);
        CString str(Temp.szSectionName);
        m_FirstReloc.SetItemText(j,1,str);
        //printf_s("%08X   ",pBasR->VirtualAddress);
        str.Format(L"%08X",pBasR->VirtualAddress);
        m_FirstReloc.SetItemText(j,2,str);
        Temp.NumberOfReloc=(pBasR->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2;
      //  printf_s("%02X  %d\n", Temp.NumberOfReloc, Temp.NumberOfReloc);
        str.Format(L"%02X",Temp.NumberOfReloc);
        CString str1;
        str1.Format(L"%d",Temp.NumberOfReloc);
        m_FirstReloc.SetItemText(j,3,str+L" "+str1);
        //dwCount=Temp.NumberOfReloc;
    
        m_VecpBseRInfo.push_back(pBasR);
        //讲一个区域重定位信息添加
        m_VecRelocAreaInfo.push_back(Temp);
        pBasR=(PIMAGE_BASE_RELOCATION)((long)pBasR+pBasR->SizeOfBlock);
        j++;
      }
      int i=0;
    }
    
    void MyRelocation::OnNMClickList(NMHDR *pNMHDR,LRESULT *pResult)
    {
    
      POSITION pos = m_FirstReloc.GetFirstSelectedItemPosition();
      int nIndex=(int)pos;
      if (pos == NULL)//判断是否为空
      {
        return;
      }
      m_SecondReloc.DeleteAllItems();
      int i=0;
      CString str;
    
      //得到第三个成员的TYPEOFFEST起始位置 之后开始循环获取重定位信息
      PTYPEOFFSET pOffset=(PTYPEOFFSET)((long)m_VecpBseRInfo[nIndex-1]+sizeof(IMAGE_BASE_RELOCATION));
      int z=m_VecRelocAreaInfo[nIndex-1].NumberOfReloc;
      for (DWORD i=0;i<m_VecRelocAreaInfo[nIndex-1].NumberOfReloc;i++)
      {
        //printf_s("索引:%d  ",i);
        str.Format(L"%d",i+1);
        m_SecondReloc.InsertItem(i,str);
        RELOCINFO RelocInfoTemp={0};
        //需要重定位的虚拟地址(RVA)
        RelocInfoTemp.dwRelocRVA=m_VecRelocAreaInfo[nIndex-1].dwAreaRVA+pOffset->Offset;
      //  printf_s("RVA:%08X  ", RelocInfoTemp.dwRelocRVA);
        str.Format(L"%08X",RelocInfoTemp.dwRelocRVA);
        m_SecondReloc.SetItemText(i,1,str);
        //根据相对虚拟地址算出的文件偏移
        RelocInfoTemp.dwOffset=RelCalcOffset(RelocInfoTemp.dwRelocRVA,AnalPE.pNtH,NULL,NULL);
      //  printf_s("偏移:%08X  ", RelocInfoTemp.dwOffset);
        str.Format(L"%08X", RelocInfoTemp.dwOffset);
        m_SecondReloc.SetItemText(i,2,str);
        //重定位方式
        RelocInfoTemp.bType=pOffset->Type;
        //printf_s("类型:HIGHLOW (%d)  ",RelocInfoTemp.bType);
        str.Format(L"HIGHLOW (%d)", RelocInfoTemp.bType);
        m_SecondReloc.SetItemText(i,3,str);
        //从算出的文件偏移取出的数据 这个数据就是需要重定位的虚拟地址(VA)
        RelocInfoTemp.dwRelocValue=*(PDWORD)((long)AnalPE.buf+RelocInfoTemp.dwOffset);
        //printf_s("FAR地址:%08X  ",RelocInfoTemp.dwRelocValue);
        str.Format(L"%08X", RelocInfoTemp.dwRelocValue);
        m_SecondReloc.SetItemText(i,4,str);
        //RelocInfoTemp.bData
        DWORD VA= RelCalcOffset(RelocInfoTemp.dwRelocValue,AnalPE.pNtH,AnalPE.buf,NULL,(PCHAR)RelocInfoTemp.bData,2);
        RelCalcOffset(VA,AnalPE.pNtH,AnalPE.buf,NULL,(PCHAR)RelocInfoTemp.bData,1);
        CString str1;
        CString str2;
        for (int j=0;j<10;j++)
        {
          //判断是否在有效字符32-126区间内
          if (32<=(RelocInfoTemp.bData)[0]&&(RelocInfoTemp.bData)[0]<=126)
          {
            //printf_s("%c",(RelocInfoTemp.bData)[j]);
    
            str1.Format(L"%c",(RelocInfoTemp.bData)[j]);
            str2+=str1;
          }
          else
          {
            //printf_s("%02X ",(RelocInfoTemp.bData)[j]);
            str1.Format(L"%02X",(RelocInfoTemp.bData)[j]);
            str2+=L" "+str1;
          }    
        }
        m_SecondReloc.SetItemText(i,5,str2);
      //  printf_s("\n");
        pOffset++;
      }
    
    }
    
    


    计算位置计算器相关信息(与[上面的B]计算偏移一致 加了点料进去而已)
    MyFileLocation.h  MyFileLocation.cpp
    
    DWORD MyFileLocation::ExclusiveCalcOffset(DWORD Rva)
    {
      //循环比较在那个区段  不在这个区段就继续循环  
      //PIMAGE_NT_HEADERS32 pnt=pNtH;
      PIMAGE_SECTION_HEADER pSecHTemp=IMAGE_FIRST_SECTION(AnalPE.pNtH);//区段头
      int index=0;
      while (!(Rva>=pSecHTemp->VirtualAddress&&
        Rva<pSecHTemp->VirtualAddress+pSecHTemp->SizeOfRawData))
      {
        //找完所有区段还没有找到
        if (index>AnalPE.pNtH->FileHeader.NumberOfSections)
        {
            m_Section=L"部首";
          ////  DWORD a[5];
          //  _memccpy(&Address,pSecHTemp,6,24);
          //  //Address=(int);      
    
          return Rva;
        }
        ++index;
        ++pSecHTemp;
      }
      PBYTE iiii=(PBYTE)(Rva-pSecHTemp->VirtualAddress+pSecHTemp->PointerToRawData+(long)AnalPE.buf);
      //CString aa;
      //十六进制编辑器也可以在这做文章
      for (int i=0;i<10;i++)
      {
        CString jj;
        jj.Format(L"%02x ",*(iiii++));
        m_Byte+=jj;
      }
      m_Section=pSecHTemp->Name;
      return Rva-pSecHTemp->VirtualAddress+pSecHTemp->PointerToRawData;;
    }
    

    就是这些了 。 慢慢看。

    ------------------------------
    源码:
    简易PE.rar

    [培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

    上传的附件:
    收藏
    免费 12
    支持
    分享
    最新回复 (30)
    雪    币: 6890
    活跃值: (8944)
    能力值: ( LV17,RANK:797 )
    在线值:
    发帖
    回帖
    粉丝
    2
    能分享一下完整的源码吗?
    2015-11-29 14:27
    0
    雪    币: 1176
    活跃值: (1234)
    能力值: ( LV12,RANK:380 )
    在线值:
    发帖
    回帖
    粉丝
    3
    有下载啊 就是完整的了
    2015-11-29 14:44
    0
    雪    币: 8865
    活跃值: (2379)
    能力值: ( LV12,RANK:760 )
    在线值:
    发帖
    回帖
    粉丝
    4
    不论代码如何,我先给你点个赞。
    2015-11-29 15:10
    0
    雪    币: 440
    活跃值: (963)
    能力值: ( LV3,RANK:30 )
    在线值:
    发帖
    回帖
    粉丝
    5
    楼主好努力啊,要像楼主学习啊
    2015-11-29 15:56
    0
    雪    币: 1176
    活跃值: (1234)
    能力值: ( LV12,RANK:380 )
    在线值:
    发帖
    回帖
    粉丝
    6
    哈哈 感谢~
    2015-11-29 16:11
    0
    雪    币: 1176
    活跃值: (1234)
    能力值: ( LV12,RANK:380 )
    在线值:
    发帖
    回帖
    粉丝
    7
    哈哈  
    2015-11-29 16:16
    0
    雪    币: 4580
    活跃值: (992)
    能力值: ( LV4,RANK:50 )
    在线值:
    发帖
    回帖
    粉丝
    8
    伸手党路过,顺便偷点代码
    2015-11-29 17:12
    0
    雪    币: 95
    活跃值: (119)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    9
    这要点个赞
    2015-11-29 19:12
    0
    雪    币: 375
    活跃值: (181)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    10
    向辛劳的楼主致敬。
    2015-11-29 19:28
    0
    雪    币: 10865
    活跃值: (2838)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    11
    大赞~支持~~
    2015-11-29 19:56
    0
    雪    币: 1
    活跃值: (10)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    12
    前几天发的是控制台,这次直接发对话框了,膜拜!!!
    2015-11-29 21:18
    0
    雪    币: 8026
    活跃值: (2511)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    13
    努力学习
    2015-11-29 21:40
    0
    雪    币: 102
    活跃值: (19)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    14
    有源码必须顶。。再学习。
    2015-11-30 13:15
    0
    雪    币: 5511
    活跃值: (2072)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    15
    简单明了,点赞!
    2015-12-1 09:49
    0
    雪    币: 53
    活跃值: (40)
    能力值: ( LV3,RANK:30 )
    在线值:
    发帖
    回帖
    粉丝
    16
    学习一下,
    2016-1-13 14:04
    0
    雪    币: 1244
    活跃值: (1267)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    17
    为了不让人家说我是伸手党  我还是回复一下  等研究完代码再回来回复
    2019-5-10 21:16
    0
    雪    币: 1244
    活跃值: (1267)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    18
    楼主能说一下编译环境吗?我用VS2019编译报错很多
    最后于 2019-5-10 21:40 被cmputer编辑 ,原因:
    2019-5-10 21:31
    0
    雪    币: 1244
    活跃值: (1267)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    19
    谢谢大佬,VS2012编译通过了,谢谢
    2019-5-10 21:42
    0
    雪    币: 5262
    活跃值: (2964)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    20
    感谢楼主分享,借鉴一下
    2019-5-10 23:56
    0
    雪    币: 2428
    活跃值: (159)
    能力值: ( LV11,RANK:198 )
    在线值:
    发帖
    回帖
    粉丝
    21
    厉害,收藏了
    2019-5-19 22:10
    0
    雪    币: 3021
    活跃值: (241)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    22
    感谢学习下。。
    2019-5-20 01:28
    0
    雪    币: 670
    活跃值: (59)
    能力值: ( LV3,RANK:20 )
    在线值:
    发帖
    回帖
    粉丝
    23
    下载下来研究研究,复习一下PE知识
    2019-6-1 13:43
    0
    雪    币: 1622
    活跃值: (3805)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    24
    很用心,帮顶
    2019-6-6 19:08
    0
    雪    币: 0
    活跃值: (136)
    能力值: ( LV2,RANK:10 )
    在线值:
    发帖
    回帖
    粉丝
    25
    很不错的资源
    2020-10-20 17:41
    0
    游客
    登录 | 注册 方可回帖
    返回
    //