Windbg命令学习7(d*s和~s (n m ~f ~u))
以下默认windbg加载calc程序
1.d*s
dds、dps和dqs命令显示给定范围内存的内容,它们是把内存区域转储出来,并把内存中每个元素都视为一个符号对其进行解析,dds是四字节视为一个符号,dqs是每8字节视为一个符号,dps是根据当前处理器架构来选择最合适的长度
比如要看看当前stack 中保存了哪些函数地址,就可以检查ebp 指向的内存
0:000> dds ebp 0007fdfc 0007ff1c 0007fe00 010021b0 calc!WinMain+0x25f 0007fe04 0007fee8 0007fe08 00000000 0007fe0c 00000000 0007fe10 00000000 0007fe14 7c80b741 kernel32!GetModuleHandleA 0007fe18 000a232f 0007fe1c 00000000
由于 COM Interface 和C++ Vtable 里面的成员函数都是顺序排列的,所以这个命令可以方便 地找到虚函数表中具体的函数地址。比如用下面的命令可以找到OpaqueDataInfo 类型中虚 函数对应的实际函数地址:
0:002> x ole32!OpaqueData* 76aa6a41 ole32!OpaqueDataInfo::GetOpaqueData = <no type information> 76aa6b3b ole32!OpaqueDataInfo::UnSerialize = <no type information> 76aa6c16 ole32!OpaqueDataInfo::SerializableQueryInterface = <no type information> 76aa5748 ole32!OpaqueDataInfo::QueryInterface = <no type information> 76aa6393 ole32!OpaqueDataInfo::CopyOpaqueData = <no type information> 76aa5757 ole32!OpaqueDataInfo::AddRef = <no type information> 76a57107 ole32!OpaqueDataInfo::UnSerializeCallBack = <no type information> 76aa5766 ole32!OpaqueDataInfo::Release = <no type information> 769a697c ole32!OpaqueDataInfo::`vftable' = <no type information> 76aa69cb ole32!OpaqueDataInfo::AddOpaqueData = <no type information> 769bfae2 ole32!OpaqueDataInfo::GetOpaqueDataCount = <no type information> 76aa6b24 ole32!OpaqueDataInfo::Serialize = <no type information> 769c9df3 ole32!OpaqueDataInfo::AddRef = <no type information> 769c9ebc ole32!OpaqueDataInfo::Release = <no type information> 76aa6a97 ole32!OpaqueDataInfo::DeleteOpaqueData = <no type information> 76aa6bc9 ole32!OpaqueDataInfo::GetCLSID = <no type information> 76aa57c0 ole32!OpaqueDataInfo::OpaqueDataInfo = <no type information> 769c1cb0 ole32!OpaqueDataInfo::GetAllOpaqueData = <no type information> 76aa54b9 ole32!OpaqueDataInfo::~OpaqueDataInfo = <no type information> 76aa6be9 ole32!OpaqueDataInfo::SetParent = <no type information> 76aa5693 ole32!OpaqueDataInfo::`scalar deleting destructor' = <no type information> 76aa6b78 ole32!OpaqueDataInfo::GetSize = <no type information> 76aa6540 ole32!OpaqueDataInfo::QueryInterface = <no type information> 769a69a0 ole32!OpaqueDataInfo::`vftable' = <no type information> 0:002> dds 769a69a0 769a69a0 76aa6540 ole32!OpaqueDataInfo::QueryInterface 769a69a4 769c9df3 ole32!InstanceInfo::AddRef 769a69a8 769c9ebc ole32!InstantiationInfo::Release 769a69ac 76aa69cb ole32!OpaqueDataInfo::AddOpaqueData 769a69b0 76aa6a41 ole32!OpaqueDataInfo::GetOpaqueData 769a69b4 76aa6a97 ole32!OpaqueDataInfo::DeleteOpaqueData 769a69b8 769bfae2 ole32!ServerLocationInfo::GetRemoteServerName 769a69bc 769c1cb0 ole32!CComProcessInfo::GetProcessName 769a69c0 76a57107 ole32!InstanceInfo::UnSerializeCallBack 769a69c4 00000021 769a69c8 76a2d73d ole32!CClassMoniker::QueryInterface 769a69cc 76a339fb ole32!CErrorObject::AddRef 769a69d0 76a0679a ole32!CClassMoniker::Release 769a69d4 76a06a39 ole32!CClassMoniker::GetUnmarshalClass 769a69d8 76a06a56 ole32!CClassMoniker::GetMarshalSizeMax 769a69dc 76a06a99 ole32!CClassMoniker::MarshalInterface 769a69e0 76a2d2b9 ole32!CClassMoniker::UnmarshalInterface 769a69e4 76a07099 ole32!CClassMoniker::ReleaseMarshalData 769a69e8 769e288e ole32!CDdeObject::COleItemContainerImpl::IsRunning 769a69ec 76a2d72e ole32!CClassMoniker::QueryInterface 769a69f0 76a339dd ole32!CErrorObject::AddRef 769a69f4 76a06ab8 ole32!CClassMoniker::Release 769a69f8 76a069d1 ole32!CClassMoniker::GetComparisonData 769a69fc 90909090 769a6a00 76a066c9 ole32!CClassMoniker::QueryInterface 769a6a04 76a05efd ole32!CSCMergedEnum<IEnumCATEGORYINFO,tagCATEGORYINFO>::AddRef 769a6a08 76a067a6 ole32!CClassMoniker::Release 769a6a0c 76a068f3 ole32!CClassMoniker::GetClassID 769a6a10 769acee9 ole32!CDdeServerCallMgr::AddRef 769a6a14 76a2d7f2 ole32!CClassMoniker::Load 769a6a18 76a06931 ole32!CClassMoniker::Save 769a6a1c 76a07055 ole32!CClassMoniker::GetSizeMax
2.~s
~s命令设置或显示当前线程号
只能在用户模式下指定线程。在内核模式下,波形符(~)用于引用处理器
0:001> ~0s eax=00000404 ebx=00000000 ecx=00000410 edx=0004c0d0 esi=0012f7f0 edi=00260688 eip=7c92e514 esp=0012f790 ebp=0012f7b0 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 ntdll!KiFastSystemCallRet: 7c92e514 c3 ret 0:000> k ChildEBP RetAddr
我们注意到,调用k时,前缀变成了0:000,这就表明成功切换到0号线程
我们可以通过~thread n来增加线程的挂起计数,相当于调用SuspendThread,而~m对应是减少线程的挂起计数,相当于调用ResumeThread
另可以通过~f来冻结一个线程 ,~u来解冻一个线程,当一个线程处于冻结状态时,恢复目标执行时这个线程不会恢复执行
0:000> ~ . 0 Id: 3a18.357c Suspend: 1 Teb: 7ffde000 Unfrozen 1 Id: 3a18.3bb8 Suspend: 1 Teb: 7ffdd000 Unfrozen 0:000> ~f 0:000> ~ . 0 Id: 3a18.357c Suspend: 1 Teb: 7ffde000 Frozen 1 Id: 3a18.3bb8 Suspend: 1 Teb: 7ffdd000 Unfrozen 0:000> g Breakpoint 1 will not be deferred because of changes in the context. Breakpoint may hit again. System 0: 1 of 2 threads are frozen