能力值:
( LV13,RANK:410 )
|
-
-
2 楼
good~~!!!
thx
|
能力值:
( LV12,RANK:330 )
|
-
-
3 楼
收藏一下!
|
能力值:
( LV9,RANK:650 )
|
-
-
4 楼
先收藏,再研究一下。
|
能力值:
( LV9,RANK:170 )
|
-
-
5 楼
学习啊...
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
虚拟机收藏
|
能力值:
( LV13,RANK:970 )
|
-
-
7 楼
支持!
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
好代码,非常有用
|
能力值:
( LV8,RANK:130 )
|
-
-
9 楼
不错呀...
不过还是应该少了点东西的,比如说tls
总是觉得m$的loader资料不是太多...
|
能力值:
( LV12,RANK:660 )
|
-
-
10 楼
支持先~
|
能力值:
(RANK:350 )
|
-
-
11 楼
不错
|
能力值:
( LV9,RANK:410 )
|
-
-
12 楼
收藏先,thx
|
能力值:
(RANK:350 )
|
-
-
13 楼
最初由 linxer 发布 *(long *)(lpDynPEBuff + nOffset) += lDifference;
在重定位处理这块,linxer好像有一句笔误,上面这句应是:
*(long *)(lpMemPage + nOffset) += lDifference;
|
能力值:
( LV12,RANK:660 )
|
-
-
14 楼
最初由 kanxue 发布 在重定位处理这块,linxer好像有一句笔误,上面这句应是:
*(long *)(lpMemPage + nOffset) += lDifference;
老大的猛壳要出世了!
|
能力值:
(RANK:350 )
|
-
-
15 楼
最初由 prince 发布 老大的猛壳要出世了!
不是,在处理DLL文件时参考了一下这块,呵~
|
能力值:
( LV9,RANK:690 )
|
-
-
16 楼
非常好。
期待老大的猛壳横空出世。
|
能力值:
(RANK:450 )
|
-
-
17 楼
首先谢谢看雪老大对程序bug的更正
近期在对FSG1.33加壳后程序load时发现 程序还有两处不妥之处
现连同看雪老大指出的bug一同更正,再次发布这段程序,希望各位大侠指点
bool PELoader(char *lpStaticPEBuff, long lStaticPELen)
{
long lPESignOffset = *(long *)(lpStaticPEBuff + 0x3c);
IMAGE_NT_HEADERS *pINH = (IMAGE_NT_HEADERS *)(lpStaticPEBuff + lPESignOffset);
//取加载到内存中大小
long lImageSize = pINH->OptionalHeader.SizeOfImage;
char *lpDynPEBuff = new char[lImageSize];
if(lpDynPEBuff == NULL)
{
return false;
}
memset(lpDynPEBuff, 0, lImageSize);
//取PE文件的节数量
long lSectionNum = pINH->FileHeader.NumberOfSections;
IMAGE_SECTION_HEADER *pISH = (IMAGE_SECTION_HEADER *)((char *)pINH + sizeof(IMAGE_NT_HEADERS));
//加载PE文件第一个节前的信息
memcpy(lpDynPEBuff, lpStaticPEBuff, pISH->VirtualAddress);
//加载各个节
long lFileAlignMask = pINH->OptionalHeader.FileAlignment - 1; //各节在磁盘中的对齐掩码
long lSectionAlignMask = pINH->OptionalHeader.SectionAlignment - 1; //各节在load后内存中的对齐掩码
for(int nIndex = 0; nIndex < lSectionNum; nIndex++, pISH++)
{
/***************************************************
在对FSG1.33加壳程序进行loader的时候,其节对齐属性
比较怪异,对PE文件接触时间不长,不过地方不知道为什么,
请各位大虾指点迷津,故注掉节属性验证代码
***************************************************/
//判定各节的对齐属性,合法不
/*if((pISH->VirtualAddress & lSectionAlignMask) || (pISH->SizeOfRawData & lFileAlignMask))
{
//出现非法节
delete lpDynPEBuff;
return false;
}*/
//加载改节
memcpy(lpDynPEBuff + pISH->VirtualAddress, lpStaticPEBuff + pISH->PointerToRawData, pISH->SizeOfRawData);
}
//修改导入表,导入程序执行过程中要用到的API函数地址
if(pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size > 0) //大于0说明有导入表
{
IMAGE_IMPORT_DESCRIPTOR *pIID = (IMAGE_IMPORT_DESCRIPTOR *)(lpDynPEBuff + \
pINH->OptionalHeader.DataDirectory[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->u1.Ordinal != 0; pITD++)
{
FARPROC fpFun;
if(pITD->u1.Ordinal & IMAGE_ORDINAL_FLAG32)
{
//函数是以序号的方式导入的
fpFun = GetProcAddress(hInstance, (LPCSTR)(pITD->u1.Ordinal & 0x0000ffff));
}
else
{
//函数是以名称方式导入的
IMAGE_IMPORT_BY_NAME * pIIBN = (IMAGE_IMPORT_BY_NAME *)(lpDynPEBuff + pITD->u1.Ordinal);
fpFun = GetProcAddress(hInstance, (LPCSTR)pIIBN->Name);
}
if(fpFun == NULL)
{
//导出这个函数失败
delete lpDynPEBuff;
return false;
}
pITD->u1.Ordinal = (long)fpFun;
}
FreeLibrary(hInstance);
}
}
//重定位处理
if(pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size > 0)
{
//取第一个重定位块
IMAGE_BASE_RELOCATION *pIBR = (IMAGE_BASE_RELOCATION *)(lpDynPEBuff + \
pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
long lDifference = (long)lpDynPEBuff - pINH->OptionalHeader.ImageBase;
//循环每个重定位块
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文件中只能见到0和3两种
if(nType == 3)
{
*(long *)(lpMemPage + nOffset) += lDifference;
}
else if(nType == 0)
{
//什么也不做
}
}
//pIBR指向下一个重定位块
pIBR = (IMAGE_BASE_RELOCATION *)(pRelocationItem + lCount);
}
}
delete lpDynPEBuff;
return true;
}
|
能力值:
( LV12,RANK:660 )
|
-
-
18 楼
顶楼上的~
|
能力值:
( LV4,RANK:50 )
|
-
-
19 楼
我正在学习这块,赶上了哈
|
能力值:
( LV2,RANK:10 )
|
-
-
20 楼
收藏,收藏收藏
|
能力值:
( LV2,RANK:10 )
|
-
-
21 楼
for(int nIndex = 0; nIndex < lSectionNum; nIndex++, pISH++)
{
/***************************************************
在对FSG1.33加壳程序进行loader的时候,其节对齐属性
比较怪异,对PE文件接触时间不长,不过地方不知道为什么,
请各位大虾指点迷津,故注掉节属性验证代码
***************************************************/
/* 判定各节的对齐属性,是否合法 */
if((pISH->VirtualAddress & lSectionAlignMask) || (pISH->SizeOfRawData & lFileAlignMask))
{
delete lpDynPEBuff;
return false;
}
/* 加载改节 */
memcpy(lpDynPEBuff + pISH->VirtualAddress, lpStaticPEBuff + pISH->PointerToRawData, pISH->SizeOfRawData);
}
这段我看不明白,在for语句里面lSectionNum是节表数,而一个节表的大小是028H,那么后面的nIndex++, pISH++是什么意思啊?
请教
|
能力值:
( LV2,RANK:10 )
|
-
-
22 楼
是不是应该pISH = pISH + 28H
|
能力值:
( LV4,RANK:50 )
|
-
-
23 楼
如果我没有猜错的话:
因为pISH是一个IMAGE_SECTION_HEADER结构指针,pISH的自增就是相当于pISH += sizeof(IMAGE_SECTION_HEADER).其实和你说的一样.
我有个问题没明白,就是入口的传入参数char *lpStaticPEBuff, long lStaticPELen分别代表什么含义?
|
能力值:
( LV2,RANK:10 )
|
-
-
24 楼
研究一下,向各位学习了,不知道楼上的兄弟,强!
|
能力值:
( LV2,RANK:10 )
|
-
-
25 楼
还有个问题,我不明白就是楼主修正后的程序
......
//取PE文件的节数量
long lSectionNum = pINH->FileHeader.NumberOfSections;
IMAGE_SECTION_HEADER *pISH = (IMAGE_SECTION_HEADER *)((char *)pINH + sizeof(IMAGE_NT_HEADERS));
//加载PE文件第一个节前的信息
memcpy(lpDynPEBuff, lpStaticPEBuff, pISH->VirtualAddress);
......
最后一句
memcpy(lpDynPEBuff, lpStaticPEBuff, pISH->VirtualAddress);
好象有点问题
是不是应该这样
memcpy(lpDynPEBuff, lpStaticPEBuff, pINH->OptionalHeader.SizeOfHeaders);
|
|
|