第一部分 调试目标程序的函数
.call命令的原理
我们使用.call调试被调试程序的函数。利用.call元命令可以不需要使函数运行到函数调用处,而是类似于进行一次虚拟调用。具体原理如下:
- windbg在栈上创建一小段代码,这段代码用于被调用函数的父函数,函数返回到这段代码,然后中断。
- 在栈上创建一个新的关于被调用函数的栈帧,用于模拟被调用函数
- 修改寄存器,使程序指向模拟被调用的函数的起始地址,保证恢复程序运行就能执行这个函数
限制条件
- 只能支持调试用户态程序时使用
- 被调用函数的私有符号120:000>x degee!wprint*04113f6 degee!wprintf=<no type information>
控制进程和线程
对线程的控制
~:查看当前调试对象的所有线程
123450:000> ~. 0 Id: 220.2ebc Suspend: 1 Teb: 0119d000 Unfrozen1 Id: 220.684 Suspend: 1 Teb: 011a0000 Unfrozen2 Id: 220.27f8 Suspend: 1 Teb: 011a3000 Unfrozen3 Id: 220.2d90 Suspend: 1 Teb: 011a6000 Unfrozen~ ThreadId:查看特定的线程信息
~ ThreadId n:增加指定线程的挂起计数(调用SuspendThread)
123456789100:000> ~11 Id: 220.684 Suspend: 1 Teb: 011a0000 UnfrozenStart: ntdll!TppWorkerThread (76ee38a0)Priority: 0 Priority class: 32 Affinity: f0:000> ~1 n0:000> ~. 0 Id: 220.2ebc Suspend: 1 Teb: 0119d000 Unfrozen1 Id: 220.684 Suspend: 2 Teb: 011a0000 Unfrozen2 Id: 220.27f8 Suspend: 1 Teb: 011a3000 Unfrozen3 Id: 220.2d90 Suspend: 1 Teb: 011a6000 Unfrozen~ ThreadId m:减少指定线程的挂起计数(调用ResumeThread)
1234560:000> ~1 m0:000> ~. 0 Id: 220.2ebc Suspend: 1 Teb: 0119d000 Unfrozen1 Id: 220.684 Suspend: 1 Teb: 011a0000 Unfrozen2 Id: 220.27f8 Suspend: 1 Teb: 011a3000 Unfrozen3 Id: 220.2d90 Suspend: 1 Teb: 011a6000 Unfrozen~ ThreadId f:冻结特定线程
- ~ ThreadId g:恢复执行特定线程
- ~ ThreadId s:切换到特定线程
对进程的控制
- 使用|命令实现对进程的控制。操作和线程一致。