windbg各种命令学习

1  dt命令:

dt _peb  直接显示

lkd> dt _peb
nt!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x003 SpareBool        : UChar
   +0x004 Mutant           : Ptr32 Void
   +0x008 ImageBaseAddress : Ptr32 Void
   ··················· 
dt -b _peb  递归式显示

lkd> dt -b _peb
nt!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x003 SpareBool        : UChar
   +0x004 Mutant           : Ptr32 
   +0x008 ImageBaseAddress : Ptr32 
   +0x00c Ldr              : Ptr32 
   +0x010 ProcessParameters : Ptr32 
   +0x014 SubSystemData    : Ptr32 
   +0x018 ProcessHeap      : Ptr32 
   +0x01c FastPebLock      : Ptr32 
   +0x020 FastPebLockRoutine : Ptr32 
   +0x024 FastPebUnlockRoutine : Ptr32 
   +0x028 EnvironmentUpdateCount : Uint4B
   +0x02c KernelCallbackTable : Ptr32 
   +0x030 SystemReserved   : Uint4B
   +0x034 AtlThunkSListPtr32 : Uint4B
   +0x038 FreeList         : Ptr32 
   +0x03c TlsExpansionCounter : Uint4B
   +0x040 TlsBitmap        : Ptr32 
   +0x044 TlsBitmapBits    : Uint4B
   +0x04c ReadOnlySharedMemoryBase : Ptr32 
   +0x050 ReadOnlySharedMemoryHeap : Ptr32 
   +0x054 ReadOnlyStaticServerData : Ptr32 
   +0x058 AnsiCodePageData : Ptr32 
   +0x05c OemCodePageData  : Ptr32 
   +0x060 UnicodeCaseTableData : Ptr32 
   +0x064 NumberOfProcessors : Uint4B
   +0x068 NtGlobalFlag     : Uint4B
   +0x070 CriticalSectionTimeout : _LARGE_INTEGER
      +0x000 LowPart          : Uint4B
      +0x004 HighPart         : Int4B
      +0x000 u                : __unnamed
         +0x000 LowPart          : Uint4B
         +0x004 HighPart         : Int4B
      +0x000 QuadPart         : Int8B
   +0x078 HeapSegmentReserve : Uint4B
   ···········································
dt -r0 _peb  不显示子类型

dt -r1 _peb  显示一级子类型  还没依次


下面是显示 搜索的字符串

dt _teb -ny Client

lkd> dt _teb -ny client//不分大小写
nt!_TEB
   +0x020 ClientId : _CLIENT_ID


dt _peb 7ffdf000  //将7ffdf000 处的数据按照_peb结构显示出来

dt exe文件名!!变量名    //可以显示变量 也可以直接dt 变量名


!pcr  //查看CPU PCR内容


dt nt!_KPCR xxxxxx //可以观察PCR


dt  _heap   或者 dt ntdll!_heap//查看_peb 中的ProcessHeap

