好友
阅读权限30
听众
最后登录1970-1-1
|
一直对SEH的反调试原理不明白,今天终于弄清楚了,放上来看看对那些我一样弄不明白SEH反调试原
理的菜菜看看。并附上相关的CM以及该CM的破解教程的链接地址。
在看过几款CrackMe后大概明白了其做法:
1. 首先利用异常处理例程来进行反跟踪,很多CM都是首先安装好一个异常处理例程,然后故意制造一
个异常,如果 xor eax, eax; mov eax, 1 或者 mov eax, 0 jmp eax 之类的,然后程序抛出异
常,在onllydebug下用shift + F7 或者 shift + F8 进入 ntdll.KiUserExceptionDispatcher,单步
跟踪后最后系统调用用户模块中的异常处理例程. 很多CM都是在异常处理例程编写一个算法来重新将
EIP定位到一个会造成异常的指令地址,重复这个过程几次,这样给调试者一种很难跟踪的假象,这种
一般只要用 shift + F9 (OnllyDebug:该组合键是将异常交给用户程序的异常处理例程来处理,如果
我们想弄清楚异常处理例程到底在做什么,我们可以在异常处理例程下个断点来查看其实现过程。
PS: 见过一个CM是用异常处理例程是每次INT3异常对应一条MSAM语句,这条语句就是注册码生成用的
,所有有时候有必要跟踪异常处理例程。如果整个注册算法很大的话.......
2.未处理异常用于反跟踪的原理 [要是早知道这个我就不会一值很困惑了。。。]
根据MSDN的描述,UnhandledExceptionFilter在没有debugger attach的时候才会被调用。所以,
SetUnhandledExceptionFilter函数还有一个妙用,就是让某些敏感代码避开debugger的追踪。比如你
想把一些代码保护起来,避免调试器的追踪,可以采用的方法:
[a]. 在代码执行前调用IsDebuggerPresent来检查当前是否有调试器加载上来。如果有,就
退出。
. 把代码放到SetUnhandledExceptionFilter设定的函数里面。通过人为触发一个
unhandled exception来执行。由于设定的UnhandledExceptionFilter函数只有在调试器没有加载的时
候才会被系统调用,这里巧妙地使用了系统的这个功能来保护代码。
第一钟方法很容易被绕过。看看IsDebuggerPresent的实现:
0:000> uf kernel32!IsDebuggerPresent
kernel32!IsDebuggerPresent:
281 77e64860 64a118000000 mov eax,fs:[00000018]
282 77e64866 8b4030 mov eax,[eax+0x30]
282 77e64869 0fb64002 movzx eax,byte ptr [eax+0x2]
283 77e6486d c3 ret
IsDebuggerPresent是通过返回FS寄存器上记录的地址的一些偏移量来实现的。([FS: [18]]:30
保存的其实是当前进程的PEB地址)。在debugger中可以任意操作当前进程内存地址上的值,所以只需
要用调试器把[[FS:[18]]:30]:2的值修改成0,IsDebuggerPresent就会返回false,导致方法1
失效。
对于第二种方法,使用[[FS:[18]]:30]:2的欺骗方法就没用了。因为
UnhandledExceptionFilter是否调用取决于系统内核的判断。用户态的调试器要想改变这个行为,要
破费一番脑筋了。
Kwan Hyun Kim提供了一种欺骗系统的方法:
How to debug UnhandleExceptionHandler
http://eparg.spaces.msn.com/blog/cns!59BFC22C0E7E1A76!1208.entry
3.提供几个CM的链接地址
[使用多次异常和未处理异常来反跟踪]
http://bbs.pediy.com/showthread.php?threadid=8155
[使用中断异常产生对应的注册算法,需要很大的耐性。。。。]
http://bbs.pediy.com/showthread.php?t=27224
[利用未处理异常,还没弄明白。。]
http://bbs.pediy.com/showthread.php?t=12217
[SetUnhandledExceptionFilter 的讨论 ]
http://bbs.pediy.com/showthread.php?t=9023 |
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|