12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
三国霸业 战车-珍宝-觉醒-攻城掠地SF-全新玩法 免费玩新区 攻城掠地私服 进入游戏
手游私服盒子 各类免费游戏 0.1折送海量资源 各类手游私服 进入游戏
皇家MU2 《奇迹 2:传奇》韩国网禅公司《奇迹》正统续作。 3D锁视角Mmrpg 暗黑3+传奇+流放之路+奇迹 进入游戏
查看: 339|回复: 0

Windbg新手入坑指南

[复制链接]

51

主题

51

帖子

112

积分

实习版主

Rank: 7Rank: 7Rank: 7

积分
112
发表于 2021-2-19 16:49:17 | 显示全部楼层 |阅读模式
前言

这篇文章是我学习windbg的一个条记和总结,通过和OD的功能来对比学习windbg的一些理论和下令,到达能调试一个exe大概sys文件的目的。大神请飘过~
认识理论 提高调试效率

在开始调试之前,了解以下理论知识可以资助你大大提高调试效率
定制自己的Windbg界面

windbg默认打开就只有一个Command窗口,但是这样调试效率很低,以是可以先设置好自己的用户界面,下面是我的Windbg界面,因为用惯了OD,以是这个完全就是仿制的OD的界面,

所有窗口都可以状态栏里调出来
设置完成之后,你可以生存到工作空间,这样下次再次打开时这个界面就会生存

关于工作空间

工作空间生存有断点 用户定义的别名 调试器的设置 图形界面信息 调试会话状态等等信息,类似VS的项目文件,PS的工作区。
下令概述

WinDBG主要是以下令方式工作的,WinDBG共支持三类下令:标准下令、元下令和扩展下令
标准下令

标准下令通常是一两个字符(version除外)大概符号,用来提供实用于各种调试目标的最根本调试功能。标准下令是不分巨细写的。比如:

  • g 运行
  • t 单步步入
  • p 单步步过
  • r 查察和修改寄存器
元下令

元下令用来提供标准下令没有提供的调试功能,与标准下令一样,元下令也是内建在调试器引擎大概WinDBG步伐文件中的。
所有元下令都以一个点(.)开始,以是元下令也被称为点下令,例如:

  • .reload 重新载入符号
  • .reboot 重启目标呆板
  • .restart 重启调试器
  • .logfile 显示信息
扩展下令

扩展下令用于扩展某一方面的调试功能。与标准下令和元下令是内建在WinDBG步伐文件中不同,扩展下令是实现在动态加载的扩展模块(DLL)文件中的。
所有的扩展下令都以!开头
通过WinDBG的SDK,用户可以编写自己的扩展模块和扩展下令,例如漏洞测试常用的一个mona插件

  • !mona
调试技巧

在开始调试之前,有几个要点,记住以下几个点对于调试事半功倍

  • 直接按回车可以实行上一条下令
  • 使用分分号作为分隔符,可以在同一行输入多条下令
  • 按上下方向键可以欣赏和选择以前输入过的下令
  • 当下令提示符显示为BUSY时,即使命令编辑框可以输入下令,但是这个下令也不会被马上实行,要等WinDBG恢复到空闲状态才能实行
  • 使用Ctrl+Break 来终止一个长时间未完成的下令。假如使用KD或则CDB,那么用Ctrl+C
  • 选择菜单->Edit_>Write Window Text to File可以把之前敲过的所有下令记录到文件
伪寄存器

WinDBG主动定义了许多伪寄存器。在下令行和下令文件中都可以使用伪寄存器。WinDBG会主动将其替换(展开)为符合的值。例如下面这个@$scopeip就是一个伪寄存器,它代表当前的eip指针

下表列出了windbg所定义的部门寄存器(字典型知识,需要时查阅即可)
伪寄存器含义$ea调试目标所实行上一条指令的有用地址$ea2调试目标所实行上一条指令的第二个有用地址$exp表达式评估器所评估的上一条表达式$ra当前函数的返回地址$eip指令指针寄存器$eventip当前调试事件发生时的指令指针$previp上一事件的指令指针$relip与当前事件关联的指令指针$scopeip当前上下文的指令指针$exentry当前进程的入口地址$retreg主要的函数返回值寄存器$retreg6464位格式的主要函数返回寄存器$csp栈顶指针ESP$p上一个内存显示下令所打印的第一个值$proc当前进程EPROCESS结构的指针$thread当前线程ETHREAD结构的指针$peb当前进程的进程情况块(PEB)的地址$teb当前线程的线程情况块(TEB)地址$tpid拥有当前线程的进程ID(PID)$tid当前线程的线程ID$bpxX号断点的地址$frame当前栈帧的序号$dbgtime当前时间$callret使用.call下令调用的上一个函数的返回值$ptrsize调试目标所在系统的指针类型宽度$pagesize调试目标所在的系统的内存页字节数开始实战

控制调试目标

控制调试目标是调试器的一个核心使命。其宗旨就是使调试目标始终处于调试器的控制之下,让调试人员可以可以随心所欲的控制步伐的实行状态。在OD可以通过图形界面和各种快捷键随心所欲地控制步伐,相比windbg就没那么方便了。但是WinDBG提供了强大的机制和丰富的下令来控制调试目标,这些下令要比OD的功能丰富的多。
单步步入和单步步过


  • t 单步步入
  • p 单步步过
下令格式如下:
p|t [r] [=StartAddress] [count] ["Command"]

  • r表现禁止显示寄存器内容
  • 默认情况下,调试器总是让目标从当前位置开始单步实行,但是也可以通过等号(=)来指定一个新的起始地址,让步伐从这个地址开始单步
  • count用来指定单步实行的次数
  • Command用来指定每次单步实行后要实行的下令
例如:

起首查察一下当前的反汇编,我想从77e40d8e这个位置开始实行单步 单步两次 不显示寄存器 单步实行完成之后显示调用堆栈,就可以实行这么一条下令,实行完成之后如图:
tr =77e40d8e 2 "kb"

单步实行到指定地址

WinDBG提供了pa和ta下令用来实行到指定的代码地址,其下令格式为:
pa|ta [r] [=StartAddress] StopAddress

  • pa是Step To Address的缩写,即单步实行到StopAddress参数所代表的地址处
  • pa和ta的区别在于 ta在遇到函数时会进入函数,windbg的实行结果会显示函数内容;而pa则是直接步过函数,windbg的实行结果不显示函数内容
例如:
查察一下当前的反汇编

假如想直接单步到77e9f137的位置,就可以输入下面这条下令,实行结果如下
par 77e9f137

单步实行到下一个函数调用

与pa和ta下令类似,pc和tc下令用来单步实行到下一个函数调用指令(call)
pc|tc [r] [=StratAddress] [Count]

  • pc或tc下令都是让调试目标从当前地址大概StartAddress指定的地址恢复实行,直到遇到函数调用时停下来
  • Count用来指定遇到的函数调用指令个数
  • 这两个的差别依然是在进入和不进入函数时windbg显示的结果上有区别
例如:
起首来查察一下当前的反汇编

假如想直接单步到77e9f137这个位置的call,就可以直接用下面一条下令
pcr

单步实行到下一个分支

CPU有分支的监视和记录功能,利用这一功能可以实现单步实行到分支,但是这个下令有一个缺陷就是不能在x86的用户态模式下使用,下令格式如下:
tb [r] [=StartAddress] [Count]
继续运行

g(go)下令的一样寻常形式为:
g[a][=StartAddress] [BreakAddress][;BreakCommands]

  • 其实StartAddress用来指定开始实行的起始地址 这个功能有点像OD的此处为新的EIP
  • BreakAddress用来指定一个断点地址
  • BreakCommands用来指定断点命中后所指定下令
  • 假如不带任何参数,那么g下令就是恢复目标运行 相当于OD的F9
  • 可以用gu下令来实行到返回 相当于OD的Ctrl+F9
追踪并监视

假如我们想了解一个函数的实行路径和它调用了哪些其它函数,每个函数包含了多少条指令,但我们又不想一步步的跟踪实行,那么可以使用wt下令让它帮我跟踪实行并生成一份报告给我
下面通过一个例子来解释wt下令的用法,留意:wt下令必须在函数的起始位置处,也就是步入call之后的第一条指令时实行
起首单步步入函数。然后使用wt下令生成报告

可以把wt下令的结果分为六个部门

  • 第一个部门是标题 显示了追踪的函数名和追踪的结束地址
  • 第二部门是详细的实行情况 包括如下四列:
  • 第一列为指令数,这一列的数字就是这个函数从入口进入到下一行所对应的函数入口所实行的指令
  • 第二列用来显示本行所对应的函数调用其他函数时所实行的总指令数
  • 第三列表现函数的调用深度 没进入一个函数深度加一
  • 第四列为函数名称 名称前的缩进用来表现深度