lkd> dt _heap
nt!_HEAP
   +0x000 Entry            : _HEAP_ENTRY
   +0x008 Signature        : Uint4B
   +0x00c Flags            : Uint4B
   +0x010 ForceFlags       : Uint4B
   +0x014 VirtualMemoryThreshold : Uint4B
   +0x018 SegmentReserve   : Uint4B
   +0x01c SegmentCommit    : Uint4B
   +0x020 DeCommitFreeBlockThreshold : Uint4B
   `````````````````````````````````````
dt _peb @$peb  //取当前的PEB


dt PEB_LDR_DATA//查看PEB_LDR_DATA结构


//查看_LIST_ENTRY

lkd> dt _LIST_ENTRY 
nt!_LIST_ENTRY
   +0x000 Flink            : Ptr32 _LIST_ENTRY
   +0x004 Blink            : Ptr32 _LIST_ENTRY

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

按MSDN解释是:
Each item in the list is a pointer to an LDR_DATA_TABLE_ENTRY structure,双向循环链表吧,从一个方向开始,不停的循环,就回到初始位了,就相当于遍历了一次
也就是只是上面这个 _LIST_ENTRY是只想LDR_DATA_TABLE_ENTRY结构的

后面可以将这个_LIST_ENTRY结构的地址ldr_data_table_entry结构显示

//查看_ldr_data_table_entry
lkd> dt _ldr_data_table_entry
nt!_LDR_DATA_TABLE_ENTRY
   +0x000 InLoadOrderLinks : _LIST_ENTRY
   +0x008 InMemoryOrderLinks : _LIST_ENTRY
   +0x010 InInitializationOrderLinks : _LIST_ENTRY
   +0x018 DllBase          : Ptr32 Void
   +0x01c EntryPoint       : Ptr32 Void
   +0x020 SizeOfImage      : Uint4B
   +0x024 FullDllName      : _UNICODE_STRING
   +0x02c BaseDllName      : _UNICODE_STRING
   +0x034 Flags            : Uint4B
   +0x038 LoadCount        : Uint2B
   +0x03a TlsIndex         : Uint2B
   +0x03c HashLinks        : _LIST_ENTRY
   +0x03c SectionPointer   : Ptr32 Void
   +0x040 CheckSum         : Uint4B
   +0x044 TimeDateStamp    : Uint4B
   +0x044 LoadedImports    : Ptr32 Void
   +0x048 EntryPointActivationContext : Ptr32 Void
   +0x04c PatchInformation : Ptr32 Void

LIST_ENTRY              InLoadOrderModuleList;          //按加载顺序  
LIST_ENTRY              InMemoryOrderModuleList;        //按内存顺序  
LIST_ENTRY              InInitializationOrderModuleList;//按初始化顺序  
为什么有三个list:其实三个都一样,顺序不同而已.


//查看 cmdline

lkd> dt _peb @$peb
nt!_PEB
   +0x000 InheritedAddressSpace : 0 ''
   +0x001 ReadImageFileExecOptions : 0 ''
   +0x002 BeingDebugged    : 0 ''
   +0x003 SpareBool        : 0 ''
   +0x004 Mutant           : 0xffffffff Void
   +0x008 ImageBaseAddress : 0x01000000 Void
   +0x00c Ldr              : 0x00191e90 _PEB_LDR_DATA
   +0x010 ProcessParameters : 0x00020000 _RTL_USER_PROCESS_PARAMETERS
   +0x014 SubSystemData    : (null) 
   ``````````````````
lkd> dt 0x00020000 _RTL_USER_PROCESS_PARAMETERS
nt!_RTL_USER_PROCESS_PARAMETERS
   +0x000 MaximumLength    : 0x1000
   +0x004 Length           : 0xb34
   +0x008 Flags            : 0x2001
   +0x00c DebugFlags       : 0
   +0x010 ConsoleHandle    : (null) 
   +0x014 ConsoleFlags     : 0
   +0x018 StandardInput    : (null) 
   +0x01c StandardOutput   : 0x00010001 Void
   +0x020 StandardError    : (null) 
   +0x024 CurrentDirectory : _CURDIR
   +0x030 DllPath          : _UNICODE_STRING "C:Program FilesDebugging Tools for Windows (x86);C:WINDOWSsystem32;C:WINDOWSsystem;C:WINDOWS;.;C:WINDOWSsystem32;C:WINDOWS;C:WINDOWSSystem32Wbem;C:Program FilesMicrosoft Platform SDK for Windows XP SP2Bin.;C:Program FilesMicrosoft Platform SDK for Windows XP SP2BinWinNT.;C:Program FilesMicrosoft Visual StudioCommonToolsWinNT;C:Program FilesMicrosoft Visual StudioCommonMSDev98Bin;C:Program FilesMicrosoft Visual StudioCommonTools;C:Program FilesMicrosoft Visual StudioVC98in;C:Program FilesMicrosoft Platform SDK for Windows XP SP2Bin.;C:Program FilesMicrosoft Platform SDK for Windows XP SP2BinWinNT."
   +0x038 ImagePathName    : _UNICODE_STRING "C:Program FilesDebugging Tools for Windows (x86)windbg.exe"
   +0x040 CommandLin
   ``````````````````````

调试器用户经常会需要查看在启动调试目标时使用了哪些命令行参数,这个信息是保存在PEB中的,可以通过!peb来获取,这个命令将解析PEB并给出完整的命令行,所有已加载DLL的位置,以及环境变量等.

http://blog.csdn.net/hgy413/article/details/8490918   学习!peb 中找出 dt _peb @$peb 中 推 出 命令行参数等信息怎么来的

将 InLoadOrderModuleList 地址 换为_LIST_ENTRY 然后子结构都可以用 _ldr_data_table_entry 表示 看到 DLLPATH 和BASE,里面还有  InLoadOrderLinks : _LIST_ENTRY  又用_ldr_data_table_entry表示找出下一个 _ldr_data_table_entry  反复往下弄 找出全部 DLLPATH 和BASE 最后发现返回到第一个DLLPATH 和BASE  ,那么证明这个事一个循环链表




每个进程对应一个EPROCESS结构

dt _eprocess //查看EPROCESS结构

!process 0 0 //得到进程的列表

PROCESS 85e80c20  SessionId: 0  Cid: 0a08    Peb: 7ffd7000  ParentCid: 03b8
    DirBase: 0c0c0540  ObjectTable: e2db9bc8  HandleCount: 2880.
    Image: explorer.exe
    `````````````````
