我们知道不管是在逆向破解还是脱壳,绝大部分的反调试机制是基于异常机制的,如果我们能够知道异常处理函数的地址,那么我们也就知道了敌人的巢穴,剩下的就看我们的能力能不能够摧垮敌人的巢穴了。
我只是简单告诉你怎么找到异常函数的地址,并不会去分析异常的实现机制,因为这就会和主题不符合了.
在找地址之前我先贴出两个至关重要的结构体TEB和PEB
fs:[0]指向TEB结构的开始,其中第一个字段是一个结构体NtTib,NtTib的结构为:
其中NtTib的第一个字段ExceptionList是一个指针指向记录SEH的信息的结构体_EXCEPTION_REGISTRATION_RECORD,该结构体结构为:
看来这个结构是一个单向链表,当Next=0xFFFFFFFF时,表示链表结束.
总结一下找SEH:
我创建一个demo
用OD附加查看main函数:
我们可以看到添加VEH,VCH调用的是
用IDA打开ntdll.dll查看这两个函数
这两个函数最终都调用了RtlpAddVectoredHandler
这个函数有3个参数其中第3个参数代表是VEH还是VCH
可以看到VEH时RtlpAddVectoredHandler的第3个参数为0
VCH时RtlpAddVectoredHandler的第3个参数为1
继续用IDA查看RtlpAddVectoredHandler函数
可有看到_LdrpVectorHandlerList指向了存放VEH和VCH的地方.其中每一个 VEH和VCH会用一个10h大小的空间保存.
_LdrpVectorHandlerList 在ntdll时一个全局参数
经过分析_LdrpVectorHandlerList全局变量的结构类型为
还需要注意的时VEH和VCH的回调i函数指针是经过RtlEncodePointer加密的,所以要获取真实的函数指针地址需要经过RtlDecodePointer解密.
描述总是浅显的,看图
总结:
UEF函数地址的寻找和寻找VEH和VCH是一样的,而且UEF更加简单
用OD附加
用IDA打开Kernel32.dll找到SetUnhandledExceptionFilter
完整代码:
关键代码:
可以看到_BasepCurrentTopLevelFilte这个全局变量就直接保存了UEF的回调函数,当然这个回调函数也是经过加密的,可以通过RtlDecodePointer解密.
在OD中查看关键代码:
总结:
来15PB学习已经有一段时间了,正好学到脱壳,发现很多加密壳都是经过异常来进行反调试的,所以在此也是作一个简单的总结.
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2018-4-24 10:09
被chpeagle编辑
,原因: