(编辑:jimmy 日期: 2024/11/10 浏览:2)
在破解程序之前我们先来了解一下 线程环境块TEB 和 进程环境块PEB
TEB:
0x00 ExceptionList:
0x04 StackBase:
0x08 StackLimit:
0x0c SubSystemTib:
0x10 FiberData:
0x14 ArbitraryUserPointer:
0x18 Self: ;其指向TEB结构,其指向其自身0x00处
0x1c EnvironmentPointer:
0x20 ClientId:
0x28 RpcHandle:
0x2c Tls Storage:
0x30 PEB Address: ;其保存进程信息块PEB的地址
PEB:
0x00 InheritedAddressSpace;
0x01 ReadImageFileExecOptions;
0x02 BeingDebugged; ;其标志程序是否被调试
mov eax,dword ptr fs:[0x30]movzx eax,byte ptr ds:[eax+0x2]retn
所以实际上IsDebuggerPresent()函数就是通过检测PEB的BeingDebugged字段来判断程序是否正在被调试。
因为我们修改了其值为0,此时IsDebuggerPresent函数就会认为程序没有被调试,返回值就为0
下面的分析涉及到windows的异常处理(如果不了解windows的异常处理就很难理解)。
因为当程序产生一个异常时,首先会被系统内核捕捉然后系统内核会判断当前是否有调试器调试,有的话把异常交给调试器。如果没有调试器或者调试器处理不了此异常的话,异常会被分发给SEH链上的各个异常处理回调函数依次处理,这些回调函数的地址是通过一个链表存储。通过遍历这个链表从而调用各个异常处理回调函数。如果异常被某个回调函数正常处理了就继续从产生异常的代码处继续往下执行。如果一直遍历到链表的最后一个异常回调函数之前都没能够处理此异常的话,此异常就会交给最后一个默认的异常处理程序处理。
- 而最后一个异常处理回调函数在调用前会先调用UnhandledExceptionFilter( )过滤函数,
- 此函数又会调用ZwQueryInformationProcess( )函数先判断是否有调试器存在,有的话会直接返回进行异常的二次分发(一般就是会结束进程)。
- 如果ZwQueryInformationProcess()函数没有检测到调试器的存在的话其将会调用默认异常处理回调函数。而一般默认异常处理回调函数是默认的终止程序的函数
但是windows提供一个函数来对UnhandledExceptionFilter( )过滤函数进行干预从而修改其返回值让其正常返回,而不执行默认的异常回调函数终止程序。此函数就是SetUnhandledExceptionFilter( ),此函数具有唯一的参数就是设置用来干预UnhandledExceptionFilter( )过滤函数的回调函数的地址,UnhandledExceptionFilter( )会在内部调用这个函数。(一般称这个函数为顶级异常处理回调函数,我认为这么称是不准确的。因为真正的顶级异常处理函数是默认的异常回调函数,此函数应该称为顶级过滤干预函数)
所以我们要想让其调用顶级过滤干预函数对UnhandledExceptionFilter( )的返回值进行干预,从而继续让程序往下执行的话我们应该改变ZwQueryInformationProcess( )函数的Buffer参数,因为函数返回后其为0值表示没有检测到调试器,这样其就可以调用顶级过滤干预函数了
由程序开头处的SetUnhandledExceptionFilter( )我们知道其设置的顶级异常处理回调函数地址为00401108,
链接:[url=https://pan.baidu.com/s/1gUEeudQ3H2hEbVhLTIWNGw]https://pan.baidu.com/s/1gUEeudQ3H2hEbVhLTIWNGw[/url] 提取码:xurl