美文网首页单位内训
Windbg 调试VC程序

Windbg 调试VC程序

作者: 星夜兼程工作笔记 | 来源:发表于2017-12-12 10:51 被阅读8次

    windbg中的调试指令有三种:  http://www.360doc.com/content/16/1110/14/30953065_605412205.shtml

    1. 基本命令: 调试器自带,提供最基本的调试功能,不区分大小写。 例如 bp ,g  ,dt ,dv ,k,s等

    2. 元命令:调试器自带,以“.”开头. 提供基本命令没有提供的功能。例如 .reload  .sympath等

    3. 扩展命令:外部加入的命令,以“!”开头。用于扩展某一方面的调试功能,其实现在动态加载的模块中。例如:!analyze

    使用;分隔符,可以在一行输入多个命令。使用 ctrl + break 可以终止一个命令。当输入框显示为busy时,即使输入框可以输入命令,输入的命令也不会立刻执行。

    一. windbg 启动调试的办法

    分为两种:

    1. 命令行方式启动:(又分为打开和附加两种方式)

    windbg  - i        // 将windbg设置为默认调试器

    windbg “notepad”  arguments   //使用windbg 启动notepad调试,设置启动参数

    windbg -p  4200    //使用windbg 附加到一个正在运行的PID = 4200的进程

    windbg -pn "notepad"  //使用windbg附加到一个正在运行的名字为"notepad"的进程

    2. 图形界面方式:直接运行windbg.exe

    二. 常用的元命令

    1.   .restart      //重启并调试

    2   .kill             //强制结束当前调试

    3.  .help          //打印出所有元命令

    4.   .hh            //打开windbg  chm帮助文档

    三. 常用基本命令

    1.  搜索命令

           s -a 0012ff40 L0x20 "Hello"     //搜索ansi字符串“hello”, 从0012ff40地址开始, 长度是 0x20的范围。即搜索范围是 0012ff40~ 0012ff60.

     2.  断点命令

          bp 0040108c             //直接在地址下断

          bp test1!Max  ; bp  Max          //直接在函数名上下断

          bp  'test1.cpp:30'                         //在test1.cpp第30行下断

          bp  CObject::CObject           //在CObject构造函数上下断

         bp   kernel32!CreateFileA      //在kernel32.dll模块CreateFileA函数头位置下断

         bp  TestCommand!CObject::add   //在TestCommand.dll模块的CObject类函数add头部下断。

         bp `ConsoleTest.cpp:40` ".if (poi(pVar)>5) {};{g}"

          // ".if (Condition) {Optional Commands}; {g}"    条件断点 pVar指针指向的值>5,执行空语句(;),断住  否则继续执行

          bu  test1!Max  ;bu  Max          //在函数的开头下断

          bm add_*                     // 匹配add_开头的函数,并在这些函数起始处都打上断点

         ba w4 0x0483dfe0// 当对0483dfe0地址写操作时停下,前面要带上0x,否则会报错。

              //ba [r|w|e] [Size] Addr      [r=read/write, w=write, e=execute], Size=[1|2|4 bytes]

               //这个指令比较强大,可以下内存访问,写入以及执行断点。  内存大小Size :单字节, 双字节,4字节,8字节。

     3. 断点管理

    bl       // 列出所有断点     breakpoint  list

    bc *     // 清除所有断点    breakpoint  clear

    bc 1     // 清除1号断点

    bc 1 2 5      // 清除1号、2号、5号断点

    be *       // 启用所有断点   breakpoint   enable

    be 1      // 启用1号断点

    be 1 2 5     // 启用1号、2号、5号断点

    bd *      // 禁用所有断点   breakpoint  disable

    bd 1     // 禁用1号断点

    bd 1 2 5      // 禁用1号、2号、5号断点

    4. 断点执行

    g       // Go(F5)

    gu     // 执行到当前函数完成时停下【Go Up】

    p      // 单步执行(F10)  【Step】

     pc     // 执行到下一个函数调用处停下【Step to  Next Call】

     pa 7c801b0b      // 执行到7c801b0b地址处停下  【Step to Adress】

     t        // Step into(F11) 【Trace】

    tc       // 执行到下一个进入点处停下 【Trace to Next Call】

    ta 7c801b12       // 执行到7c801b12地址处停下 【Trace to Adress】

    5.  进程相关

    |         // 列出调试进程

    |*        // 列出调试进程

    6.  线程相关

    ~       // 列出线程

    ~*       // 所有线程

    ~* k     // 所有线程堆栈信息

    ~* r    // 所有线程寄存器信息

    ~.       // 查看当前线程

    ~0s      // 查看主线程

    ~#      // 查看导致当前事件或异常的线程

    7.  模块相关

    lm     //列出进程加载模块 

    8. 查看变量

    dt     i_c        //查看变量地址, 类型, 值

    dt ntdll!*      // 显示ntdll里的所有类型信息

    dt  *!*IMAGE_DOS*     // 显示所有模块中含有IMAGE_DOS字符的类型信息

    dt myApp!g_app             // 表示显示myApp进程里全局变量g_app的内存布局

    dt WindbgTest!CTest       // 查看模块WindbgTest的CTest的内存布局

    dt WindbgTest!CTest 0x0041f8d4          // 将0x0041f8d4地址处内容按照模块WindbgTest的CTest的内存布局来解析

     dt this                   // 查看this指针的类型及成员变量

    dt  -v   _PEB @$PEB           // 使用详细模式查看PEB(process's environment block)内存结构

    dt   tagMSG 0x0336e54c              // 类型要使用tagMSG,不能使用typedef产生出的MSG

    typedef  struct   tagMSG{

    HWND hwnd;

    UINT message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD time;

    POINT pt;

    } MSG, *PMSG;

    dv               // 显示当前函数内所有局部变量,函数参数的值   

    dv  nCount    // 查看局部变量nCount的值

    x              //显示当前函数内所有局部变量 ,函数参数的值, 包括变量地址、

    x   nCount   // 查看局部变量nCount的值 和地址


    9.  查看堆栈

    k          // 显示当前调用堆栈

    kn        // 带栈编号显示当前调用堆栈

    kb         // 打印出前3个函数参数的当前调用堆栈

    kb 5        // 只显示最上的5层调用堆栈

    kv             // 在kb的基础上增加了函数调用约定等信息

    kp         // 显示每一层函数调用的完整参数,包括参数类型、名字、取值(必须是完整符号的情况下,private symbols);注意:若程序被优化,这些值不一定对

    kd         // 打印堆栈的地址

    dds        //显示栈帧

    10. 显示反汇编

    u      //显示当前eip位置往后的8条指令

    uf CTest::add    // 反汇编CTest类的add函数

    uf /c main         // 反汇编main函数,通过/c可以查看main函数中的函数调用(call)都有哪些

    ub 000c135d L20          // 查看地址为000c135d指令前的20条指令内容


    11.  显示寄存器

    r                // 显示所有寄存器信息及发生core所在的指令

    r eax, edx     // 显示eax,edx寄存器信息

    r eax=5, edx=6       // 对寄存器eax赋值为5,edx赋值为6


    12. 显示内存

    !address       // 查看进程的所有内存页属性

    !address 7ffd8000       // 查看7ffd8000地址处内存页属性

    dd /c 5 7c801e02      // 从7c801e02内存处开始以dword为单位显示内存(宽度为:5)

    dd /c 5 7c801e02 L8    // 从7c801e02内存处开始以dword为单位显示内存(宽度为:5)【显示8个dword】

    da /c 100 7c80ff03     // 从7c80ff03内存处开始显示Ascii字符串(宽度为:100)

    du /c 100 7c8022f5     // 从7c8022f5内存处开始显示Unicode字符串(宽度为:100)

    s -w 522e0000 L0x100  0x1212 0x2212 0x1234    // 表示在起始地址522e0000之后的0x100个单位内搜索0x1212 0x2212 0x1234系列的起始地址

    s -u 522e0000 527d1000 "web"    //表示在522e0000 和527d1000之间搜索Unicode 字符串”web”

    ea 0x445634 "abc"    // 表示在0x445634地址写入Ascii字符串abc, 不包含结束符0

    eza 0x445634 "abc"    // 表示在0x445634地址写入Ascii字符串abc, 包含结束符0

    eu 0x445634 "abc"   // 表示在0x445634地址写入Unicode字符串abc, 不包含结束符0

    ezu 0x445634 "abc"    // 表示在0x445634地址写入Unicode字符串abc, 包含结束符0

    ed nCounter 80      // 将变量nCounter的值修改为80(注:80为10进制还是16进制,还是其他,取决于当前进制)

    .writemem D:\Test\0041a5e4.bin 0041a5e4 L0x1000   // 将内存地址处0x0041a5e4后面0x1000长度的内容拷贝存储到D:\Test\0041a5e4.bin中

    13 查看堆

    !heap -s     // 显示进程堆的个数(每一项是一个堆,也就是_HEAP结构指针,对应的API是HeapCreate)

    dt _HEAP 00140000   // 选取一个堆的地址,打印该堆的内存结构

    !heap -a 00140000   // 选取一个堆的地址,打印该堆的信息,比上面打印内存命令更详细直观

    14. 虚拟内存

    !vadump   // 查看虚拟内存布局

    15. 查看句柄

    !handle   // 查看所有句柄的ID

    相关文章

      网友评论

        本文标题:Windbg 调试VC程序

        本文链接:https://www.haomeiwen.com/subject/krsgixtx.html