准备工作
工程文件已经打包。 解决方案内有2个项目:EasyProtect 和 Shell。
EasyProtect 是用来加壳的。
Shell就是壳的核心,编译后是Shell.dll。
EasyProtect 流程
:
打开被加壳文件 -> 打开Shell.dll -> 提取shell.dll代码段(.MyCode) 数据 ->在被加壳文件中创建新的区段->重定位Shell.dll的代码数据->把重定位好的代码数据写到被加壳程序的新区段中->加密被加壳程序代码段->修正OEP
但是还有一些细节没有提及。
packPE 加壳函数。
bool packPE(char * szFileName)
{
CPeFile MyPe;
CPeFile MyShell; // 壳也是一个编译的pe文件
PIMAGE_SECTION_HEADER pNewSec,pShellSec;
PMyDosHeader pDosHead;
char *shellcode;
if(!MyPe.LoadPe(szFileName))
return false;
if(!MyShell.LoadPe(SHELL_FILE))
return false;
pDosHead = (PMyDosHeader)MyPe.GetBuffer();
if (pDosHead->info.flag==0x1447) // 已经加密过了
return false;
/* 获取壳的代码段 */
pShellSec = MyShell.FindSectionByName(".MyCode");
pNewSec = MyPe.AddSection(".fishc",pShellSec->SizeOfRawData);
if(!pNewSec) return false;
// 重定位数据 0.0
FixRelocBase2(MyShell,MyPe.GetImageBase(),pNewSec->VirtualAddress);
// 复制代码数据
shellcode = new char[pShellSec->SizeOfRawData];
bool bRet =
MyShell.ReadDataByRaw(pShellSec->PointerToRawData,shellcode,pShellSec->SizeOfRawData);
if(!bRet)return false;
bRet =
MyPe.WriteDataByRaw(pNewSec->PointerToRawData,shellcode,pShellSec->SizeOfRawData);
if(!bRet) return false;
delete shellcode;
// 加密代码段
char *buf;
char *key = "mooncakeisverylovelygirl";
PIMAGE_SECTION_HEADER cs;
pDosHead->info.CodeSec=MyPe.GetCodeSection();
cs = MyPe.GetSectionById(pDosHead->info.CodeSec);
buf = (char *)MyPe.GetBuffer();
xorPlus(&buf[cs->PointerToRawData],cs->SizeOfRawData,key,strlen(key));
// 修正OE