首页
社区
课程
招聘
给PE文件增加节的时候出现的问题
发表于: 2010-5-5 16:31 4313

给PE文件增加节的时候出现的问题

2010-5-5 16:31
4313
我的目的是想给PE文件增加一个节,然后把一段代码复制到这个节中去。但是,在复制的时候总是出现 access violation 错误。请大家帮忙看一下是什么问题。
这个是创建 内存映射的代码
hFile=::CreateFile(lpFilename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);//创建文件对象
  
  if (!hFile)           
    return FALSE;
  DWORD dwFileSize = GetFileSize(hFile,NULL);
    dwFileSize += 0x000002000;//增加8Kb,为后面增加节做准备
     hMapping=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,dwFileSize,NULL);//创建内存映射
  if(!hMapping)
  {                  
    CloseHandle(hFile);
    return FALSE;
  }
  ImageBase=MapViewOfFile(hMapping,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);//得到内存映射的基址
    if(!ImageBase)
  {                  
    CloseHandle(hMapping);
    CloseHandle(hFile);
    return FALSE;
  }


下面是增加节的代码

CcheckPE check; // 获取PE头文件信息的类
PIMAGE_FILE_HEADER       pFH=NULL;
PIMAGE_SECTION_HEADER   pFirstSecH;  //第一个块表
PIMAGE_SECTION_HEADER   pLastSecH;//原来的最后一个块表
PIMAGE_OPTIONAL_HEADER   pOH=NULL;


pOH=check.GetOptionalHeader (ImageBase);  //得到 option header 指针
pFirstSecH=check.GetFirstSectionHeader(ImageBase);//得到第一个块表指针
pFH=check.GetFileHeader(ImageBase);//得到 NT HEADER指针

pAddSecH = (PIMAGE_SECTION_HEADER)((DWORD)(pFirstSecH) + (sizeof(IMAGE_SECTION_HEADER) * (pFH->NumberOfSections)));//增加块表
pLastSecH = (PIMAGE_SECTION_HEADER)(((DWORD)(pAddSecH) - sizeof(IMAGE_SECTION_HEADER)));//得到原来的最后一个块表的指针

//判断最后一个节表后面是否有多余空间来增加节表.如果有十个双字是全0则表示有空间。
  for (int i = 0;i < 12;i++)
  {
    if (*((PDWORD)(pAddSecH)+i)!=0)
    {  
    break;
    }
  }


[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 137
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
下面是增加节表 各个参数的代码

if(i>=10)
		
{//有空间增加节表,开始增加
pFH->NumberOfSections=pFH->NumberOfSections+1;

DWORD   dwNewSecAlign = getAlign(pLastSecH->VirtualAddress + pLastSecH->Misc.VirtualSize,pOH->SectionAlignment);//新加节对齐后的内存RVA
DWORD dwNewFileAlign = getAlign(pLastSecH->PointerToRawData+pLastSecH->SizeOfRawData,pOH->FileAlignment);//新加节对齐后的文件RVA
pOH->SizeOfImage += getAlign(0x00001000,pOH->SectionAlignment);
memcpy(pAddSecH->Name,".new",8); //给新块命名
			
pAddSecH->VirtualAddress = dwNewSecAlign;
pAddSecH->Misc.VirtualSize = 0x00001000;
pAddSecH->PointerToRawData = dwNewFileAlign;
pAddSecH->SizeOfRawData = getAlign(0x00001000,pOH->FileAlignment);
pAddSecH->Characteristics = 0xE0000020; //Characteristics

lpSec=(LPVOID)((DWORD)ImageBase +pAddSecH->VirtualAddress );//新块的绝对地址,也即代码块的起始地址

::memcpy(lpSec,pdata,sizeof(pdata));//将要添加的数据复制进新的节,pdata是一个数组

2010-5-5 16:35
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
3
2010-5-5 16:39
0
雪    币: 137
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢LS
不过那里找不到答案。

我调试的时候,发现新加的节,也就是在创建内存映射的时候增加的那部分映射无法读。有朋友知道这是什么原因么?
2010-5-6 11:33
0
雪    币: 360
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rol
5
无法读?难道节属性有问题?
看错了,你说的好像是内存映射无法复制。。。。。。。
2010-5-6 12:40
0
雪    币: 137
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
不是节属性的问题~
刚调试的时候,我查看内存,发现内存映射文件还是以文件的方式存在内存中,也就是说只能用文件里的地址来读各个节的数据。我的代码中用的是内存的地址读的,所以会出错。
但是又有新的问题出现,内存映射文件包含了exe文件的调试信息,这个调试信息在最后一个节的后面。这样子我创建内存映射文件时扩充的空间就在调试信息的后面了,那我怎么来添加节呢?难道添加在调试信息的后面?
2010-5-6 12:48
0
雪    币: 137
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
这个问题比较急~~~
哪位朋友 帮帮忙 告诉我一下~~~~
2010-5-6 13:07
0
雪    币: 137
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
还想问一下:
是不是程序加了壳,那么它的节表的信息就不准确了。
比如说,从节表中查到它的最后一个节在 地址A截止。但是地址A后面其实还有数据~~~~
2010-5-6 15:40
0
雪    币: 137
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
试了一下,有些程序最后一个节后面没有了数据,有些程序最后一个节后面有数据。我想可能是因为某些程序加了壳的原因。
2010-5-6 16:23
0
雪    币: 360
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rol
10
有这种可能,3楼也说过这个问题,有时间我也试一下
2010-5-6 16:37
0
雪    币: 137
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
问题基本上解决了~
多谢上面几位的回答~~~
2010-5-7 17:17
0
游客
登录 | 注册 方可回帖
返回
//