首页
社区
课程
招聘
[原创]PE节表头的调整 解决畸形PE中RVAToFileOffset错误
发表于: 2012-6-19 11:53 5519

[原创]PE节表头的调整 解决畸形PE中RVAToFileOffset错误

2012-6-19 11:53
5519
PE 获取导入表 导出表 节信息等都需要RVAToFileOffset,这个函数里面依赖于节表头的信息.在畸形PE中节表头里面的字段有些是不对的,需要调整,实际中发现PEID0.94对这种情况无能为力,但是0.95却可能轻松应对,于是调试了下PEID0.95 ,发现他的RVAToFileOffset和网络上流传的并无区别,只是在调用它之前已经对节表头进行了调整,具体在0045D6B0函数中,于是分析了下这个函数发现了调用方法和具体参数,我们可以在调整节表后再调用RVAToFileOffset就可以了,下面是IDA 结合自己分析的那个函数代码

附件中有例子和VC6的工程代码,里面的例子路径根据实际路径修改下
ShowPeInFo("C:\\1.exe");("C:\\1.exe")改为实际路径


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// this2 + 0 pMap             IN
//      + 4 FileSize         IN
//      + 8 pMap             IN
//      + 12 pNtHeader       IN
//      + 16 pFileHeader     IN
//      + 20 pOptionHeader   IN
//      + 24 第一个节表头    IN
//      + 28 第一个节表头 新分配内存中的 经过调整后的节表头  OUT
//      + 32 节数目          IN
//      + 36 文件粒度        IN
//      + 40 FileAlignment - 1  IN
//      + 44 SectionAlignment - 1 IN
//   
char __thiscall my_TiaoZhengSecHeader(int this2, char a2)
{
  int this1; // esi@1
  int pOptionalHeader; // eax@1
  int pFileHeader; // edx@1
  int NumOfSection; // ecx@1
  unsigned int v6; // eax@2
  char v7; // bl@2
  int pVirtualAddress; // ecx@3
  void *pMallocSecHeader; // eax@7
  void *pMallocSecHeader1; // edi@7
  int FileSize; // eax@8
  int pFirstSecHeader; // esi@8
  char result; // al@8
  unsigned int v14; // ebx@12
  int pPointerToRawData; // eax@13
  int SizeOfRawData; // edx@18
  int v17; // edi@20
  int VirtualSize; // ecx@20
  int VirtualSize2; // ecx@20
  int VirtualAddress; // edx@20
  int PointerToRawData; // edx@25
  unsigned int FileSize2; // ecx@25
  unsigned int v23; // edi@27

  this1 = this2;
  pOptionalHeader = *(_DWORD *)(this2 + 20);
  *(_DWORD *)(this2 + 40) = *(_DWORD *)(pOptionalHeader + 36) - 1;// FileAlignment - 1
  *(_DWORD *)(this2 + 44) = *(_DWORD *)(pOptionalHeader + 32) - 1;// SectionAlignment - 1
  pFileHeader = *(_DWORD *)(this2 + 16);
  *(_DWORD *)(this2 + 36) = (*(_DWORD *)(pOptionalHeader + 60) + 511) & 0xFFFFFE00;// +60 = SizeOfHeaders
  NumOfSection = *(_WORD *)(pFileHeader + 2);
  *(_DWORD *)(this1 + 32) = NumOfSection;
  if ( *(_DWORD *)(pOptionalHeader + 32) < 0x1000u )// SectionAlignment < 0x1000
  {
    v6 = 0;
    v7 = 1;
    if ( !NumOfSection )
    {
LABEL_6:
      *(_DWORD *)(this1 + 32) = 1;
      goto LABEL_7;
    }
    pVirtualAddress = *(_DWORD *)(this1 + 24) + 12;
    while ( *(_DWORD *)(pVirtualAddress + 8) == *(_DWORD *)pVirtualAddress )
    {
      ++v6;
      pVirtualAddress += 40;
      if ( v6 >= *(_DWORD *)(this1 + 32) )
        goto LABEL_6;
    }
    if ( a2 )
      return 0;
  }
  v7 = 0;
LABEL_7:
  pMallocSecHeader = malloc(40 * *(_DWORD *)(this1 + 32));// 节头大小 * 节数目
  pMallocSecHeader1 = pMallocSecHeader;
  *(_DWORD *)(this1 + 28) = pMallocSecHeader;
  if ( v7 )
  {
    *(_DWORD *)pMallocSecHeader = 0;
    *((_DWORD *)pMallocSecHeader + 1) = 0;
    *((_DWORD *)pMallocSecHeader + 2) = 0;
    *((_DWORD *)pMallocSecHeader + 3) = 0;
    *((_DWORD *)pMallocSecHeader + 4) = 0;
    *((_DWORD *)pMallocSecHeader + 5) = 0;
    *((_DWORD *)pMallocSecHeader + 6) = 0;
    *((_DWORD *)pMallocSecHeader + 7) = 0;
    *((_DWORD *)pMallocSecHeader + 8) = 0;
    *((_DWORD *)pMallocSecHeader + 9) = 0;
    FileSize = *(_DWORD *)(this1 + 4);
    *((_DWORD *)pMallocSecHeader1 + 2) = FileSize;
    *((_DWORD *)pMallocSecHeader1 + 4) = FileSize;
    *((_DWORD *)pMallocSecHeader1 + 9) = 0xE00000E0u;
    pFirstSecHeader = *(_DWORD *)(this1 + 24);
    *(_DWORD *)pMallocSecHeader1 = *(_DWORD *)pFirstSecHeader;
    *((_DWORD *)pMallocSecHeader1 + 1) = *(_DWORD *)(pFirstSecHeader + 4);// pSec->VirtualAddress
    result = 1;
  }
  else
  {
    MemCpyN(pMallocSecHeader, *(_DWORD *)(this1 + 24), 40 * *(_DWORD *)(this1 + 32));// 复制节表头到申请的内存中
    v14 = 0;
    if ( *(_DWORD *)(this1 + 32) )              // 节数目
    {
      pPointerToRawData = (int)((char *)pMallocSecHeader1 + 20);
      do
      {
        if ( !*(_DWORD *)(pPointerToRawData - 12) )// MISC == 0
          *(_DWORD *)(pPointerToRawData - 12) = *(_DWORD *)(pPointerToRawData - 4);// VirtualSize = SizeOfRawData
        if ( !*(_DWORD *)pPointerToRawData )    // PointerToRawData == 0
          *(_DWORD *)(pPointerToRawData - 4) = 0;// SizeOfRawData = 0
        SizeOfRawData = *(_DWORD *)(pPointerToRawData - 4);
        if ( !SizeOfRawData )
          *(_DWORD *)pPointerToRawData = 0;
        v17 = SizeOfRawData + (*(_DWORD *)pPointerToRawData & 0x1FF);
        *(_DWORD *)pPointerToRawData &= 0xFFFFFE00u;// 关键一句
        *(_DWORD *)(pPointerToRawData - 4) = v17;// SizeOfRawData = v17
        VirtualSize = *(_DWORD *)(pPointerToRawData - 12);
        *(_DWORD *)(pPointerToRawData - 4) = ((~*(_DWORD *)(this1 + 40) & (*(_DWORD *)(this1 + 40) + v17)) + 511) & 0xFFFFFE00;// + 40 == FileAlignment - 1
        VirtualSize2 = (VirtualSize + 4095) & 0xFFFFF000;
        VirtualAddress = *(_DWORD *)(pPointerToRawData - 8) & 0xFFFFF000;
        *(_DWORD *)(pPointerToRawData - 8) = VirtualAddress;
        *(_DWORD *)(pPointerToRawData - 12) = VirtualSize2;
        if ( (unsigned int)VirtualSize2 < *(_DWORD *)(pPointerToRawData - 4) )
          *(_DWORD *)(pPointerToRawData - 4) = VirtualSize2;
        if ( (unsigned int)VirtualAddress < *(_DWORD *)(this1 + 36) && VirtualAddress )// + 36 = 文件粒度
          *(_DWORD *)(this1 + 36) = VirtualAddress;
        PointerToRawData = *(_DWORD *)pPointerToRawData;
        FileSize2 = *(_DWORD *)(this1 + 4);
        if ( *(_DWORD *)pPointerToRawData <= FileSize2 )
        {
          v23 = *(_DWORD *)(pPointerToRawData - 4);
          if ( v23 > FileSize2 || PointerToRawData + v23 > FileSize2 )
            *(_DWORD *)(pPointerToRawData - 4) = FileSize2 - PointerToRawData;
        }
        else
        {
          *(_DWORD *)(pPointerToRawData - 4) = 0;
        }
        ++v14;
        pPointerToRawData += 40;
      }
      while ( v14 < *(_DWORD *)(this1 + 32) );
    }
    result = 1;
  }
  return result;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 107
活跃值: (404)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这种东西.你只要手上有个样本,自己调试一下就能自己写吧...

还需要逆PEID的?
2012-6-19 14:32
0
雪    币: 217
活跃值: (68)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
3
增加了特殊例子和VC6的工程,2楼的朋友可以看看例子,自己改改试试~~~~
2012-6-21 09:33
0
游客
登录 | 注册 方可回帖
返回
//