cyxvc 发表于 2018-1-26 12:56:07

[开源]用C++实现的壳(扩展版)

本帖最后由 cyxvc 于 2018-1-27 16:54 编辑

之前我写了篇【用C++实现的壳(基础版)】完成了一个非常单纯的C++壳基础框架。现在这个【扩展版】的壳在之前的基础上增加了两个功能,一个是IAT加密,在一个就是机器码绑定。并修复了一些bug,静态编译了Shell.dll,使得在Win 7 x86和Win 7 x64位下都可以正常加壳了,如果加壳后的程序无法运行,请取消“IAT加密”选项,原因是我在IAT加密中使用了Hook-API,而Hook以后全当Call来处理了,实际有的程序IAT位置所填写的地址指向的并不全是Call指令,有时候是Mov指令,所以“IAT加密”功能的兼容性不足。
      本来想增加反调试功能,可我实在水平有限,无法干掉StrongOD的反反调试功能,所以就没在拓展版中假如反调试功能,如果大家有什么好的反调试技术可以添加到这个壳子里,我在这就不献丑了...

下面就分别介绍一下“IAT加密”和“机器码绑定”这两个功能的实现。


【IAT加密】      

      我对IAT进行加密的思路是:
      ①首先定义一个自己的导入表数据结构,在Pack部分加壳的时候,读取被加壳程序的导入表信息并保存到我自己的导入表数据结构中,然后抹去被加壳程序的导入表数据;
      ②在Shell部分对IAT进行解密的时候,直接从我自己定义的导入表数据结构中获取修复IAT所用的信息,当通过这些信息获取到真正的函数地址后,将该地址填入一个new出来的堆空间1内保存,在这个堆空间1内加入一些花指令,最终再调用真正的函数地址。
      如果直接将堆空间1的地址写入IAT,就完成了一个简单的IAT-Hook,但这样操作的话,真正的函数地址和要写入的IAT地址会同时出现,在反汇编中修改代码,直接将函数地址写入IAT地址的话,就会使得IAT-Hook失效,所以我没有直接将堆空间1写入IAT地址。
      ③而是将堆空间1写入了一段又new出来的堆空间2,然后再在别的函数中,将堆空间2的地址写入IAT地址,这就能保证真正的函数地址和IAT地址不同时出现,这样的话,如果脱壳者在不了解我自己定义的导入表数据结构的情况下,是很难修复IAT并成功脱壳的。
      我自己定义的IAT数据结构如下:
typedef struct _MYIMPORT
{
DWORDm_dwIATAddr;      //IAT地址
DWORDm_dwModNameRVA;      //模块名偏移
DWORDm_dwFunNameRVA;      //函数名偏移
BOOLm_bIsOrdinal;      //是否为序号导出函数
DWORDm_Ordinal;      //序号
}MYIMPORT, *PMYIMPORT;

示意图如下:
https://bbs.pediy.com/upload/attach/201601/662999_vaalg4momh0vbt6.jpg

      经过这样处理后的IAT,在你停在原程序OEP的情况下,用IAT修复工具是很难进行自动修复的,修复失败,也就意味着不能脱壳成功。
      
      如果大家感兴趣可以用这个壳对一个程序进行“IAT加密”,然后忘掉这个导入表数据结构,再脱脱壳感受一下,嘿嘿...
【机器码绑定】
      这个其实没有什么技术含量,只是在逻辑上很难破解(在你不知道这个程序所绑定的机器码的情况下)。
      原理就是,用机器码1同代码段进行亦或操作,这样加过壳的程序就只能在机器码1的电脑上运行了,而如果在其他机器上运行,Shell部分在对机器码绑定进行解密的时候,获取的机器码同机器码1不同,这样解密出来的代码就是垃圾代码,根本无法运行,这样双击的效果为:
https://bbs.pediy.com/upload/attach/201601/662999_mjxzo6vzo96zvzx.jpg
      大家在测试的时候,通过我打包的文件中的“查看机器码”查看本机的机器码,然后将这个机器码输入到加壳选项中,所加壳后的程序就只能在你的机器上运行了,如果改动一位,加壳后的程序运行时就会出错。
      我这个获取机器码的代码是从网上找的,但貌似并不是真正的机器码,不过也无所谓,只要能保证每台机器所获取的信息都是不同且唯一的就行,原理一样。
      
【总结】
      给程序加壳其实就是拖慢破解者的进度,或者从数量上击垮对方,很难有脱不了的壳,除非是经过VM保护的代码才会很难分析。这就是一场加壳者和破解者之间的较量,再简单的壳也会有小菜脱不了,再难的壳也会有大牛能搞定。
      注:测试环境为win7系统,32位和64位都可以,但在xp上不行,原因是Shell部分获取Kernel32.dll基址的时候的代码只适用于win7,xp的话需要删除一句“mov eax, ”。如果你想要兼容xp的话,请从网上自行搜索获取Kernel32.dll基址的其他方法。
源码下载:**** Hidden Message *****

DeEP1996 发表于 2018-4-18 09:54:03

是黑客技术吗

nfsq550ml 发表于 2018-4-18 23:19:07

学习学习学习

凌乱大帅比 发表于 2018-5-2 17:04:47

iygiug1是大概是个

溯影 发表于 2018-5-6 20:09:57

学习一下,为什么大家这么优秀{:10_254:}{:10_279:}

九月ya 发表于 2018-6-8 00:57:15

为什么大家都这么优秀。估计就我一个菜鸟了

Emotion 发表于 2018-6-18 00:06:15

666

leiyun 发表于 2018-9-6 16:17:46

ghostkeeper 发表于 2018-10-28 20:52:52

后排围观LZ代码

2164930278 发表于 2019-6-23 09:37:06

大佬

AmosAlbert 发表于 2019-8-9 16:39:20

学习一下

清蒸小龙虾 发表于 2019-10-21 14:37:29

666

艾苦酒 发表于 2020-5-20 14:41:04

学习

wheroiny 发表于 2020-7-5 10:55:29

借鉴一下

理想小青年 发表于 2020-9-24 17:33:44

{:10_333:}

梦蝶1994 发表于 2020-9-28 22:00:25

顶楼主啦..希望楼主多发精品好帖啦.....

ManiSang 发表于 2020-10-12 11:42:42

我就知道你不简单

G10CK 发表于 2021-2-15 11:46:08

谢谢楼主分享

zcrui9911 发表于 2021-3-29 15:29:29

黑家的师傅吗?

athena1024 发表于 2021-6-14 14:03:50

学习
页: [1] 2
查看完整版本: [开源]用C++实现的壳(扩展版)