1.垃圾代码
向程序添加大量无意义的代码来增加代码调试的难度,这就是“垃圾代码”反调试技术。尤其是,这些垃圾代码中还含有真正有用的代码或者应用其他反调试技术时,调试程序会变得更加困难。
1)一些指令(PUSH/POP、XCHEG、MOV)拥有相同的操作数,最终执行的是一些无意义的运算。(命令执行后没有什么变化)
2)将一些简单的指令复杂化实现,增加分析难度。
2.扰乱代码对齐(花指令)
通过巧妙的编写汇编代码,实现干扰调试器反汇编的结果,让反汇编看上去一团乱。
在正常的汇编中插入多余的call、jmp等半个指令。而实际上运行时,在这些半个指令上面可能是直接跳转到下面执行的。但反编译会老老实实的一行一行解析,导致连同错误的半指令也会被反汇编,最终导致后面的指令全部错位。
3.加密/解密
加密/解析(Encryption/Decryption)是压缩器与保护器中经常使用的技术,用来隐藏程序代码与数据,从而有效防止调试分析程序。
在运行的过程中动态的修改汇编指令,使得dump都无法获取完整的转存。
4.Stolen Bytes(Remove OEP)
Stolen Bytes技术将部分源代码(主要是OEP代码)转移到压缩器/保护器创建的内存区域运行。
该技术的优点是,转存进程内存时,一部分OEP代码会被删除,转存的文件无法正常运行反转存技术。
另外一个优点是,应用Stolen Bytes技术的文件再次经过压缩器/保护器压缩后,会给逆向分析人员造成很大的混乱。文件脱壳后,得到的不是熟悉的OEP代码,而是其他形态的代码,这很难判断是脱壳成功还是继续操作。容易引起代码逆向分析人员的混乱。
5.API重定向
程序保护器会将主要的API代码复制一份到其他的内存区域中,然后修改API调用的地方,让其调用修改后的API,这样可用来防止调试者在API中下断点。并且,在API函数复制到其他内存区域时,还会加入混淆、花指令等反调试技术。这使得调试难度再次增加。当调试者在正真的API上下断点时会发现,程序压根就不经过0.0。
6.Debug Blocker(Self Debugging)
这是一种高级反调试技术,顾名思义,它在调试模式下运行自身进程。
该技术采用的是双进程运行的方法,父进程会再次启动自身,而主要的业务代码将会在子进程中执行。由于父进程使用的是调试模式执行的子进程,这使得其他调试器无法附加到子进程上。由于父进程是调试者,所以可以完全控制子进程的执行流程,包括进程的异常等。两者交缠再一起形成了调试难度极大的双子星。