首页
社区
课程
招聘
[旧帖] [己解决]一段感染EXE文件的代码,对偏移量的疑惑 0.00雪花
发表于: 2008-2-23 19:19 4794

[旧帖] [己解决]一段感染EXE文件的代码,对偏移量的疑惑 0.00雪花

2008-2-23 19:19
4794
以下代码从《加密解密技术内幕》中选取

if(strstr((const char *)header->section_header[0].Name,".text")!=NULL)
{
virtsize=header->section_header[0].Misc.VirtualSize;
//此段的真实长度
physaddress=header->section_header[0].PointerToRawData;
//此段的物理偏移
physsize=header->section_header[0].SizeOfRawData;
//此段的物理长度
peaddress=dos_head->e_lfanew;
//得到PE文件头的开始偏移

peHeader peH;
tmpaddress=(unsigned long )&peH;
//得到结构的偏移
tmpaddress1=(unsigned long )&(peH.section_header[0].Characteristics);
//得到变量的偏移
flagaddress=tmpaddress1-tmpaddress+2;
//得到属性的相对偏移
flags=0x8000;
//一般情况下,“.text”段是不可读写的,如果我们要把数据写入这个段需要改变其属性,实际上这个程序并没有把数据写入“.text”段,所以并不需要更改,但如果你实现复杂的功能,肯定需要数据,肯定需要更改这个值,

space=physsize-virtsize;
//得到代码段的可用空间,用以判断可不可以写入我们的代码
//用此段的物理长度减去此段的真实长度就可以得到
progRAV=header->opt_head.ImageBase;
//得到程序的装载地址,一般为400000
codeoffset=header->opt_head.BaseOfCode-physaddress;
//得到代码偏移,用代码段起始RVA减去此段的物理偏移
//应为程序的入口计算公式是一个相对的偏移地址,计算公式为:
//代码的写入地址+codeoffset


entrywrite=header->section_header[0].PointerToRawData+header->section_header[0].Misc.VirtualSize;
//代码写入的物理偏移
mods=entrywrite%16;
//对齐边界
if(mods!=0)
{
entrywrite+=(16-mods);
}
oldentryaddress=header->opt_head.AddressOfEntryPoint;
//保存旧的程序入口地址
newentryaddress=entrywrite+codeoffset;
//计算新的程序入口地址
return;
}


我的问题是codeoffset=header->opt_head.BaseOfCode-physaddress;
有什么用?我的理解是BaseOfCode是段在内存中的偏移,physaddress是段在硬盘中相对于文件的偏移,他们相减等于程序在加载是由于“内存对齐?”而产生的空隙,不知理解对否?

第二个问题:newentryaddress为什么要加上codeoffset?我觉得直接等于entrywrite好了

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
2
entrywrite=header->section_header[0].PointerToRawData+header->section_header[0].Misc.VirtualSize;
//代码写入的物理偏移

也就是这个偏移(entrywrite)是相当对文件头的偏移

而实际的程序入口(newentryaddress)是内存中相当对于加载基址的偏移(RVA)

这两都如何转换呢?这就要用到那个codeoffset 
codeoffset=header->opt_head.BaseOfCode-physaddress;
//得到代码偏移,用代码段起始RVA减去此段的物理偏移
//应为程序的入口计算公式是一个相对的偏移地址,计算公式为:
//代码的写入地址+codeoffset


其实这是个数学题,上面可能从直观上不容易理解,我们把上面的问题转化成数学题:

newentryaddress = entrywrite +codeoffset
codeoffset = BaseofCode - Rawoffset

我们把他写成这样可能更容易让人理解:

newentryaddress = entrywrite - Rawoffset + BaseofCode

entrywrite - Rawoffset 等于我们写代码的位置相当对于代码段开始始位置的偏移(均指文件中),因为这是个偏移,所以它也等于加载入内存后,我们的代码相对于代码段加载基址的偏移。(即内存中)
此时得到的这个偏移+BaseofCode 就是代码相对于程序加载基址(ImageBase)的偏移。这个偏移就是我们常说的EntryPoint。
2008-2-23 20:57
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
msy
3
终于明白了~
非常感谢大侠为我解答~顶~
2008-2-23 21:31
0
游客
登录 | 注册 方可回帖
返回
//