GetRVA.rar
在学习PE文件的格式的时候写的,通过获取IMAGE_OPTIONAL_HEADER 的AddressOfEntryPoint得到程序的执行入口地址c,然后获取区块.text的地址范围[a,b],如果c不再[a,b]的范围里面,则入口是异常的,可能被加壳
#pragma warning(disable:4786)
#include<windows.h>
#include<stdio.h>
#include<iostream>
#include<winnt.h>
#include<stdlib.h>
#include<imagehlp.h>
#include<cstring>
#include<string>
#include<vector>
#include<string.h>
using namespace std;
/////////////////////
#pragma comment(lib,"imagehlp.lib")
///////////////////////////////////////////////////////
//
//
typedef struct _MAP_FILE_STRUCT
{
HANDLE hFile;
HANDLE hMapping;
LPVOID ImageBase;
}MAP_FILE_STRUCT,*PMAP_FILE_STRUCT;
/////////////////////
#define GETTHUNK(pImportDesc) ((DWORD) \
( \
(PIMAGE_IMPORT_DESCRIPTOR)pImportDesc->OriginalFirstThunk ? \
(PIMAGE_IMPORT_DESCRIPTOR)pImportDesc->OriginalFirstThunk:(PIMAGE_IMPORT_DESCRIPTOR)pImportDesc->FirstThunk ) \
)
///////////////////////////////////////////////
//函数功能:载入文件句柄,文件映像,文件基地址
//参 数:lpFilename文件名
// PMAP_FILE_STRUCT文件结构体
//返 回:打开成功返回TRUE
///////////////////////////////////////////////
bool load(LPTSTR lpFilename,PMAP_FILE_STRUCT &p)
{
HANDLE hFile=CreateFile(lpFilename,GENERIC_READ,FILE_SHARE_READ,NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
if(!hFile)
{
cout<<"file open error"<<endl;
return false;
}
HANDLE hMapping=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
if(!hMapping)
{
cout<<"file map error"<<endl;
return false;
}
LPVOID ImageBase=MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0);
if(!ImageBase)
{
cout<<"file load error"<<endl;
return false;
}
p->hFile=hFile;
p->hMapping=hMapping;
p->ImageBase=ImageBase;
return true;
}
///////////////////////////////////////////////
//函数功能:判断文件是否为PE文件
//参 数:ImageBase文件的基地址
//返 回:是PE文件返回TRUE
///////////////////////////////////////////////
bool IsPE(LPVOID ImageBase)
{
PIMAGE_DOS_HEADER pdos=NULL;
PIMAGE_NT_HEADERS pnt=NULL;
pdos=(PIMAGE_DOS_HEADER)ImageBase;
if(pdos->e_magic!=IMAGE_DOS_SIGNATURE)
{
return false;
}
pnt=(PIMAGE_NT_HEADERS)((DWORD)pdos+pdos->e_lfanew);
if(pnt->Signature!=IMAGE_NT_SIGNATURE)
{
return false;
}
return true;
}
///////////////////////////////////////////////
//函数功能:获取文件的PIMAGE_NT_HEADERS地址
//参 数:ImageBase文件的基地址
//返 回:返回PIMAGE_NT_HEADERS
///////////////////////////////////////////////
PIMAGE_NT_HEADERS GetNtHead(LPVOID ImageBase)
{
if(!IsPE(ImageBase))
{
return NULL;
}
PIMAGE_NT_HEADERS pnt;
PIMAGE_DOS_HEADER pdos;
pdos=(PIMAGE_DOS_HEADER)ImageBase;
pnt=(PIMAGE_NT_HEADERS)((DWORD)pdos+pdos->e_lfanew);
return pnt;
}
///////////////////////////////////////////////
//函数功能:获取文件的PIMAGE_OPTIONAL_HEADER地址
//参 数:ImageBase文件的基地址
//返 回:返回PIMAGE_OPTIONAL_HEADER
///////////////////////////////////////////////
PIMAGE_OPTIONAL_HEADER GetOptionalHead(LPVOID ImageBase)
{
PIMAGE_DOS_HEADER pdos=NULL;
PIMAGE_NT_HEADERS pnt=NULL;
PIMAGE_OPTIONAL_HEADER poptional=NULL;
pnt=GetNtHead(ImageBase);
poptional=&(pnt->OptionalHeader);
return poptional;
}
///////////////////////////////////////////////////////////////////////
//函数功能:获取程序执行入口
//参 数:ImageBase文件的基地址
//返 回:程序执行入口地址
//////////////////////////////////////////////////////////////////////
DWORD GetAddressOfEntryPoint(LPVOID ImageBase)
{
PIMAGE_OPTIONAL_HEADER poptional=GetOptionalHead(ImageBase);
return poptional->AddressOfEntryPoint;
}
///////////////////////////////////////////////////////////////////////
//函数功能:函数入口是否正常
//参 数:ImageBase文件的基地址
//返 回:正常返回TRUE
//////////////////////////////////////////////////////////////////////
bool EntryPointIsRright(LPVOID ImageBase)
{
DWORD c=GetAddressOfEntryPoint(ImageBase);
PIMAGE_NT_HEADERS pnh=NULL;
PIMAGE_FILE_HEADER pfh=NULL;
PIMAGE_SECTION_HEADER psh=NULL;
pnh=GetNtHead(ImageBase);
pfh=(PIMAGE_FILE_HEADER)&pnh->FileHeader;
int num=pfh->NumberOfSections;
psh=IMAGE_FIRST_SECTION(pnh);
int i,j;
for( i=0;i<num&&psh;i++,psh++)
{
string tmp;
for( j=0;j<8;j++)
{
char ch=psh->Name[j];
if(ch=='.'||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
tmp+=psh->Name[j];
}
}
int a=psh->VirtualAddress;
int b=psh->VirtualAddress+psh->SizeOfRawData;
//printf("%s %d %d\n",tmp.c_str(),psh->VirtualAddress,psh->SizeOfRawData+psh->VirtualAddress);
if(tmp==".text"&&a<=c&&c<=b)
{
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
int main()
{
//freopen("a.txt","w",stdout);
string s;
printf("输入文件目录:");
while(cin>>s)
{
LPTSTR filename=(LPTSTR )s.c_str();
PMAP_FILE_STRUCT map;
map=(PMAP_FILE_STRUCT)malloc(sizeof(MAP_FILE_STRUCT));
if(!load(filename,map))
{
cout<<"load() error"<<endl;
return 0;
}
if(!IsPE(map->ImageBase))
{
cout<<"ispe() error"<<endl;
return 0;
}
bool t=EntryPointIsRright(map->ImageBase);
printf("%d\n",t);
}
return 0;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课