加密与解密,可作为经常查阅的工具书,比如查各种jmp的机器码,除法的编译,虚表详述。书中用源代码-无优化-有优化的对比来叙述。有优化这块算是盲区了,比如连续switch会编译成跳表,不连续的也会做衰减判断(自动调整为从小号到大号的顺序),lea可以拿来做算数加法,等等。
私人壳往往被当作病毒处理。商用壳则有兼容性问题。所以现在正经软件的保护一般不加壳,而是靠序列号设计。
虚拟机壳的设计思路是提高分析成本。将x86指令替换成自己的字节码,然后执行虚拟机解释字节码。
效率换安全,一条指令会膨胀几十上百倍。一般只对关键代码做保护。
VMProtect的使用有两种方式,一种是直接指定要保护的起止地址。另一种是SDK方法,开发的时候加个关键字VMProtectbegin和VMProtectend标记,然后用VMProtect打开编译后的exe实施保护。
这是目前最流行的趋势。
压缩可以慢,解压必须快。常见的压缩引擎包括aPLib,JCALG1,LZMA。
跟卖服务器的CC保护不是一个意思,他们那个说的是DDoS。
将子进程中所有跳转指令换成INT 3指令(CC)。父进程负责截获异常,并计算正确的跳转地址。
在调试器中,看见的都是call 立即数,call [ebp+x],很容易茫然。书中给了一个例子,流程如下:
最终目标是文件能够正常运行。
一种方法是,从壳的开始处跟踪,直至到达代码段。
感觉这是一种不错的反调试方法。在可执行文件的末尾附加上一段数据,这段数据不会被映射进内存,块表里也看不见。所以脱壳时dump内存,结果无法正常运行(信息损失了)。
除了将附加数据粘贴到脱壳结果,代码上可能也需要修改文件指针的偏移量,总之最终要确保能读取附加数据。
基本标准是可以运行。完美则不止于此。
将汇编指令改为EB FE,就能简单实现一个死循环。FE是-2。
魔改的目的是,用最少的劳动阻止upx -d官方脱壳。
upxpr,只修改了两个地方(块名和upx!),手工改回来即可。判断时或许可以看段总数和段名。
upxfix_by_diken,这个在看雪上能找到,据说能把魔改壳改回普通壳。
upx破坏了输入表和重定位表,并且会合并区块。而aspack则都不会。
aspack直接对text段的实际内存地址(imagebase+text voffset)下写断点,就能等到解压完毕。
用得比较广泛、研究得也比较多的加密壳。
dll的oep可以在载入时找,也可以在退出时找。退出时找更容易,书中示例也都是退出时找。
可以patch任意一条指令而做到只添加不删除。
比如将or al,al指令修改为jmp,
在jmp的目标位置先做想做的事(先pushad,最后popad),此过程中可以用hideOD这样的插件来分配空间,
然后最后or al,al,再jmp回原来or al, al的下一条指令。
beingdebugged为true,为影响ntglobalflag,进一步影响heap flag,影响堆的填充内容。如果不从源头上消灭,会留下很多痕迹。
任何单个的反调试手段,破解起来都不困难。将常见的手段组合起来,就能拖垮耐心。
除了检查窗口名称和进程名称,其实还有很多方法。
windows提供了进程间互访内存的函数,readprocessmemory和writeprocessmemory。用virtualprotect函数设置权限之后,就能读写进程的地址空间。
类似Linux的preload library,但只能劫持非核心系统库DLL,比如网络应用程序中的ws2_32.dll和游戏中的d3d8.dll,以及大部分应用程序都会用的lpk.dll。
如果不方便用调试器启动,可以先启动目标进程,然后附加。调试游戏时一般附加。
切记,试用版不能包含重要功能的代码。
序列号机制的本质是,对比用户输入序列号和内置算法生成序列号。
较为简单的注册机的本质是正向(而非逆向)抠出了内置生成算法,此算法一般的输入是用户名、机器信息等。
“期望的用户输入”在任何时候都不应该出现在内存中。生成端再复杂都没用,关键是用户输入端。CTF中也是如此,以strcmp为界,其实只有输入一侧需要研究。
如果使用对称加密的话,用户输入的注册码应作为密钥,而不是明文。否则密钥就只能硬编码,硬编码的结果就是别人容易写出注册机。对称加密的秘密是密钥。
如果使用非对称加密的话,生成算法不放在软件本地,版权方用私钥签名来生成。输入端需要输入一个能被公钥成功验签的内容。
针对各类签名算法的软件保护,都可以用patch n的方法来攻击。有点打包重签名的意思。修改算法中的大数n,自己制定私钥,写出注册机,一起重新发布即可。
取证标准要求不能开机。硬盘被系统挂载时会有数据写入,导致污染。
不能拆机时,使用linux可启动光盘启动目标计算机,然后用dd命令复制硬盘。
能拆机时,可以借助硬盘复制机连接src和dst,或者用另一台取证计算机(linux用dd,windows用winhex)。
手机自带的闪存芯片焊在主板上,部分手机会用SD卡。前者可以用热风枪吹下来(chip-off,但有损坏风险),后者直接用读卡器即可。
自带存储的取证可以用JTAG法,通过跳线将手机置于调试模式。
对于已root、开启usb调试的手机上,将/system分区以读写模式重新挂载,把busybox装进/system/xbin,然后nc、dd。
移动设备中不能被用户使用的分区有很多。正常情况下,只有/data和/mnt/sdcard以读写模式挂载,因此大多数取证操作中只需要检查这两个分区就可以了。