• 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 是属于现在用户调试状态下的哪个



  • 相关阅读:
    回答提出的问题1-17章
    《构建之法》第13-17章读书笔记
    读《一个程序员的生命周期》有感
    构建之法的第十、十一、十二章读书笔记
    阅读《构建之法》第8,9,10章
    5.2-5.3
    作业5.1测试与封装
    读《构建之法》5.6.7 思考
    读《构建之法》的思考
    作业2 结对思则运算
  • 原文地址:https://www.cnblogs.com/zcc1414/p/3982421.html
Copyright © 2020-2023  润新知