Re: 请教:78页KiTrap03中将程序指针寄存器减1
《软件调试》答疑
请教:78页KiTrap03中将程序指针寄存器减1
saviola
2011-07-05, 11:10 上午
请教一下那段带有dec ebx的汇编代码,是如何实现EIP减1的?
Re: 请教:78页KiTrap03中将程序指针寄存器减1
saviola
2011-07-05, 11:16 上午
哦,我可能明白了,是把压在栈中的EIP值减了1,return时跳到原执行指令的位置。不知对不对?
Re: 请教:78页KiTrap03中将程序指针寄存器减1
格蠹老雷
2011-07-05, 22:13 下午
很好的问题,这个地方将EBX减1后,作为参数传递给CommonDispatchException。后者内部会分配一个EXPCEPTION_RECORD结构,然后将减1后的EIP值放到EXPCEPTION_RECORD的ExceptionAddress字段中,即如下代码:
nt!CommonDispatchException:
818537f0 83ec50 sub esp,50h ;; 在栈上分配 EXCEPTION_RECORD
818537f3 890424 mov dword ptr [esp],eax
818537f6 33c0 xor eax,eax
818537f8 89442404 mov dword ptr [esp+4],eax
818537fc 89442408 mov dword ptr [esp+8],eax
81853800 895c240c mov dword ptr [esp+0Ch],ebx ;; ExceptionAddress dt _EXCEPTION_RECORD
nt!_EXCEPTION_RECORD
+0x000 ExceptionCode : Int4B
+0x004 ExceptionFlags : Uint4B
+0x008 ExceptionRecord : Ptr32 _EXCEPTION_RECORD
+0x00c ExceptionAddress : Ptr32 Void
+0x010 NumberParameters : Uint4B
+0x014 ExceptionInformation : [15] Uint4B
这样修改后,ExceptionAddress 就指向了断点处本来指令的起始位置,这对于分析异常信息是很重要的。
其实还有一个地方调整EIP,就是在KiDispatchException函数中:
8182f7e9 8b03 mov eax,dword ptr [ebx] ;; ExceptionRecord.ExceptionCode
8182f7eb 3d03000080 cmp eax,80000003h ;; STATUS_BREAKPOINT
8182f7f0 0f84a9000000 je nt!KiDispatchException+0x130 (8182f89f)
...
8182f89f ff8dd0fdffff dec dword ptr [ebp-230h] ;; 将CONTEXT结构中的EIP减1
注意这里是将以局部变量形式存在的CONTEXT结构中的EIP字段减去1,没有直接修改KTRAP_FRAME,这是KiDispatchException函数的总体设计决定的,在这个函数开始会根据KTRAP_FRAME得到CONTEXT结构:
8182f7e4 e8a46e0100 call nt!KeContextFromKframes (8184668d)
在末尾再将CONTEXT结构中的信息复制会KTRAP_FRAME,这样处理后,保存在栈上的KTRAP_FRAME结构中的EIP便也变化了,也指向断点处本来指令的起始地址,此后,再执行iret指令异常返回后,CPU便从KTRAP_FRAME中恢复EIP,重新执行断点处的指令了