栈调试分析


栈分析:

0: kd> kv           
00 98803784 99d60f41 88e0fe00 98803814 98803810 DoubleCBFilter!PfpGetFullPathPreCreate (FPO: [Non-Fpo]) (CONV: stdcall)
01 98803890 99d61303 00000000 86f1d020 88e0fe00 DoubleCBFilter!PfpCommonCreate+0x301 (FPO: [Non-Fpo]) (CONV: stdcall)
02 988038b0 83e50593 86f1d020 88e0fe00 8889937c DoubleCBFilter!PfpCreate+0xb3 (FPO: [Non-Fpo]) (CONV: stdcall) 
03 988038c8 840602a9 9ab230df 98803a70 00000000 nt!IofCallDriver+0x63

.....




第一部分:
.frame 02    <----切换到PfpCreate的栈上下文中
然后命令: uf DoubleCBFilter!PfpCreate+0xb3   <-----反汇编pfpCreate代码
可以看到:
DoubleCBFilter!PfpCreate+0xa4 [filespycreate.c @ 676]:
  676 99d612f4 8b550c          mov     edx,dword ptr [ebp+0Ch]   <---获取参数3,是一个入参
  676 99d612f7 52              push    edx <---参数3入栈
  676 99d612f8 8b4508          mov     eax,dword ptr [ebp+8] <---计算参数2,也是一个入参,所以也用ebp来计算
  676 99d612fb 50              push    eax
  676 99d612fc 6a00            push    0 <---这个是参数1,是个NULL
  676 99d612fe e83df9ffff      call    DoubleCBFilter!PfpCommonCreate (99d60c40)   <----开始调用PfpCommonCreate


对应的代码: return PfpCommonCreate(NULL, DeviceObject, Irp);
(注:  NTSTATUS  PfpCreate(
__in PDEVICE_OBJECT DeviceObject,   <----这个是入参1, 放在bp+8位置
__in PIRP Irp     <----这个是入参2, 放在bp+0C位置,栈中的参数存放从(栈顶向下:参数N...参数1)
)  <-----这个是PfpCreate的参数
}


第二部分:

.frame 01   <-----切换到01的栈上下文中
.open -a DoubleCBFilter!PfpCommonCreate  <----可以直接打开源码
然后命令:  uf DoubleCBFilter!PfpCommonCreate
太多找不到就.cls清理屏幕
温习上次的调试说明:
DoubleCBFilter!PfpCommonCreate 
  354 99d60c40 55              push    ebp <-----先保存上次的ebp
  354 99d60c41 8bec            mov     ebp,esp <-----然后保存当前的esp到ebp上,此时的ebp就是新的栈顶,最后还可以用这个ebp来直接恢复esp
  354 99d60c43 81ecf4000000    sub     esp,0F4h <-----给当前的函数创建局部变量空间


...............
//这里都是call函数PfpGetFullPathPreCreate()之前的参数入栈的操作,看后面的马上要调用的函数原型
  484 99d60f2c 8b4d0c          mov     ecx,dword ptr [ebp+0Ch] <--------因为是入参,直接用ebp来获取计算
  484 99d60f2f 51              push    ecx <--------参数4,入栈
  484 99d60f30 8d5580          lea     edx,[ebp-80h] <--------这个是局部变量,所以是ebp减去80的位置了,前面说了,ebp下面是局部变量空间
  484 99d60f33 52              push    edx <--------参数3,入栈
  484 99d60f34 8d4584          lea     eax,[ebp-7Ch]
  484 99d60f37 50              push    eax
  484 99d60f38 8b4d10          mov     ecx,dword ptr [ebp+10h] <--------这个也是之前的入参
  484 99d60f3b 51              push    ecx
  484 99d60f3c e81f040000      call    DoubleCBFilter!PfpGetFullPathPreCreate (99d61360)  <----又开始进行新函数调用了!!




(注: 调用的函数原型 
NTSTATUS PfpGetFullPathPreCreate(
PIRP pIrp,
WCHAR** pszFullPathWithOutDeviceName,
ULONG* szLenReturnedInBytes,
PDEVICE_OBJECT pDevice)
)


-----------------
从上面这个简单的栈分析,就可以看到函数的每次的在栈中的调用运行关系
dt _tagstruct addr   <-----这样就可以直接看当前栈的变量了
dv 所有变量

你可能感兴趣的:(Windows环境和调试)