1原创段仿真PE加载器行程序
程序假定PE文件合法方没提供容错处理
bool PELoader(char *lpStaticPEBuff long lStaticPELen)
{
long lPESignOffset *(long *)(lpStaticPEBuff + 0x3c)
IMAGE_NT_HEADERS *pINH (IMAGE_NT_HEADERS *)(lpStaticPEBuff + lPESignOffset)
取加载存中
long lImageSize pINH>OptionalHeaderSizeOfImage
char *lpDynPEBuff new char[lImageSize]
if(lpDynPEBuff NULL)
{
return false
}
memset(lpDynPEBuff 0 lImageSize)
取PE文件节数量
long lSectionNum pINH>FileHeaderNumberOfSections
计算PE头信息节表信息占存
long lPEHeadSize lPESignOffset + sizeof(IMAGE_NT_HEADERS) + lSectionNum * sizeof(IMAGE_SECTION_HEADER)
加载PE头部信息节表
memcpy(lpDynPEBuff lpStaticPEBuff lPEHeadSize)
加载节
long lFileAlignMask pINH>OptionalHeaderFileAlignment 1 节磁盘中齐掩码
long lSectionAlignMask pINH>OptionalHeaderSectionAlignment 1 节load存中齐掩码
IMAGE_SECTION_HEADER *pISH (IMAGE_SECTION_HEADER *)((char *)pINH + sizeof(IMAGE_NT_HEADERS))
for(int nIndex 0 nIndex < lSectionNum nIndex++ pISH++)
{
判定节齐属性合法
if((pISH>VirtualAddress & lSectionAlignMask) || (pISH>SizeOfRawData & lFileAlignMask))
{
出现非法节
delete lpDynPEBuff
return false
}
加载改节
memcpy(lpDynPEBuff + pISH>VirtualAddress lpStaticPEBuff + pISH>PointerToRawData pISH>SizeOfRawData)
}
修改导入表导入程序执行程中API函数址
if(pINH>OptionalHeaderDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]Size > 0) 0说明导入表
{
IMAGE_IMPORT_DESCRIPTOR *pIID (IMAGE_IMPORT_DESCRIPTOR *)(lpDynPEBuff + \
pINH>OptionalHeaderDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]VirtualAddress)
循环扫描函数导入dll
for( pIID>Name NULL pIID++)
{
*OllyDump源代码里重建导入表时候没初始化OriginalFirstThunk字段
里OriginalFirstThunk字段进行处理*
IMAGE_THUNK_DATA *pITD (IMAGE_THUNK_DATA *)(lpDynPEBuff + pIID>FirstThunk)
HINSTANCE hInstance LoadLibrary(lpDynPEBuff + pIID>Name)
if(hInstance NULL)
{
导入dll失败
delete lpDynPEBuff
return false
}
循环扫描dll导入函数
for( pITD>u1Ordinal 0 pITD++)
{
FARPROC fpFun
if(pITD>u1Ordinal & IMAGE_ORDINAL_FLAG32)
{
函数序号方式导入
fpFun GetProcAddress(hInstance (LPCSTR)(pITD>u1Ordinal & 0x0000ffff))
}
else
{
函数名称方式导入
IMAGE_IMPORT_BY_NAME * pIIBN (IMAGE_IMPORT_BY_NAME *)(lpDynPEBuff + pITD>u1Ordinal)
fpFun GetProcAddress(hInstance (LPCSTR)pIIBN>Name)
}
if(fpFun NULL)
{
导出函数失败
delete lpDynPEBuff
return false
}
pITD>u1Ordinal (long)fpFun
}
FreeLibrary(hInstance)
}
}
重定位处理
if(pINH>OptionalHeaderDataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]Size > 0)
{
取第重定位块
IMAGE_BASE_RELOCATION *pIBR (IMAGE_BASE_RELOCATION *)(lpDynPEBuff + \
pINH>OptionalHeaderDataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]VirtualAddress)
long lDifference (long)lpDynPEBuff pINH>OptionalHeaderImageBase
循环重定位块
for( pIBR>VirtualAddress 0 )
{
char *lpMemPage lpDynPEBuff + pIBR>VirtualAddress
long lCount (pIBR>SizeOfBlock sizeof(IMAGE_BASE_RELOCATION)) >> 1
页面中需重定位项进行处理
short int *pRelocationItem (short int *)((char *)pIBR + sizeof(IMAGE_BASE_RELOCATION))
for(int nIndex 0 nIndex < lCount nIndex++)
{
int nOffset pRelocationItem[nIndex] &0x0fff
int nType pRelocationItem[nIndex] >> 12
然windows定义重定位类型PE文件中见03两种
if(nType 3)
{
*(long *)(lpDynPEBuff + nOffset) + lDifference
}
else if(nType 0)
{
什做
}
}
pIBR指重定位块
pIBR (IMAGE_BASE_RELOCATION *)(pRelocationItem + lCount)
}
}
delete lpDynPEBuff
return true
}
文档香网(httpswwwxiangdangnet)户传
《香当网》用户分享的内容,不代表《香当网》观点或立场,请自行判断内容的真实性和可靠性!
该内容是文档的文本内容,更好的格式请下载文档