我几乎用了好几分钟来考虑我该不该写写这段文字,最后我水平有限的理由终于还是被已经写好的标题所屈服,所以我并不怕你笑我。
我没有google过其他资料然后才写此文的,只因一时兴起,错误之处请指正。
在过去两年,我曾写过4次壳,这里我把一些经验写出来,希望有写壳的少走弯路。不废话了,切入主题。
我的第一代壳:
当时我还在某学校练高中2年纪,那时候我就着手写我的第一个壳,当时我对这方面完全不了解,手头上几乎只有几篇介绍pe文件格式的文章,当时我壳的构架是基于win 32调试机制的,也就是很像现在的arm和encryptpe,不过当时完全不知道有两个东东。于是呼,在我当时使用的开发工具delphi 7新建一个工程就开始了,名字我想不起来了,似乎现在资料都还保存在我一台笔记本硬盘里面,永远封存起来了。由于当时Code能力也烂到了极点,也就是注定这壳很快会夭折,不怕你笑话,当时我还不知道如何利用类这个东西,所以在数据格式的管理上简直是原始到了不可言语的地步,当时基于调试api的构架初看起来很好,对code的操作能力很大,我甚至还设计了好多种代码处理原形,不过正如我前面提到的,不久后,这壳夭折了。失败原应是因为过于追求界面部分,还有code能力差,到后来发现构架并不是想象中的那么好。最终此壳只加密成功过一个很小的程序。
总结一下构架方面,并不是说这样的构架很差,而似乎它还有天生的优点,比如子进程不能直接调试,需要合并进程,对代码操作能力好。从加壳处理方面来说操作性也很好,因为你可以写一个标准的loader程序,然后把被加密的程序当作附加数据来处理。缺点是你必须考虑services程序的这个事实,还有就是加密dll是这种构架的天生弱点。
很快,在时代的步伐下,我各方面进步了,至少自我感觉进步了。我决定重新写一款壳,这壳是我在主动退学后在美丽的家乡居住的时候想到的。关于退学的事我除了说我退学了之外并不想说此时的具体原因。
我的第二代壳:
由于第一代壳的失败,我决定花更多时间来搜集资料,但也不至于没有天理的把自己扔到网页堆里,很快我开始动工了,这壳用的构架是基于寄生被加密pe的构架,也就是在原来的pe上添加一个新区段,然后修改入口,都在这里面完成loader工作,当时我就考虑到vm将会在壳里有所作为,但我并没有意识到我特差的代码能力将使其无所作为,而且当时我还设计了另外一种伪执行模式,是一种简单高效的假vm执行引擎,但是当我使用大量内联汇编尚未达到想要的效果的时候,我开始重新考虑我的代码能力,很快的,这壳流产了。
失败原因也是特差的代码能力,和不够好的构架,我很高兴我有这么多自由时间来完成这样无聊而无结果的工作,这又一次告诉我需要提高自己个方面能力。
关于这样寄生的构架,我并不推荐,初看起来很简单,你不需要考虑新建一个pe所要考虑的各各方面, 你仍然可以做你所有能做的事情,但是你不得不考虑到如何将代码完美的寄生到目标里面去,你也许还会为此写一个code link engine,你会想让代码是多么的灵活,根据不同的选项生成特定的代码,似乎听起来非常的不错,但是当你进一步为你的壳加入新功能的时候,你会发现代码维护越来越困难。直到你开始抱怨。
我的第三代壳:
不久后,我开始在一个小城市和家乡之间来回穿梭,但是即使这样,我仍然有足够的时间,于是呼,我开始写我的第三带壳。也就是后来的pe123。
前两次的失败或多或少让我学到了不少东西, 这款壳的构架是基于新建PE的,加密时是直接拷贝代码方式,也就是代码先在加壳程序里写好,然后直接复制到目标程序,开始一切都很好,很快的,我完成了一系列代码筐架,然后对于那些不够好的代码我只能说,因为当时我已开始使用另外一门开发语言c++,所以对于delphi我只能说我在尚未学好它时已经开始放弃使用它,这是一大遗憾,但是当时总总迹象表明,我必须得放弃它。对于c++我还想说一点,我并没有看多少讲这样那样的学习教程的书,因为那些书上的和教育局书上的差不多一个样,除了个别精品之外,全是叫你用你那并不富裕的记忆记这样那样的语法,所以我选择了另外一总学习方式,参考别人代码,写自己的代码,遇到难题google.扯远了。
pe123我并不以为是一特别失败的壳,即使他很不成熟,而基于这样的构架,很明显是比较有优点的,你可以固定入口,所有代码你不需要重新连接,重新定位,也就是说你不需要写一个类似上面提到的link code engine这样的东西,你可以把代码写好,然后直接复制进去用。然后对于加壳方式我并提倡这样复制粘贴的方式。因为你迟早会发现你同样会陷入管理代码的泥潭而无法自拔。
我的第4代壳:
由于后来我除了写小工具外,几乎不用delphi了,所以本来不够用的代码能力已经无法将这个壳继续延续下去了,所以我一天夜里终于还是打开了vs2005新建了一个名为PeCancer的工程。我的第4个壳开始了。
对于delphi代码能力的不尽人意再一次提醒我在c++上面再也不能重复那样的路子,于是整个PeCancer的开发成了我的一个学习过程,他的大部分代码已经被我写过第二次,刚开始我的壳采用的是那个什么什么b*m*壳的方式的高级版本,也就是拥有一个shell dll,+shell loader的构架,当然也是新建PE,这种构架的好处在于,你将充分享受shell dll为你带来的代码维护便利,你不用担心你的这个函数的代码会不会放错位置,这个函数的调用会不会出问题,你还可以充分享受c++强大的调试能力给你带来的便利,只要你代码遇到问题,那么只要你生成了pdb文件,你可以立刻定位到相映的原代码上,而且shell和加密程序代码完全分开,这样你维护代码将非常轻松,后来我将这个构架又更改了一下,改成了shell dll+shell loader dll模式,放弃了shell loader也靠复制粘贴的依赖,更加易于代码的管理,这样以来,壳的shell部分也拥有任何c++程序可以拥有的模式,比如debug,release,你可以更容易的调试管理,这是我经历前几次调试痛苦之后而产生的想法,因为壳不比其他程序,shell代码位置肯定是要变动的,也就是说这样基本不可能源代码实时调试,至少当前来说。但是你可以通过asm+精确的源代码定位来弥补这个缺陷。
虽然至今我尚未公开过PeCancer的任何版本,但是我想我已经摆脱了加壳技术问题的噩梦,公开他的第一个版本也是迟早问题,我曾经想过开源,因为我没有太多时间来管理,但是被fly一语惊醒,开源的另一个意思就是放弃。但我不想放弃,因为我已经不想写我的第5代壳了。
总结一下上面所说,我说用到的构架中,最后一种是我最推荐的。当然我并没有去调查有没有其他构架,所以仅推荐而已。
有机会我再写一篇关于一些现在加壳所流行的技术,来阐述加壳的人是如何千方百计的***难脱壳者的。