首页
社区
课程
招聘
[原创]PE文件格式学习小结 之 文件偏移地址计算器功能的实现
发表于: 2008-7-6 13:21 16508

[原创]PE文件格式学习小结 之 文件偏移地址计算器功能的实现

2008-7-6 13:21
16508
【文章标题】: 谈一下LoadPE的FLC功能的编程实现
【文章作者】: 美丽の破船
【作者邮箱】: juxingting@163.com
【作者主页】: http://hi.baidu.com/juxingting
【编写语言】: C/C++
【操作平台】: XP + VC6.0
【作者声明】: 学PE文件格式的练习程序,发出来供象我一样菜的朋友共同进步!程序实现的算法很笨,往高手指教!
【详细内容】:

    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的方法也可想出来了,只不过是把上面的方法倒过来就可以了~~~
   下面我给出我写的代码:

void CTESTDlg::OnExec() 
{
	UpdateData(TRUE);
	DWORD Temp;
	if(((CButton*)GetDlgItem(IDC_RVA))->GetCheck())
	{
		sscanf(m_RvaCNT,"%X",&Temp);
		m_VaCNT.Format("%.8x",(m_ImgBase + Temp));
		if(Temp <= m_Sections[m_NumberOfSections-1].VirtualAddress + m_Sections[m_NumberOfSections-1].SizeOfRawData)
		{
			for(int a = 0;a < m_NumberOfSections;a++)
			{
				if(Temp >= m_Sections[a].VirtualAddress && Temp <= (m_Sections[a].VirtualAddress + m_Sections[a].SizeOfRawData))
				{
					m_OffCNT.Format("%.8x",(Temp - m_Sections[a].VirtualAddress)+m_Sections[a].PointerToRawData);
					m_SecName.Format("%s",m_Sections[a].Name);
					sscanf(m_OffCNT,"%X",&Temp);
					m_Content = GetHexContent(Temp);
				}
			}
		}
		else
		{
			MessageBox("超出范围了!!!");
			m_VaCNT = "";
			m_RvaCNT = "";
			m_OffCNT = "";
		}
	}
	else if(BST_CHECKED == ((CButton*)GetDlgItem(IDC_VA))->GetCheck())
	{
		sscanf(m_VaCNT,"%X",&Temp);
		m_RvaCNT.Format("%.8x",(Temp - m_ImgBase));
		sscanf(m_RvaCNT,"%X",&Temp);
		if(Temp <= m_Sections[m_NumberOfSections-1].VirtualAddress + m_Sections[m_NumberOfSections-1].SizeOfRawData)
		{
			for(int a = 0;a < m_NumberOfSections;a++)
			{
				if(Temp >= m_Sections[a].VirtualAddress && Temp <= (m_Sections[a].VirtualAddress + m_Sections[a].SizeOfRawData))
				{
					m_OffCNT.Format("%.8x",(m_Sections[a].PointerToRawData + (Temp - m_Sections[a].VirtualAddress)));
					m_SecName.Format("%s",m_Sections[a].Name);
					sscanf(m_OffCNT,"%X",&Temp);
					m_Content = GetHexContent(Temp);
				}
			}
		}
		else
		{
			MessageBox("超出范围了!!!");
			m_VaCNT = "";
			m_RvaCNT = "";
			m_OffCNT = "";
		}
	}
	else if(BST_CHECKED == ((CButton*)GetDlgItem(IDC_OFF))->GetCheck())
	{
		sscanf(m_OffCNT,"%X",&Temp);
		if(Temp <= (m_Sections[m_NumberOfSections-1].PointerToRawData + m_Sections[m_NumberOfSections-1].SizeOfRawData))
		{
			for(int a = 0;a < m_NumberOfSections;a++)
			{
				if(Temp >= m_Sections[a].PointerToRawData && Temp <= (m_Sections[a].PointerToRawData + m_Sections[a].SizeOfRawData))
				{
					m_RvaCNT.Format("%.8x",(m_Sections[a].VirtualAddress + (Temp - m_Sections[a].PointerToRawData)));
					m_VaCNT.Format("%.8x",(m_Sections[a].VirtualAddress + (Temp - m_Sections[a].PointerToRawData) + m_ImgBase));
					m_SecName.Format("%s",m_Sections[a].Name);
					sscanf(m_OffCNT,"%X",&Temp);
					m_Content = GetHexContent(Temp);
				}
			}
		}
		else
		{
			MessageBox("超出范围了!!!");
			m_VaCNT = "";
			m_RvaCNT = "";
			m_OffCNT = "";
		}
	}
	m_RvaCNT.MakeUpper();
	m_VaCNT.MakeUpper();
	m_OffCNT.MakeUpper();

	UpdateData(FALSE);
}
  

