聚星亭

吾笨笨且懒散兮 急须改之而奋进

  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  2 随笔 :: 3 文章 :: 3 评论 :: 0 Trackbacks
LoadPE的功能强大想必是众所周知的!
    小弟我最近在学习PE文件格式,为了巩固自己的所学,我也在模仿LoadPE的PE编辑器功能!
    昨天,我把它的FLC功能给实现了,个人认为收获不小,颇为激动。
    在失眠了一夜之后,终于耐不住、来发帖子,与大家分享我的所得!(说不定,再让我骗来个精华~ )
    程序用的是最笨的方法,外加笨人比较愚笨,代码写的也罗嗦无比!故高手飘过~~~ 

    闲话不说了,说主题:
    在学习《加密与解密》(第二版)的时候,书里说的根据RVA计算文件偏移的方法如下:
 引用书中的内容        1、先遍历区段表中每个区段的Virtual Offset得到每个节的起始RVA,并根据SizeOfRawData属性得到每个节的结束RVA
        2、再根据第一步的结果判断要转换的RVA属于哪个区段内
        3、然后根据区段表中相应区段的Virtual Offset和Raw Offset的值来计算出每个区段中,它们两个的差值:△k
        4、最后就可以根据公式转换了!
          ·RVA = VA - ImageBase;
          ·File Offset = RVA - △k;

    可是怎么根据File Offset来计算RVA就不知道怎么办了~~

    随着我对PE文件结构的了解越来越深,慢慢的我才知道:节的PointerToRawData属性就是它在文件中的偏移地址! 

    这样一来,它们之间转换的方法就变成了:
适合程序中实现的方法        1、先遍历区段表中每个区段的Virtual Offset得到每个节的起始RVA,并根据SizeOfRawData属性得到每个节的结束RVA
        2、再根据第一步的结果判断要转换的RVA属于哪个区段内
        3、然后用要转换的RVA - 它所在的起始RVA 得到 这个RVA位于起始RVA的偏移RVA'
        4、最后取出它所在段的PointerToRawData属性值加上上一步算出来了RVA' 便得到它的文件偏移地址了!

  从文件偏移转换到RVA的方法也可想出来了,只不过是把上面的方法倒过来就可以了~~~ 
   下面我给出我写的代码:

 1void CTESTDlg::OnExec() 
 2{
 3  UpdateData(TRUE);
 4  DWORD Temp;
 5  if(((CButton*)GetDlgItem(IDC_RVA))->GetCheck())
 6  {
 7    sscanf(m_RvaCNT,"%X",&Temp);
 8    m_VaCNT.Format("%.8x",(m_ImgBase + Temp));
 9    if(Temp <= m_Sections[m_NumberOfSections-1].VirtualAddress + m_Sections[m_NumberOfSections-1].SizeOfRawData)
10    {
11      for(int a = 0;a < m_NumberOfSections;a++)
12      {
13        if(Temp >= m_Sections[a].VirtualAddress && Temp <= (m_Sections[a].VirtualAddress + m_Sections[a].SizeOfRawData))
14        {
15          m_OffCNT.Format("%.8x",(Temp - m_Sections[a].VirtualAddress)+m_Sections[a].PointerToRawData);
16          m_SecName.Format("%s",m_Sections[a].Name);
17          sscanf(m_OffCNT,"%X",&Temp);
18          m_Content = GetHexContent(Temp);
19        }

20      }

21    }

22    else
23    {
24      MessageBox("超出范围了!!!");
25      m_VaCNT = "";
26      m_RvaCNT = "";
27      m_OffCNT = "";
28    }

29  }

30  else if(BST_CHECKED == ((CButton*)GetDlgItem(IDC_VA))->GetCheck())
31  {
32    sscanf(m_VaCNT,"%X",&Temp);
33    m_RvaCNT.Format("%.8x",(Temp - m_ImgBase));
34    sscanf(m_RvaCNT,"%X",&Temp);
35    if(Temp <= m_Sections[m_NumberOfSections-1].VirtualAddress + m_Sections[m_NumberOfSections-1].SizeOfRawData)
36    {
37      for(int a = 0;a < m_NumberOfSections;a++)
38      {
39        if(Temp >= m_Sections[a].VirtualAddress && Temp <= (m_Sections[a].VirtualAddress + m_Sections[a].SizeOfRawData))
40        {
41          m_OffCNT.Format("%.8x",(m_Sections[a].PointerToRawData + (Temp - m_Sections[a].VirtualAddress)));
42          m_SecName.Format("%s",m_Sections[a].Name);
43          sscanf(m_OffCNT,"%X",&Temp);
44          m_Content = GetHexContent(Temp);
45        }

46      }

47    }

48    else
49    {
50      MessageBox("超出范围了!!!");
51      m_VaCNT = "";
52      m_RvaCNT = "";
53      m_OffCNT = "";
54    }

55  }

56  else if(BST_CHECKED == ((CButton*)GetDlgItem(IDC_OFF))->GetCheck())
57  {
58    sscanf(m_OffCNT,"%X",&Temp);
59    if(Temp <= (m_Sections[m_NumberOfSections-1].PointerToRawData + m_Sections[m_NumberOfSections-1].SizeOfRawData))
60    {
61      for(int a = 0;a < m_NumberOfSections;a++)
62      {
63        if(Temp >= m_Sections[a].PointerToRawData && Temp <= (m_Sections[a].PointerToRawData + m_Sections[a].SizeOfRawData))
64        {
65          m_RvaCNT.Format("%.8x",(m_Sections[a].VirtualAddress + (Temp - m_Sections[a].PointerToRawData)));
66          m_VaCNT.Format("%.8x",(m_Sections[a].VirtualAddress + (Temp - m_Sections[a].PointerToRawData) + m_ImgBase));
67          m_SecName.Format("%s",m_Sections[a].Name);
68          sscanf(m_OffCNT,"%X",&Temp);
69          m_Content = GetHexContent(Temp);
70        }

71      }

72    }

73    else
74    {
75      MessageBox("超出范围了!!!");
76      m_VaCNT = "";
77      m_RvaCNT = "";
78      m_OffCNT = "";
79    }

80  }

81  m_RvaCNT.MakeUpper();
82  m_VaCNT.MakeUpper();
83  m_OffCNT.MakeUpper();
84
85  UpdateData(FALSE);
86}

87
具体的代码,大家可以看附件!
希望我这个烂文章能对向我一样梦想自己成为高手的朋友有所帮助!
最后,祝大家成功!!加油~~
附件PE文件地址转换器
posted on 2008-11-01 11:40 美丽の破船 阅读(754) 评论(0)  编辑 收藏 引用 所属分类: C/C++/VC/MFC
只有注册用户登录后才能发表评论。