制止调试


  • q 制止调试
  • .detach 分离调试器
区别在于制止调试时调试器和目标步伐的偶制止运行,而分离调试器则是调试器显示No Target,而目标步伐继续运行
总结

下令含义阐明pStep单步步过tTrace单步步入paStep to Address单步到指定地址 不进入子函数taTrace to Address追踪到指定地址 进入子函数pcStep to Next Call单步实行到下一个函数调用tcTrace to Next Call追踪实行到下一个函数调用tbTrace to Next Branch追踪到下一条分支指令gGo恢复运行guGo Up实行到函数返回qQuit制止调试.detachdetach分离调试器使用断点

软件断点

WinDBG设计了三条下令来设置软件断点,分别是bp、bu和bm。其中bp是根本的而且最常用的,其下令格式如下:
bp[ID] [Options] [Address [Passes]] ["Command String"]

  • ID用来指定断点编号 不指定默认从0开始编排
  • Options用来指定选项
  • Address用来指定断点地址
  • Passes用来指定经过断点的次数 默认经过一次断下
  • CommandString用来指定设置断点后实行的下令 用双引号包围下令,多个下令用分号分隔
bu下令用来设置一个耽误的以后再求解的断点,用于对尚未加载模块中的代码设置断点。当指定的模块被加载时,WinDBG会真正落实这个断点。以是bu下令对于调试动态加载模块的入口函数大概初始化代码特别有用
bm下令用来设置一批断点,相当于帮我们主动实行许多次bp大概bu下令。比如以下下令对于msvcr80d模块中的所有print开头的函数设置断点:
bm msvcr80d!print*
bm和bu是下令格式如下:
bu[ID] [Options] [Address [Passes]] ["Command String"]bm[Options]  SymbolPattern [Passes] ["Command String"]其中的Options可以为以下内容

  • /1假如指定此选项,那么这个断点命中一次后便会便主动从断点列表中删除。这种断点被称为一次命停止点
  • /p这个开关只能用在内核调试中,/p后跟一个进程的EPROCESS结构,作用是只有当前进程是指定进程时才触发这个断点
  • /t与/p开关类似,只能用在内核调试中,用来指定一个ETHREAD结构,作用是只有在实行指定的线程访问断点地址时才触发断点
  • /c和/C这两个开关后面可以带一个数字,用来指定停止给用户的最大函数调用深度和最小函数调用深度。举例来说,使用下令bp/c5msvcr80d!printf设置的断点只有当函数调用深度浅于5时才停止给用户
硬件断点

WinDBG的ba下令用来设置硬件断点,其格式如下:
ba [ID] Access Size [Option] [Address[Passes]] ["Command String"]

  • ID用来指定断点序号
  • Access用来指定触发断点的访问方式 可以为以下几个字母之一

    • e 读取和实行时触发断点
    • r 读取和写入时触发断点
    • w 写入时触发断点
    • i 有IO操作时触发断点

  • Size用来指定访问的长度 x86系统可以为1 2 4三种值
  • Passes参数和CommandString参数的用法与设置软件断点下令中的一样
例如:
ba r1 0x401000
那么对内存地址0041717c的一字节访问、字访问、双字访问(读写)都会触发这个断点
假如想要查察硬件断点和状态可以直接看寄存器窗口的DR0-DR7寄存器
条件断点

对 没有错!windbg也支持条件断点,但是这玩意有点复杂,而且实用性好像不大,反正我在OD里从来没用过,直接PASS吧。别的windbg好像是没有内存断点的
地址表达式

可以使用以下三种方法来指定断点下令中的地址参数

  • 直接使用内存地址,比如bp 00411390
  • 使用模块名加函数符号的方式,比如bp dbgee!wmain代表对dbgee模块中的wmain函数设置断点。也可以在符号后增加一个地址偏移,比如bp dbgee!wmain+3
  • 假如是使用完全的调试符号,调试符号中包含源代码行信息,那么可以使用如下形式:
    `[[Module!]Filename][:LineNumber]`
其中Module为模块名,Filename为源步伐文件名,LInenumber为行号。整个表达式要用两个波浪号包起来``,要有调试符号才能实现,对于逆向来说没什么用 这个也pass

  • 对于C++的类方法,也可以使用类名双冒号(::)大概双下划线(__)来连接类名和方法名,比如:
    bp MyClass__MyMethod
    bp MyClass:MyMethod
    bp@@(MyClass::MyMethod)
    管理断点