查看 85e80c20  解析EPROCESS

dt _eprocess 85e80c20

lkd> dt _eprocess 85e80c20  
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ProcessLock      : _EX_PUSH_LOCK
   +0x070 CreateTime       : _LARGE_INTEGER 0x1cee669`bb688c8e
   +0x078 ExitTime         : _LARGE_INTEGER 0x0
   +0x080 RundownProtect   : _EX_RUNDOWN_REF
   +0x084 UniqueProcessId  : 0x00000a08 Void
   +0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x8630c630 - 0x86056790 ]
   +0x090 QuotaUsage       : [3] 0x5058
   +0x09c QuotaPeak        : [3] 0x73d0
    ````````````````
   +0x174 ImageFileName    : [16]  "explorer.exe"
dd 85e80c20 + 0x88 得到下一个EPROCESS 的进程链表
要得到下一个EPROCESS的地址 必须减去0x88 才能得到

lkd> dd 85e80c20+0x88
85e80ca8  8630c630 86056790 00005058 000641cc
85e80cb8  0000200f 000073d0 0008a8b4 00002588
85e80cc8  0000200f 12af8000 0ddad000 8630c65c
85e80cd8  860567bc 00000000 e150bf68 e2db9bc8
85e80ce8  e302b94f 00000001 ee01b670 0000000b
85e80cf8  00040001 00000000 85e80d00 85e80d00
85e80d08  00000000 0003e034 00000001 ee01b670
85e80d18  00000011 00040001 00000000 85e80d24

dt _eprocess (8630c630-0x88) 

lkd> dt _eprocess (8630c630-0x88)
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ProcessLock      : _EX_PUSH_LOCK
   +0x070 CreateTime       : _LARGE_INTEGER 0x1cee669`bbb27574
   +0x078 ExitTime         : _LARGE_INTEGER 0x0
   +0x080 RundownProtect   : _EX_RUNDOWN_REF
   +0x084 UniqueProcessId  : 0x000009e4 Void
   +0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x86239c98 - 0x85e80ca8 ]
   +0x090 QuotaUsage       : [3] 0x7f8
   +0x09c QuotaPeak        : [3] 0x7f8
     ``````````````````
   +0x174 ImageFileName    : [16]  "wscntfy.exe"


2 ln  命令

ln (List Nearest Symbols)
The ln command displays the symbols at or near the given address.

Syntax
ln Address 

eg:

