//pSource
压缩源,lInLength数据的大小,lOutLenght判断宏
Compress(PVOID pSource, long lInLength, OUT long &lOutLenght)
{
//packed
保存压缩数据的空间,workmem为完成压缩需要使用的空间
BYTE *packed, *workmem;
if
((packed = (BYTE *) malloc(aP_max_packed_size(lInLength))) == NULL ||
(workmem = (BYTE *) malloc(aP_workmem_size(lInLength))) == NULL)
{
return
NULL;
}
//
调用aP_pack压缩函数
lOutLenght = aP_pack(pSource, packed, lInLength, workmem, NULL, NULL);
if
(lOutLenght == APLIB_ERROR)
{
return
NULL;
}
if
(NULL != workmem)
{
free
(workmem);
workmem = NULL;
}
return
packed;
//
返回保存地址
}
[B]区段的处理[
/B
]
为了保存各个压缩区段的信息,可以定义一个结构体,保存压缩区段信息
typedef struct _CompessSection
{
DWORD VA;
DWORD CompessVA;
DWORD CompessSize;
//
LPVOID lpCompessData;
//
}CompessSection, *PCompessSection;
首先,要提取出不能压缩的区段,然后根据之前压缩壳的构建,确定要压缩区段写入的地址,应该是紧接在占位区间之后。这里全局变量pMemPointer为之前获得的载入内存基址。
//PeSectionHeader
此时指向占位区段最后一个节首地址
DWORD LastSecRva = PeSectionHeader.VirtualAddress;
//
最后一个节经过内存对齐后的大小
DWORD LastSecSize = AlignmentNum(pPeSectionHeader[m_iSecNum-1].Misc.VirtualSize,
MemAlignment);
//
获得区段压缩后保存的地址
DWORD CompressRva = LastSecRva + LastSecSize;
//
获取要压缩区段数
DWORD CompressSecNum = SecNum;
//
如果存在资源区段,则不压缩这个区段,被压缩区段数减1
if
(IsRESOURCE == TURE)
{
CompressSecNum --;
}
//
配置压缩信息
m_pComSec = new CompessSection[CompressSecNum];
int iPos = 0;
int j = 0;
for
(unsigned int i = 0; i < SecNum; i++)
{
//
跳过资源目录和重定位目录
if
(i == 2 )
{
iPos++;
continue
;
}
else
{
if
(mPeSectionHeader[iPos].SizeOfRawData == 0)
{
//
空节不压缩
iPos++;
continue
;
}
long lCompressSize = 0;
PVOID pCompressData;
PVOID pInData = (BYTE *)pMemPointer + PeSectionHeader[iPos].VirtualAddress;
//
调用Compress函数
pCompressData = Compress(pInData,
PeSectionHeader[iPos].Misc.VirtualSize,
lCompressSize);
//
压缩数据指针
m_pComSec[j].lpCompessData = pCompressData;
//
解压后内存地址
m_pComSec[j].VA = PeSectionHeader[iPos].VirtualAddress;
//
压缩数据加载后的内存地址
m_pComSec[j].CompessVA = CompressRva;
//
压缩数据大小
m_pComSec[j].CompessSize = CompressSize;
//
下一个节压缩数据加载的地址
iCompressRva += AlignmentNum(CompressSize, MemAlignment);
iPos++;
j++;
}
}
}