具体代码就不贴了,知道原理就可以写出代码。一些是实践所得,一些是别人的成果,也
都收集在一起了。解密、加密这个攻防战好像和传统作战的攻防战不同,防的一方能用的技术
远远多于攻的一方。
1)花指令
很无聊的技巧,但也有一定作用:隐藏指令,干扰分析。
2)花循环
无用循环,让跟踪者浪费时间,心烦。
3)时间比较
经典的反跟踪技巧,单步跟踪比连续执行的时间长很多。
4)父进程检查
被调试器加载后父进程就不是通常的Explorer.exe。
5)检查调试器
Windows本身就提供一些API可以用来检查调试器是否存在。如IsDebuggerPresent/NtQueryInformationProcess。
另外还有CreateFile/PEB(和IsDebuggerPresent一样)等方法检查调试器。
6)动态加/解密代码
干扰分析。把执行过的代码重新加密可以防止跟踪者翻看代码。
7)IAT加密
防止ImpREC等工具的自动脱壳修复,加大脱壳难度。
8)指令摘取
有很多方式,从OEP处摘取指令,随机摘取一段指令等,加大脱壳难度。摘取的指令还可变形处理。
9)CALL处理
根据CALL指令本身特点,让其先CALL进壳的空间,加大脱壳难度。
10)自调试
对于一个程序,Windows只允许这个程序被一个调试器调试,基于此,采用双进程或多进程方式,
自已调试自己,加大跟踪难度。另外,通过设置某中断地址,使程序发生某中断时执行程序中的中断
处理代码,进行解码、指令摘取等动作,加大跟踪难度。
11)异常处理机制
人为产生异常,改变程序流程或在异常处理时进行解码,加大跟踪难度。常见的异常有内存存取
错误异常,中断异常(INT3/单步/其它中断等),非法指令,非法EIP等。
12)多线程的运用
利用被调试程序所有线程会被挂起的特点,达到干扰跟踪的目的。一,用多线程改变程序流程:在
线程中修改主线程代码,如果被单步跟踪线程将不会运行,流程也就不对了。二,用多线程解码:同理,
线程不能运行解码也就不能进行。
13)反SMC
用Timer/线程不断地将敏感的内存空间的属性设置成只读,可以防止被打补丁。
14)CRC校验
代码被修改之后CRC检验值就不同了。
15)破坏调试环境
破坏调试寄存器内容,破坏中断处理地址或自己接管中断处理等,从根本上反调试。
16)反进程转存
将某个不会用到的代码空间设置成NO_ACCESS,LordPE等工具dump到这个空间时就
会异常而dump不了啦。
17)监视键盘
监视F7、F9就够了。
18)固定屏幕
在壳运行期间把屏幕固定,跟踪者看都不看到,当然跟不了。
19)破坏异常处理环境
用SetUnhandledExceptionFilter破坏异常处理环境,使调试器无法捕捉程序产生的异常。
20)调试父进程
利用调试函数的特点,即被调试进程会被挂起的特点,反单步跟踪。
21)Arm的CC保护,CopyMem-II保护
把所有跳转改成CC,父进程检测到INT3中断时查表改EIP去到正常的位置。
CopyMem-II就是把自己复制到另一块内存中去运行,哪么dump的时候就麻烦些啦。
22)反attach分析
执行过的代码就破坏掉,防止attach分析。另外,生成一个指明不能用调试器的进程之后本
身进程直接退出,可防attach。(NT系统有效)
23)指令预取
利用CPU会预读取指令的特点,干扰单步跟踪。如:
mov word ptr [@@],20cdh
@@:
nop
nop
正常情况下CPU预读了2个nop,而不会执行INT 20(cd20),但单步跟踪下来就不同了。
24)写代码时的反调试
对加壳选项的不同而生成不同的代码,这样可以有效地防止脱壳机的patch。只用标志位
来判断是否加密IAT是很危险的。
25)随机存放敏感数据
如果用jmp OEP的方式去OEP,并且代码位置是固定的,哪么写脱壳机时OEP就随手可得了,
所以使代码不定长,或把敏感数据隐藏起来是很好的对策。另外一些壳运行时要用的原程序的
参数放在程序里面比一堆地放在壳后面更安全得多。
26)反汇编
把自己作为一个指令解释器,反汇编自身代码并解释执行,这样就可以防止指令被改。
软件设计的复杂性比单纯的反调试技巧更有效。加密算法的运用更是有力的反脱壳措施。
anti技巧的安排也很重要,比如子程序里面放anti代码要更好些,因为跟踪者要先过双进程
这一关;解码前设置anti dump比解码后设置更好些,因为解码后立即用LordPE的话anti dump
就形同虚设了。
都收集在一起了。解密、加密这个攻防战好像和传统作战的攻防战不同,防的一方能用的技术
远远多于攻的一方。
1)花指令
很无聊的技巧,但也有一定作用:隐藏指令,干扰分析。
2)花循环
无用循环,让跟踪者浪费时间,心烦。
3)时间比较
经典的反跟踪技巧,单步跟踪比连续执行的时间长很多。
4)父进程检查
被调试器加载后父进程就不是通常的Explorer.exe。
5)检查调试器
Windows本身就提供一些API可以用来检查调试器是否存在。如IsDebuggerPresent/NtQueryInformationProcess。
另外还有CreateFile/PEB(和IsDebuggerPresent一样)等方法检查调试器。
6)动态加/解密代码
干扰分析。把执行过的代码重新加密可以防止跟踪者翻看代码。
7)IAT加密
防止ImpREC等工具的自动脱壳修复,加大脱壳难度。
8)指令摘取
有很多方式,从OEP处摘取指令,随机摘取一段指令等,加大脱壳难度。摘取的指令还可变形处理。
9)CALL处理
根据CALL指令本身特点,让其先CALL进壳的空间,加大脱壳难度。
10)自调试
对于一个程序,Windows只允许这个程序被一个调试器调试,基于此,采用双进程或多进程方式,
自已调试自己,加大跟踪难度。另外,通过设置某中断地址,使程序发生某中断时执行程序中的中断
处理代码,进行解码、指令摘取等动作,加大跟踪难度。
11)异常处理机制
人为产生异常,改变程序流程或在异常处理时进行解码,加大跟踪难度。常见的异常有内存存取
错误异常,中断异常(INT3/单步/其它中断等),非法指令,非法EIP等。
12)多线程的运用
利用被调试程序所有线程会被挂起的特点,达到干扰跟踪的目的。一,用多线程改变程序流程:在
线程中修改主线程代码,如果被单步跟踪线程将不会运行,流程也就不对了。二,用多线程解码:同理,
线程不能运行解码也就不能进行。
13)反SMC
用Timer/线程不断地将敏感的内存空间的属性设置成只读,可以防止被打补丁。
14)CRC校验
代码被修改之后CRC检验值就不同了。
15)破坏调试环境
破坏调试寄存器内容,破坏中断处理地址或自己接管中断处理等,从根本上反调试。
16)反进程转存
将某个不会用到的代码空间设置成NO_ACCESS,LordPE等工具dump到这个空间时就
会异常而dump不了啦。
17)监视键盘
监视F7、F9就够了。
18)固定屏幕
在壳运行期间把屏幕固定,跟踪者看都不看到,当然跟不了。
19)破坏异常处理环境
用SetUnhandledExceptionFilter破坏异常处理环境,使调试器无法捕捉程序产生的异常。
20)调试父进程
利用调试函数的特点,即被调试进程会被挂起的特点,反单步跟踪。
21)Arm的CC保护,CopyMem-II保护
把所有跳转改成CC,父进程检测到INT3中断时查表改EIP去到正常的位置。
CopyMem-II就是把自己复制到另一块内存中去运行,哪么dump的时候就麻烦些啦。
22)反attach分析
执行过的代码就破坏掉,防止attach分析。另外,生成一个指明不能用调试器的进程之后本
身进程直接退出,可防attach。(NT系统有效)
23)指令预取
利用CPU会预读取指令的特点,干扰单步跟踪。如:
mov word ptr [@@],20cdh
@@:
nop
nop
正常情况下CPU预读了2个nop,而不会执行INT 20(cd20),但单步跟踪下来就不同了。
24)写代码时的反调试
对加壳选项的不同而生成不同的代码,这样可以有效地防止脱壳机的patch。只用标志位
来判断是否加密IAT是很危险的。
25)随机存放敏感数据
如果用jmp OEP的方式去OEP,并且代码位置是固定的,哪么写脱壳机时OEP就随手可得了,
所以使代码不定长,或把敏感数据隐藏起来是很好的对策。另外一些壳运行时要用的原程序的
参数放在程序里面比一堆地放在壳后面更安全得多。
26)反汇编
把自己作为一个指令解释器,反汇编自身代码并解释执行,这样就可以防止指令被改。
软件设计的复杂性比单纯的反调试技巧更有效。加密算法的运用更是有力的反脱壳措施。
anti技巧的安排也很重要,比如子程序里面放anti代码要更好些,因为跟踪者要先过双进程
这一关;解码前设置anti dump比解码后设置更好些,因为解码后立即用LordPE的话anti dump
就形同虚设了。