使用bl下令可以列出当前已经设置的所有断点,例如:


  • 第一列是断点的序号
  • 第二列是断点的状态

    • e代表启用(enable)
    • d代表禁用(disable)
    • 对于bu设置的断点还大概有字母u,表现尚未办理(unresolved)

  • 第三列是断点的地址
  • 第四列是断点触发剩余次数
  • 第五列是断点的初始计数
  • 第六列是断点所关联的进程和线程,冒号前是进程号,冒号后是线程号
  • 第七列是断点地址的符号表现
下令bc、bd、be分别用来删除、禁止和启用断点,它们的格式都是:
bc|bd|be 断点号
其停止点号可以使用*来通配所有断点,使用-来表现一个范围,大概使用逗号来指定多个断点号。例如以下下令都是有用的:
bd 0-2,4  禁止0 1 2 4号断点be *      启用所有断点总结

最后来一个表格总结
下令含义bp设置软件断点bu对未加载的模块设置断点bm批量设置断点ba设置硬件断点bl列出所有断点bc删除断点bd禁止断点be启用断点观察栈

显示栈回溯

WinDBG的k系列下令就是用来资助我们进行栈回溯的,先来看一个例子


  • 其中的每一行代表栈上的一个栈帧 也就是一个函数
  • 最上面一行表现的是当前正在实行的函数 每个函数下面一行是上一行的父函数
  • 第一列是栈帧的基地址EBP
  • 第二列是函数的返回地址
  • 第三列是函数名以及实行位置
K下令显示了函数名信息,但是没有显示每个函数的参数。下令kb可以显示放在栈上的前三个参数,例如(L是不显示源文件信息):


  • 前两列以及最后一列的内容与k下令结果是一样的
  • 中心三列是函数的参数 只显示三个,假如要观察第四个参数可以用  dd ebp+x014
  • 这只是栈上的前三个参数,假如函数的调用约定为fastcall,那么前两个参数还是在ecx和edx
其他K系列的下令:

  • kp下令可以把参数和参数值都以函数原型格式显示出来,但是需要有符号,对于逆向来说没什么用
  • kv下令可以在kb下令的基础上增加显示FPO信息和调用约定
  • kn下令会在每行前显示栈帧的序号
总结

下令含义k显示调用堆栈kb显示调用堆栈和栈上的前三个参数kp参数和参数值都以函数原型格式显示出来(必须有符号)kvkb下令的基础上增加显示FPO信息和调用约定kn下令会在每行前显示栈帧的序号分析内存

显示内存

WinDBG的d系列下令用来显示指定内存区域的数据内容。这些下令的格式为:
d{a|b|c|d|D|f|p|q|u|w|W} [Options] [Range]dy{b|d} [Options] [Range]d [Options] [Range]其中大括号中的字母(区分巨细写)用来指定数据的显示方式,含义如下:

  • a表现ASCII码
  • b表现字节和ASCII码
  • c表现DWORD和ASCII码
  • d表现DWORD
  • D表现双精度浮点数
  • f表现单精度浮点数
  • p表现按指针宽度显示
  • q表现四字(8字节)
  • u表现UNICODE字符
  • w表现字
  • W表现字和ASCII码
  • yb表现二进制和字节
  • yd表现二进制和双字
Range参数用来指定要显示的内存范围。可以有以下几种表现方法:

  • 第一种方法是起始地址加空格加终止地址,比如dd 0012fd9c 0012fda8下令以双字格式显示从0012fd9c开始到0012fda8结束的16字节内存数据
  • 第二种方法是起始地址加空格加L(大概1)和对象个数,比如上面的下令可以等价的写为:dd 0012fd9c L4
  • 第三种方式是结束地址加空格加L(大概1)加负号和对象个数。使用这种方式可以把上面的下令写为:dd 0012fdac L-4
显示字符串

可以以0末了的简单字符串,可以使用da大概du下令来显它的内容,前者用于使用单字节字符集的字符串,后者用于接纳UNICODE字符集的字符串。当遇到字符串末尾的0时,会主动制止显示。例如:du 003a2e9c

显示数据类型

