滴水逆向联盟
标题:
获取PE中空隙的大小和地址
[打印本页]
作者:
夺命书生
时间:
2014-12-11 12:54
标题:
获取PE中空隙的大小和地址
要插入代码到程序中?哇,这听起来好酷哦。
不过,做起来就有一点困难了。首先要知道哪里可以插入?
慢点,好像我们也可以自己为PE添加一个Section来做,不必插入代码。
呵呵。。。当然可以了,不过这帖中带领大家来到PE格式之旅第一旅:先寻找有没有可以插入的代码点。
我们都知道磁盘上的PE和内容上的PE存在很大的不同的。其中这贴中我们最关心的应该是文件对齐的问题了。
我们用工具LoadPe很简单就看到,一般程序在磁盘上的对齐大小是0x200,而在内存上就是0x1000,不过
如果程序的作者在写的时候可以通过改变连接方式来改变这个值
比如#pragma comment(linker,"/align:0x300")就可以改变内存对齐,而#pragma comment(linker,"/filealign:0x300")
就是把文件对齐设为0x300大小。这个编译的域,分别对应于PE文件中的两个域,我们可以自己读出来!
不管怎么说如果采用默认的方式的话,还是会产生PE空隙的,如果我们能把这段空隙利用起来,那我们就能
不改变原大小的情况下来插入代码了。。。。好了。。。好了。。。这些概念貌似太简单了。。。很多资料和
前辈都有说过了。问题是如何计算空隙的大小和开始的地址,这个简单!(帖子刚开始嘛,水平也有限,而且大想法就是有
小想法一个一个组成的)
一些计算公式是这样的:
//空隙计算公式:
//空隙大小 = SizeOfRawData - Misc.VirtualSize - 1;
//节的起始点 = PointerToRawData;
//空隙起始点 = PointerToRawData + Misc.VirtualSize;
哇,太简单了。有些朋友就等不捞了,没有耐心了,包括我。。。呵呵。。。不过真正的黑客是最有耐心的,我这样告诉我自己,小知识
变成大知识!
代码很少,也只是测试代码,就直接上来了。
unsigned long g_psection=0;//point to section start
typedef struct _sect_
{
char secname[256];//section name,0x100
long gapsize;
PVOID secstart;
PVOID gapstart;
}sect,*psect;
sect g_section[50]={0};
unsigned long g_filealign=0;//文件对齐值
unsigned long g_viralign=0;//内存对齐值
unsigned short g_type=0;//可以进行一些dll,或exe的判读,分别对文件的类型进行感染是不同的
unsigned short g_secnumber=0;//numbers of section
void section_read(char *szfile)
{
//section name...size..
HANDLE hfile=CreateFile(
szfile
,GENERIC_ALL
,NULL
,NULL
,OPEN_EXISTING
,FILE_ATTRIBUTE_NORMAL
,NULL
);
if(hfile==INVALID_HANDLE_VALUE)
return ;
//create mapping
HANDLE hmap=CreateFileMapping(
hfile
,NULL
,PAGE_EXECUTE_READWRITE
,0,0
,NULL
);
if(hmap==NULL)
return ;
long pmodule=(long)MapViewOfFile(hmap,FILE_MAP_ALL_ACCESS,0,0/*offset*/,0);
if(pmodule==0||*(short*)pmodule!=IMAGE_DOS_SIGNATURE)
return ;
long ppeheader=*(long*)(pmodule+0x3c/*e_lfanew*/)+pmodule;
IMAGE_NT_HEADERS *ntheader=(IMAGE_NT_HEADERS*)ppeheader;
if(ntheader->Signature!=IMAGE_NT_SIGNATURE)
return ;
g_type=ntheader->FileHeader.Characteristics;
g_secnumber=ntheader->FileHeader.NumberOfSections;
g_filealign=ntheader->OptionalHeader.FileAlignment;
g_viralign=ntheader->OptionalHeader.SectionAlignment;
//定位到section区段,读取section header
IMAGE_SECTION_HEADER *psection=(IMAGE_SECTION_HEADER*)(sizeof(IMAGE_NT_HEADERS)+ppeheader);
for (int i=0;i<g_secnumber;i++)
{
lstrcpy((char*)g_section.secname,(char*)psection.Name);
//空隙计算公式:
//空隙大小 = SizeOfRawData - Misc.VirtualSize - 1;
//节的起始点 = PointerToRawData;
//空隙起始点 = PointerToRawData + Misc.VirtualSize;
g_section.gapsize=psection.SizeOfRawData-psection.Misc.VirtualSize-1;
g_section.secstart=(PVOID)psection.PointerToRawData;
g_section.gapstart=(PVOID)(psection.PointerToRawData+psection.Misc.VirtualSize);
}
}
int main(int argc, char* argv[])
{
section_read("c:\\splitfile.exe");
for (int i=0;0!=g_section.gapsize;i++)
{
printf("name:%s,gapstart:%p,gapsize:%d\n",g_section.secname,g_section.gapstart,g_section.gapsize);
}
return 0;
}
复制代码
欢迎光临 滴水逆向联盟 (http://www.dtdebug.com/)
Powered by Discuz! X3.2