设计一款DLL壳需要考虑的问题

因为个人爱好,对程序保护有一些经验。今天向大家分享一下自己的一点小心得。
DLL程序相较于关闭**随机基址**EXE的特别之处有二:

  • 会被映射到一个不确定的位置
  • 程序入口点与dllmain

先说前一点,在内存中不确定的位置意味着重定位表是必须的
第二点,程序入口点,如你所知,程序入口点在PE结构中Optional->AddressOfEntryPoint表示是一个RVA地址,即相对虚拟地址(Relative Virtual Address),详见PE结构介绍文章。EntryPoint(入口点)系统在解析PE文件如果是EXE则直接调用该入口点一次。然后等着结束,遇到DLL时候比较特殊,会以调用函数的方式首先执行一次(多线程另考虑).但是比较特殊的是系统通过三个参数来调用DLL的入口函数,这段代码再通过三个参数调用dllmain()。

加密寄主代码后我们需要保证解密后代码也能正常运行,但是DLL映射位置不一,所以为了保证我们的DLL总是能够在揭秘后执行起来,我们需要自己对解密后的代码进行重定位。

重定位的规则并没有想象中的复杂,重定位表中指出哪些位置需要重定位,即:
该位置的值是在默认的加载基址下的偏移,比如默认基址为0x10 000 000,如果加载到内存中的实际基址是0x12 000 000,那么就需要在每个重定位项指向的地址加上这个差值:0x12 000 000-0x10 000 000=0x2 000 000.所有的目标代码即被重定位完成,又能正确的执行了。

另一点需要注意的地方是,如果你移动了代码的位置你需要这个偏移。

大概是这些吧。有更多可以评论里讨论.
2016年7月25日 22:51:00

分享调试壳设计调试方法

当你的壳程序已经寄生在目标程序上时,如何调试你的壳程序将是一个不得不面对的问题。即使你的shell如此并不复杂而你又是作者,也将免对被优化和变形的代码-这些代码没有符号。
我也曾为此而苦恼过。
通过尝试我将原shell的符号文件.pdb在IDA中通过修正加载基址成功将shell部分的符号起到作用。
方法如下:
File->Load File->PDB File->
Address输入shell的实际加载位置,显然这个位置是shell部分MZ所在位置而不是当前整个寄生文件的起始。

2016年9月8日星期四 23:31更新

你可能感兴趣的:(实践)