首页
社区
课程
招聘
[原创]C语言改造一个壳程序
发表于: 2013-6-27 14:59 3944

[原创]C语言改造一个壳程序

2013-6-27 14:59
3944

最近在逆向一个游戏的时候,碰到了加壳的。壳,“知其然,不知其所以然”。先找个简单的来瞧瞧吧,刚好加密解密(第三版)里有一个。

好好认识了一下(压缩壳)加壳的流程

//读取文件内容
(1)打开源文件读取DOS头,读取PE头到局部变量空间
(2)文件对和节对齐大小等,根据节对齐大小修正映像大小并申请空间装映像
(3)读取文件头(DOS + NT Header)到新内存空间,修正文件头大小
(4)定位节表头,按照文件和节对齐大小修正节的大小,并检查最后一个节大小
(5)读取各节的内容到新的内存空间,修正可选头中的映像大小
(6)提取额外数据

//处理文件内容
(1)保存重定位表
(2)按照一定的文件格式处理输入表(所需空间大小通过MoveImpTable函数跑一遍得到)
(3)提取运行时需要的资源
(4)合并区段(貌似只是把节表头给抹了,抹掉的节的大小加到第一个节里面)
(5)压缩各个节
1、清除IAT目录信息
2、重新计算文件头大小(最后一个节表地址(考虑增加一个节) - 映像基址),用文件对齐大小修正,并修正第一个节的RAW地址
3、写回各种修正后的文件头到源文件中
4、写回各个节数据;重新计算节大小(扣除数据尾部的零数据);判断当前节是否可以压缩,执行压缩,写回压缩数据(紧接着文件头),填充对齐零数据,按文件对齐大小修正节大小,保存压缩前节的信息;对于可压缩资源区段,先获取资源目录大小,写入资源目录,压缩资源,写回压缩后的数据,修正资源节大小并填充零数据,记录压缩前节的信息;对于不可区段,直接保存数据,修正下一个节的起始偏移地址,循环执行

//写回文件内容
(1)拼装外壳段,外壳分两段,对于第二段进行压缩;在外壳段中保存各种信息,同时修正文件头的导入表和TLS表,使其指向外壳段对应位置,修两表的各种参数,
(2)添加一个新节,设置节表相关变量的值,按文件对齐大小修正节大小,按节对齐大小修正虚拟大小,修改文件头
(3)若是DLL,则把重定位表指向外壳段的虚构重定位表
(4)写入外壳段,末尾填充零数据
(5)定位源文件末尾,写入额外数据

//壳运行流程
(1)外壳第一段代码
1、从导入表获取GetModuleHandleA、GetProcAddress、VirtualAlloc函数的函数地址
2、申请一块内存,用于解压外壳第二段代码
3、解压外壳第二段代码,构造jmp xxxx跳到第二段代码执行
(2)外壳第二段代码
1、获取LoadLibraryA、aP_Depack函数地址
2、解压缩各节,解压后写到源文件对应位置
3、回复原文件的输入表
4、若有重定位数据,则修正重定位数据
5、准备返回OEP

代码Copy完一遍,第一个感觉就是各种大小修正,各种计算公式(部分):
//映像大小修正
ImageSize = AlignSize(nImage,nSectionAlign);
//映像大小计算(psececHeader 最后一个节表指针)
ImageSize = psecHeader->VirtualAddress + psecHeader->Misc.VirtualSize;
//定位NTHeader
pNtHeader = ImageBase + DosHeader.e_lfanew;
//定位NtHeader.OptionalHeader数据目录的数据
pTarget = m_pImageBase + pDataDir->VirtualAddress;
//定位节表
pSecHeader = m_pNtHeader + NtHeader.FileHeader.SizeOfOptionalHeader;
//节表数据起始地址
psecHeader[1].PointerToRawData = psecHeader->PointerToRawData + psecHeader->SizeOfRawData;
//额外数据大小计算
nMapOfSDataSize = nFileSize - (psecHeader->PointerToRawData + psecHeader->SizeOfRawData);
//NtHeader大小计算
nNtHeaderSize = sizeof(NtHeader.FileHeader) + sizeof(NtHeader.Signature) + NtHeader.FileHeader.SizeOfOptionalHeader;
//节表相关大小修正
psecHeader->SizeOfRawData = AlignSize(nRawDataSize,nFileAlign);
psecHeader->Misc.VirtualSize= AlignSize(nVirtualSize,nSectionAlign);
//节表大小修正后,检测最后一个节大小的处理
if(nIndex == nSectionNum - 1 && psecHeader->VirtualAddress + psecHeader->SizeOfRawData > m_nImageSize){
  psecHeader->SizeOfRawData = m_nImageSize - psecHeader->VirtualAddress;
}

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 5
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回