WinDBG的dt下令用来显示数据类型以及按照类型来显示数据。Dt的含义是Dump symbolic Type information。Dt是个比较复杂的下令,下面我们按照用法分别来介绍
起首,可以使用dt来显示一个数据类型(数据结构)。这种用法的典型格式是:
dt[模块名!]类型名
其中模块名部门可以省略,假如省略,那么调试器会主动搜刮所有模块。类型名即步伐中定义数据结构大概通过typedef定义的类姓名。类型名中可以包含通配符,比如以下下令会列出NTDLL模块中的所有类型:
dt ntdll!*
假如类型名是确定的类型,那么dt便会显示这个类型的定义,假如类型中还包含子类型,那么可以用-b开关来递归式显示所有子类型,也可以使用-r开关来指定显示深度。-r0表现不显示子类型,-r1表现显示1级子类型,依此类推,例如:
dt -r1 _TEB
假如不想显示整个结构,而只显示某些字段,那么可以在类型名后使用-ny开关附加字段搜刮选项,比如以下下令只显示TEB结构的LastError开始的字段:
dt _TEB -ny LastError
Dt下令的第二种用法是在上一种方法的基础上增加内存地址,让dt 按照类型显示指定地址的变量。例如,以下下令使用_PEB结构来显示内存地址7ffdd000出的数据:
dt _PEB 7ffdd000
Dt下令的第三种用法是显示类型的实例,包括全局变量、静态变量和函数。比如以下下令显示dbgee步伐的g_szGlobal全局变量:
dt dbgee!*wmain*
搜刮内存

S下令用于搜刮内存,有三种使用方法。

  • 第一种用法是在指定的内存范围内搜刮任何ASCⅡ字符大概UNICODE字符串,其格式如下:

    • s-[[Flags]]sa|su Range
    • Range用来指定内存范围
    • sa用来搜刮ASCII字符串 su用来搜刮unicode字符串
    • Flag可以指定搜刮选项
    例如,以下下令搜刮nt!PsInitialSystemProcess变量所指向地址开始的512个字节范围内任何长度不小于5的ASCIⅡ字符串:
    s-[l5]sa poi(nt!)PsInitialSystemProcessl200

  • 第二种用法是在指定内存地址范围内搜刮与指定对象相同类型的对象,这里的对象是指包含假造函数表的使用面向对象语言(如C++)编写的类(Class)对象。其格式为:

    • s[[Flags]]v Range Object

  • S下令的第三种用法是在指定范围内搜刮某一内容模式,其语法格式为:

    • s[-[[Flags]]Type] Range Pattern
    • 其中类型表现搜刮的内容的数据类型(宽度),可以为b(字节) d(双字)
    • Pattern参数用来指定要搜刮的内容

假如你觉得上面一段话理解起来有点费劲,不妨直接看下面的例子
s 0012ff40 L20 'H' 'e' 'l' 'l' 'o' s 0012ff40 L20 48 65 6c 6c 6f s -a 0012ff40 L20 "Hello" 它们都是等效的。意为在0012ff40到0012ff60之间搜刮hello字符,-a参数指定以ACSII的方式搜刮字符,类似的还有-u,它指定以UNICODE的方式搜刮字符
修改内存

下令e用来修改指定内置地址大概区域的内容,

  • 第一种是按字符串编辑,其下令格式为:

    • e{a|u|za|zu}Address "String"
    • 其中Address是要修改的内存的起始地址
    • za代表以0末了的ASCII字符 zu代表以0末了的Unicode字符
    • a和u分别代表不是以0末了的ASCII和Unicode字符

  • 第二种用法是以数值方式编辑,其格式为:

    • e{b|d|D|f|p|q|w} Address [Values]
    • 其中大括号中的字母用来表现要修改的数据类型,也决定要修改的内存方式
    • Address用来指定要修改的内存起始地址
    • Values用来指定新的值

例如:
Eb 00100000 01 02 03 04      数据类型为BYTEEd 00100000 0201 0403        数据类型为DWORDEa 00100000 ‘hello’          数据类型为ASCIIEu 00100000 ‘你好’            数据类型为UNICODE其他下令

下表记录了我个人认为在调试时常常会用到的一些下令,记录的不全,接待增补
下令含义.attach.attach PID 附加到指定ID的进程.restart重启被调试应用.cls清理屏幕.formats显示数字的各种格式信息lm显示模块.reboot重启假造机r查察或修改寄存器u显示汇编.help查察资助参考资料

《windbg用法详解》
WinDbg下令三部曲
从Ollydbg说起-----WinDbg用户态调试教程:https://bbs.pediy.com/thread-34379.htm

来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
楼主热帖
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|12558网页游戏私服论坛 |网站地图

GMT+8, 2024-11-28 18:37 , Processed in 0.093750 second(s), 32 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表