最近出差,偶有闲暇,写了个简单的壳,先声明下,此壳部分内容借鉴看雪论坛某位大侠(现在搜索找不到了,所以名字忘记了)名为shell的程序。
主要实现有以个方面的功能:
1,对text块进行RC4加密,组织程序被IDA等静态工具分析。
2,替换程序中的部分API函数,让其执行到API函数时能跳到壳执行相关代码后再跳回。
3,在壳中加了CRC和自己随便写的一个CheckSum用来检验程序的完整性,以用来防止程序被修改。
4,加了部分anti。
此壳可扩充的空间:
1,可增加更多anti.
2,可扩展为输入表加密。
3,因为加壳后的程序被替换了API函数,所以执行时必定会跳回壳代码中执行,因此如果给壳做VM的话,可大大加大难度!此点本人已实现,但不好放出来:)
4,目前只支持exe文件,可扩展为支持dll文件的加壳。
摘录此壳的主要流程:
CreatefileBak(OpenFileName);//加密前先创建备份文件
PeFileToEncrypt.OnInitPE(OpenFileName);//建立映像文件,初始化 PIMAGE_DOS_HEADER dosHeader等信息
bool IsValid=PeFileToEncrypt.CheckIfValidPE();//由PE文件里面的信息来判断是否为PE文件
if(IsValid)//目前只支持对exe文件加壳
{
//pImageFileHeader->SizeOfOptionalHeader,可选头(文件头)大小,此字节一般用来添加块。
PeFileToEncrypt.GetPoniterToSection();
//pImageOptionalHeader->AddressOfEntryPoint,程序入口,RVA地址
PeFileToEncrypt.GetEntryPoint();
//初始化asm用的全局变量
PeFileToEncrypt.InitGloablForAsm();
//计算入口地址,便于被加壳文件的载入,计算后的入口地址即一般为0x400000+RVA(GetEntryPoint函数中得到)
PeFileToEncrypt.CalculateOldEntryPoint();
//计算节表尾部的RVA,即最后一个块的尾部地址
PIMAGE_SECTION_HEADER pTmp_Setion=PeFileToEncrypt.pSection;
//先增加一区段
DWORD sectionAddr;//为已加+(DWORD)pImageBase的值。
sectionAddr = PeFileToEncrypt.AddsecHeader(".pack");//返回的地址为新增区块的文件首地址
for(int i=0;i<PeFileToEncrypt.NumberOfSection;i++)
//对每个section调用Encrypt_sections,能加密的节加密,不能加密的修改节名,修改节的属性
{
PeFileToEncrypt.Encrypt_sections(pTmp_Setion);//
pTmp_Setion++;//下一个section
}
if(PeFileToEncrypt.IsEncrypted)//此变量表示需加密
{
// 在壳中加入RC4算法函数
theApp.dwGlobelInjectAddress = PeFileToEncrypt.InjectRC4EncryptFuction(sectionAddr);
//插入CRC32校验函数部分
theApp.dwGlobelInjectAddress = PeFileToEncrypt.InjectCRC32Fuction(theApp.dwGlobelInjectAddress);
//插入CRC32校验部分
theApp.dwGlobelInjectAddress = PeFileToEncrypt.InjectWriteCRC32OrCheckSum(theApp.dwGlobelInjectAddress,
PeFileToEncrypt.dwCRCChecksum,PeFileToEncrypt.dwCRC32FuctionAddress);
//插入CHECKSUM校验函数部分
theApp.dwGlobelInjectAddress = PeFileToEncrypt.InjectCheckSumFuction(theApp.dwGlobelInjectAddress);
//插入CHECKSUM校验部分
theApp.dwGlobelInjectAddress = PeFileToEncrypt.InjectWriteCRC32OrCheckSum(theApp.dwGlobelInjectAddress,
PeFileToEncrypt.dwChecksum,PeFileToEncrypt.dwCheckSumFuctionAddress);
theApp.dwGlobelInjectAddress = PeFileToEncrypt.InjectAntiDebug(theApp.dwGlobelInjectAddress);
//插入API替换函数调用
PeFileToEncrypt.InjectApiReplace();
//最后插入Loder
PeFileToEncrypt.InjectLoaderByWriteFile(sectionAddr);//此地址为文件偏移地址
AfxMessageBox("加壳成功!");
}
}
else
{
AfxMessageBox("不支持此文件,请确认为有效PE文件!");
}
PeFileToEncrypt.CloseHandleOfPe();
具体源文件见相关下载。