具体的代码,大家可以看附件!
希望我这个烂文章能对向我一样梦想自己成为高手的朋友有所帮助!
最后,祝大家成功!!加油~~
【附件下载】: 文件地址转换器及VC源码.rar
--------------------------------------------------------------------------------

                                                       2008年07月06日 12:26:35

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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (19)
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ppt
2
破船兄辛苦了,谢谢分享,学习了
2008-7-6 13:31
0
雪    币: 86
活跃值: (34)
能力值: ( LV2,RANK:150 )
在线值:
发帖
回帖
粉丝
3
写的不错,友情帮顶了。。。。。。
2008-7-6 13:31
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习顺便收藏了。。
2008-7-6 13:36
0
雪    币: 63
活跃值: (17)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
5
学习一下
2008-7-7 07:30
0
雪    币: 82
活跃值: (10)
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
6
可以继续研究下去,把所获得的地址,按照pe的结构解析出来,做一个简单的pe编辑器
2008-7-7 07:35
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
7
学习~

.
2008-7-7 07:44
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
8
看来一大早有不少人活动哇

比偶早多了
2008-7-7 07:50
0
雪    币: 65
活跃值: (811)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
9
谢谢你的建议,我已经开始写这个PE编辑器了,功能和界面基本上就是防的LoadPE的PE编辑器~(估计暑假结束的时候就可以完成了~~~)
2008-7-7 09:24
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
10
当时候记得要开源啊,

来ding你哦~

"ding你" 2个字竟然被屏蔽了 - -
2008-7-7 09:36
0
雪    币: 190
活跃值: (20)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
11
呵呵,支持开源...............
2008-7-7 10:08
0
雪    币: 65
活跃值: (811)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
12
我从你的程序里学了很多的东西呢~~~
不开源就对不住你共享出来的代码了~~~
再说了,`~本来就是学习用的程序
2008-7-7 12:09
0
雪    币: 563
活跃值: (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
顶学习!!!!!!!
2008-7-7 12:35
0
雪    币: 259
活跃值: (26)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
14
不错不错,继续努力
2008-7-7 19:00
0
雪    币: 421
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
哈哈,很方便的话必定收藏了
确实有时候需要
2008-7-14 15:07
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
写得很好,收藏个软件
2008-11-30 21:17
0
雪    币: 200
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
刚看下就有问题了
Temp <= m_Sections[m_NumberOfSections-1].VirtualAddress + m_Sections[m_NumberOfSections-1].SizeOfRawData

VirtualAddress是内存中虚拟的,SizeOfRawData是文件中的,不能这样加起来,应该用
VirtualAddress+VirtualSize-1
2008-12-6 21:51
0
雪    币: 74
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
收藏了~~
2009-11-9 15:20
0
雪    币: 133
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
楼主辛苦了~学习收藏了
2009-11-15 10:08
0
雪    币: 244
活跃值: (169)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
现在工具都给计算好了,俺一时都不知道咋算的,来这边学习下
2017-8-17 17:47
0
游客
登录 | 注册 方可回帖
返回
//