加壳器的编写
加壳器主要分为两个部分:
编写一个加壳器:
1.写一个加壳器,首先是要可以打开一个文件,如果一个文件都打不开,谈什么加壳。
1.1打开一个文件需要用GreateFileA 这个API。
1.2关闭一个文件,GloseHandle 。
2,写完一个壳,需要保存到一个路径中。
2.1将文件保存到制定路径中
2.2 获取文件内容和大小
3.需要释放文件内容
获取文件之后,就是获取各种头,DOS头,NT头 等等
3.获取完各个头,遍历区段
4.因为加壳要加在原先区段的最后一个区段的后面,下面就应该去获取最后一个区段的区段头
在这里插入图片描述
5.区段都找到之后,要算一下对齐的大小,为了下一步为添加区段最准备
6.下面开始添加区段
6.1.增加区段的各种信息
6.2 修改扩展头的映像大小(旧的加上新的)
6.3 扩充文件数据的堆空间大小
写到这里,就差不多完成了一个加壳器,下面写stub部分
编写一个壳的stub部分
总的概述
加壳器的流程
stub的流程
配置stub工程
先创建一个结构体,为下面需要的stub.dll 提供服务
同时,最后一个StubConf 也是一个结构体,作为放全局变量的地方,
通过LoadLibrary去加载要写的stub.dll
添加新区段的注意点:
修复IAT流程
支持重定位
让stub的代码支持重定位
让被加壳程序支持重定位
总结概述
怎么把stub的机器码植入到新区段???
1.使用加壳器,给被加壳程序添加新区段
2.加密/压缩被加壳程序
3,将stub的代码段移植新区段
3.1修正stub.text中的重定位(将属于stub的段首rva改成新区段的段首rva,也需要替换加载基址)
4.将被加壳程序的oep记录到stub
5.将被加壳的程序ope设置到stub
6.保存为新文件。
stub的流程
配置stub工程
1.将工程设置成release版本,
2.属性,配置属性,stub -> relase
添加新区段的注意点:
1.sizeoflmage的值是否 == 新区段virtualaddress + 新区段.sezeofrawdata/新区段的misc.virtualsize
2.新区段的 virtualaddress = 上一个区段 virtualaddress + 内存力度对气候的区段大小
3 文件数据的结束位置 == 新区段的 Pointertorawdata + 新区段的misc.virtualsize
修复IAT的流程
1.找到导入表
2.通过导入变的Name字段得到DLL的名字,然后使用LoadLibraryA加载这个DLL
3.遍历IAT/INT,得到导入函数的字符串,通过GetProcAddres得到函数的地址,将函数地址写回到IAT中,
让stub的代码支持重定位
原理:将stub的重定位表移植到被加壳的程序中,然后将被加壳的程序的数据目录表中的重定位表的VirtualAddress和size改成stub的重定位表的rva和size,但这个rva和size必须是重定位表移植到新区段之后的rva和size。
步骤:
1.将重定位项中的VirtualAddrss 修正
1.1遍历区段表,找到VirtualAddress所属的区段,减去这个所属区段的段首rva
1.2 再加上,该区段移植到被加壳程序的新区段的段首rva
2.将stub的重定位表拷贝被加壳程序的新区段。
3.将被加壳程序的数据目录表的重定位表的rva设置成stub移植过来的重定位表
让被加壳程序支持重定位
在stub中添加代码:
1.遍历被加壳程序的重定位表
2.获取当前程序的加载地址(GetModuleHandle(NULL)),找到重定位项,减去默认的加载基址,加上当前的加载基址。