lkd> rdmsr 176
msr[176] = 00000000`8053e540
lkd> ln 8053e540
(8053e540)   nt!KiFastCallEntry   |  (8053e649)   nt!KiServiceExit
Exact matches:
    nt!KiFastCallEntry = <no type information>


3 !idt 命令

!idt

The !idt extension displays the interrupt service routines (ISRs) for a specified interrupt dispatch table (IDT). 


Syntax
!idt IDT 
!idt [-a] 
!idt -? 

Parameters
IDT 
Specifies the IDT to display. 
-a 
When IDT is not specified, the debugger displays the IDTs of all processors on the target computer in an abbreviated format. If -a is specified, the ISRs for each IDT are also displayed. 
-? 
Displays help for this extension in the Debugger Command window. 

!idt -a 2e  //显示终端2E的处理函数ISR

lkd> !idt 2e
Dumping IDT:
2e:	8053e481 nt!KiSystemService

int 2e 会执行  KiSystemService  做了一些准备后又会转到 KiFastCallEntry
int 2e 和 sysenter 是差不多的


3 dd dw db命令

·························································

typedef struct _SYSTEM_SERVICE_TABLE   //sst 服务描述表
{
PVOID ServiceTableBase; //这个指向系统服务函数地址表
PULONG ServiceCounterTableBase;
ULONG NumberOfService; //服务函数的个数
ULONG ParamTableBase;
}SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE;
typedef struct _SERVICE_DESCRIPTOR_TABLE  //服务描述表 SDT = SSDT
{
SYSTEM_SERVICE_TABLE ntoskrnel; //ntoskrnl.exe的服务函数
SYSTEM_SERVICE_TABLE win32k; //win32k.sys的服务函数,(gdi.dll/user.dll的内核支持)
SYSTEM_SERVICE_TABLE NotUsed1;
SYSTEM_SERVICE_TABLE NotUsed2;
}SYSTEM_DESCRIPTOR_TABLE,*PSYSTEM_DESCRIPTOR_TABLE;
·························································

typedef struct _ServiceDescriptorTable {
    unsigned int* ServiceTableBase; //System Service Dispatch Table 的基地址  
    unsigned int* ServiceCounterTable;
    //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 
    unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。  
    unsigned char* ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 
}*PServiceDescriptorTable; 
lkd> dd KeServiceDescriptorTable
80553fa0  80502b8c 00000000 0000011c 80503000 //ntoskrnl.导出 KeServiceDescriptorTable只有一个SST
80553fb0  00000000 00000000 00000000 00000000
80553fc0  00000000 00000000 00000000 00000000
80553fd0  00000000 00000000 00000000 00000000 //其他三个SST未使用
80553fe0  00002710 bf80c0b6 00000000 00000000
80553ff0  f7adaa80 f7249b60 86155580 806e2f40
80554000  00000000 00000000 a99b7e04 00000506
80554010  7ee976c4 01ceeb6e 00000000 00000000
lkd> dd KeServiceDescriptorTableShadow        //指派给GUI线程使用
80553f60  80502b8c 00000000 0000011c 80503000 //ntoskrnl.exe 
80553f70  bf999b80 00000000 0000029b bf99a890 //win2k.sys
80553f80  00000000 00000000 00000000 00000000 //其余两个SST未使用
80553f90  00000000 00000000 00000000 00000000
80553fa0  80502b8c 00000000 0000011c 80503000
80553fb0  00000000 00000000 00000000 00000000
80553fc0  00000000 00000000 00000000 00000000
80553fd0  00000000 00000000 00000000 00000000

lkd> dd KiServiceTable
80502b8c  8059a948 805e7db6 805eb5fc 805e7de8 //80502b8c 是上面SDT的ServiceTable
80502b9c  805eb636 805e7e1e 805eb67a 805eb6be
80502bac  8060cdfe 8060db50 805e31b4 805e2e0c
80502bbc  805cbde6 805cbd96 8060d424 805ac5ae
80502bcc  8060ca3c 8059edbe 805a6a00 805cd8c4
80502bdc  80500828 8060db42 8056ccd6 8053600e
80502bec  806060d4 805b2c3a 805ebb36 8061ae56
80502bfc  805f0028 8059b036 8061b0aa 8059a8e8
跟踪 ntdll!ZwCreateFile 设置的索引为25 

lkd> ln poi(KiServiceTable + 4*25)
(8056f27c)   nt!NtCreateFile   |  (8056f2b6)   nt!NtCreateNamedPipeFile
Exact matches:
    nt!NtCreateFile = <no type information>


Native API 总结:


1) ntdll.dll 中ZwXxx 和 NtXxx 函数都是导向ntoskrnl.exe 的Stub函数

2)ntoskrnl.exe 中 ZwXxx 函数也是Stub函数,导向 ntoskrnl.exe的NtXxx函数

3) ntoskrnl.exe 中 NtXxx 函数是所有 Stub 的目的地,是真正做事情的函数

4 poi 命令

poi Pointer-sized data from the specified address. The pointer size is 32 bits or 64 bits. In kernel debugging, this size is based on the processor of the target computer. In user-mode debugging on an Itanium-based computer, this size is 32 bits or 64 bits, depending on the target application. Therefore, poi is the best operator to use if you want pointer-sized data. 


5 bp  下断点命令

bp $exentry //对载入windbg的EXE程序入口点设断点

对指定代码行下断

先要在这个函数中下断
然后
bl查看
14 e b2211490 [z:eooks驱动开发source_code新建文件夹kb_sniff_mpkb_sniffmp.c @ 17]    0001 (0001) Kb_sniffMp!search_irq1
然后就这样下断

kd> bp `Kb_sniffMp!z:eooks驱动开发source_code新建文件夹kb_sniff_mpkb_sniffmp.c:53`  //这里 注意 `  还有   `模块!C文件路径:多少行`


bl  X   //查看断点

bd X  //禁止断点

be X  //恢复断点

ba  //内存断点

ba r 1 xxxxx  //在xxxx下读字节的内存读写断点

e (execute) Breaks into the debugger when the CPU retrieves an instruction from the specified address. 
r (read/write) Breaks into the debugger when the CPU reads or writes at the specified address. 
w (write) Breaks into the debugger when the CPU writes at the specified address. 
i (i/o) (Microsoft Windows XP and later versions, kernel mode only, x86-based systems only) Breaks into the debugger when the I/O port at the specified Address is accessed.  

6 s  搜索命令

s -a 00400000 999999 "Wrong"   //搜索以ASCII码形式存在  从A 开始 B字节内搜索

Shift+F11  跳出函数

7 a  //修改指令

首先,输入a,Enter
然后,输入要修改成的指令
最后,Enter,结束//多少字节要enter几回


8 ~~[xx]  //查看线程ID xx 是属于现在用户调试状态下的哪个



原文地址:https://www.cnblogs.com/zcc1414/p/3982421.html