加密与解密 调试篇 动态调试技术 (五)-WinDbg

news/2024/11/22 18:40:03/

windbg主要厉害的地方是在他可以对内核调试

并且本身微软的产品 对windows调试适配度够高

注意 windbg给出的图形操作并不好用  主要是使用命令行来进行操作

我们省略安装

直接进入调试

file 可以打开软件 可以附加也可以分析dump文件还可以进行内核和 远程调试
内核调试分为5种NET  USB 1394 COM和本地调试前面四种是双机调试模式  附加进程的非入侵模式调试 dump文件调试和本地内核调试都是属于非实时调试模式
不能直接控制被调试目标的中断和运行一般是用来观察的也可以用来修改内存数据

1.开始调试

Ctrl+E 打开程序F6可以附加调试在windbg中反汇编代码默认停止在 ntdll.dll 的系统断点处并不会停在程序入口处

我们需要在命令窗口 输入g@$exentery 转到程序入口

2.这里给出目标的执行命令

单步跟踪命令
命令快捷键功能
tF8/F11跟踪执行,进入call
pF10单步执行,不进入call
gF5运行程序
pa 地址单步到指定地址 并且不进入call
ta 地址追踪到指定地址 并且进入call
pc [count]单步执行到下一个call调用
tc [count]追踪到下一个call调用,遇到call进行跟进
tb [count]

追踪到下一条分支指令 遇到call进行跟进

【只适用于内核调试】

pt单步执行到下一条call的返回
tt追踪到下一条call的返回,并且遇到call进行跟进
ph单步执行到下一条分支指令
th追踪执行到下一条分支指令,遇到call进行跟踪
wt自动追踪函数执行过程
$ra代表当前函数的的返回地址所以使用
“pa @$ra”来走出当前函数pc和tc都是执行到下一个call指令count用于指定 遇到call的个数默认是1如果count为1 pc和tc这两个指令是等价的

3.这里给出的是断点指令

1.软件断点

bp断点

bp[ID] [Options] [Address [Passes]] ["CommandString"]
ID : 指定断点options:
/l :一次性断点
/c :指定最大调用深度 大于这个深度断点不工作
/C :指定最小调用深度 小于这个深度断点不工作Address:
地址或符号 例如 MessageBoxWPasses:忽略中断的次数CommandString : 指定一组命令 当断点中断的时候 自动执行这些命令用双引号来包裹指令  分号来区分多指令

bu断点

bu用于对某一个符号断点bu kernel32!GetVersiono和bp的区别:bu是和符号关联 如果符号的地址改变了
断点会保持和源符号的关联bp是和地址的关联 如果模块把地址的指令转移到其他地址
断点不会移动 依然是在原地址并且 bu会保存在 windbg的工作空间 下次启动自动断点

bm断点

bm断点是支持一次性创建多个bp或bu断点的指令例如 对 msvcr80d模块的 print开头的函数都进行断点bm msvcr80d!print*

实例

TraceMe.exe

 自动在命令行处进行加载

我们设置断点

bp kernel32!GetVersion

然后使用g来运行程序

2.硬件断点

硬件断点可以实现 监视I/O访问等功能 这些是软件断点无法实现的

ba

ba[ID] Access Size [Options] [Address [Passes]] ["CommandString"]
ID : 指定断点Access : 指定断点触发断点的访问方式e :在读取指令或执行指令的时候触发断点
r :在读取指令的时候触发断点
w :在写入数据的时候触发断点
i :在执行输入/输出访问(I/O)触发断点Size :
访问的长度  
在X86可以为 1,2,4 代表 字节 字 双字
在X64多了一个 8   8字节访问Address : 断点的地址 地址值按Size的值进行内存对齐Passes和CommandString
和软件断点用法一样

3.条件断点

软件断点和硬件断点都支持 条件断点

断点触发后 WinDbg会执行一些自定义的判断 并且执行命令

bp|bu|bm|ba _Adddress "j (Condition) 'OptionalCommands';'gc'"bp|bu|bm|ba _Adddress ".if (Condition) {OptionalCommands} .else {gc}"
例子bp kernel32!GetVersion ".if(@eax=0x12ffc4){}.else{gc}"当 GetVersion调用的时候 检测 eax
如果值为 0x12ffc4就中断
否则 gc指令继续执行但是当值为 0x12ffc4的时候 不一定能断下
因为在内核态   MASM会对 eax进行符号扩展0x12ffc4会变为 0xFFFFFFFFc012ffc4这个时候就可以使用 & 把eax的高位清零bp kernel32!GetVersion ".if(@eax& 0x0`ffffffff)=0xc012ffc4{}.else{gc}"
例子2
在不中断的情况下 打印 CreateFileA的函数调用bp kernel32!CreateFileA ".echo;.printf\"CreateFileA(%ma,%p,%p),ret=\",poi(esp+4),dwo(esp+8),dwo(esp+c);gu;.printf\"%N\",eaxl.echo;g"

4.管理断点

bl

bl 列出断点bc bd be 来删除 禁止 启动断点bd 1-3,4   禁止 1234断点bc * 删除所有断点

 

 4.栈窗口

栈是观测函数调用的重要调试手段

因为 call指令会把返回地址记录在栈中

我们就可以通过遍历栈帧来追溯函数调用过程

这里我遇到一个问题 就是怎么一直在 系统领空

这里是我忘记了windbg会自动在系统断点停止g @$exentry 就可以调到程序领空

这里我们开始看栈中的函数

k命令

 

栈帧的基地址是通过EBP来访问的 所以是childebp下面是返回地址 就是调用本函数的那条call指令的下一条地址 就是作为返回地址

kb命令

只用于显示放在栈上的前3个参数

 其他的k命令

kp 可以吧参数和参数值以函数的原型返回出来 包括参数类型 名字 取值kv命令可以在kb的基础上增加 栈指针省略信息和调用约定kd命令用于列出栈的数据

内存命令

1.查看内存

d命令

d [类型][地址范围]dd 4001000 L4L4可以指定显示前4个

 字节

d命令有很多衍生dw 双字word  dd 四个字节dq 八个字节df 四个字节单精度浮点数格式dD 八个字节双精度浮点数格式dp 指针大小格式 在32位中为4字节 64中为 8字节

ASCII

da 表示字符串db 表示字节和字符串dc dword和ASCIIdu 表示unicode字符串dW 表示双字节word 和 ASCIIds 用于显示 ANSI_STRINGdS 用于显示 UNICODE_STRING

二进制

dyb 表示二进制和字节dyd 表示二进制和dword

结构

dt [模块名!]类型名 用于显示数据类型和数据结构例如 dt ntdll!* 可以列出NTDLL模块的所有结构dt _PEB 可以显示 PEB的结构

地址

dds dps dqs 用于显示 地址和相关符号

拿 0040115Eh来举例子

 

 

 

 

 

 

 2.搜索指令

s指令

s - [type] range pattern
type :搜索的数据类型 b 比特
w word
d dword
a ascii
u unicode默认为 brange : 地址范围 可以用两个方式
1.起始地址+终止地址
2.起始地址+L(长度)如果超过 256MB 使用 L?lengthpattern:指定要搜索的内容 可以使用空格分隔要搜索的值

例如

s -u 400000 430000 "pediy"在 400000 到 430000中 搜索 unicode字符串 pediys -a 0x000000000 L?0x7fffffff mytest表示在 2GB的 user mode 内存空间中搜索 ASCII字符串mytest

3.修改内存

e命令

 写入字符串

e{a|u|za|zu} address "String"
za zu 是表示以 0 结尾的 ASCII 和 UNICODE 字符串a u 表示不以0 结尾例如eaz 298438 "pediy"
就是在 298438 这个地址 写入 pediy这个ASCII 并且以0结尾

写入数值

e{a|b|d|D|f|q|u|w} address [values]a asciib bited dwordD DOUBLEf floatq 八个字节u unicodew wordeb 298438 70 65 64 69 79会在 298438 写入 pediy 的数值形式

 

 

 4.观察内存属性

!address [Address]

5.脚本

windbg的脚本是一个语言

例如

我们想输出 helloword

.echo helloword

1.伪寄存器

windbg给了很多伪寄存器

在表达式中使用伪寄存器 必须要使用转义符 @

$exentry 当前进程的入口地址 运行 g @$exentry 可以到达程序入扣$ip 当前的指针寄存器$ra 当前函数的返回地址$retreg  当前函数返回地址存在这个寄存器中$csp 当前的栈指针 esp/rsp$tpid 当前进程的标识$tid 当前线程的标识$ea 最后一天被执行指令的有效地址$p 最后一条 d 命令打印的值$bpNumber 对应断点的地址$t0~$t19 自定义伪寄存器

 2.别名

类似 define宏

一个是固定别名

一个是自定义别名

固定别名

windbg提供了10个固定别名$u0~$u9在定义固定别名的时候需要使用 r 命令r $.u0="helloword"
.echo $u0

自定义别名

自定义别名的命令有3个as ad alas为内存中的字符串定义别名ad 删除别名     ad Name   ad *al 列出别名
as /选项 别名名称 别名实体选项的选择/ma ASCII/mu Unicode/msa ANSI_STRING/msu UNICODE_STRING/e 指定的环境变量/f 指定文件的内容

as /ma bookname 0040115e

 

3.表达式

windbg识别两个表达式  MASM / c++

默认使用MASM

.expr 可以显示表达式语法

使用@@c++()可以指定c++表达式@@masm()可以指定 masm表达式

MASM表达式

除了 +-*/这些算术运算符还支持转型运算符hi/low 可以得到32位数的高16 或 低16by/wo 可以得到指定地址的地位1字节/1字的值dwo/pwo 可以得到指定地址的DWORD/QWORDpoi 可以得到指定地址的指针长度

为了支持复杂的调试命令 Windbg还定义了特殊的运算符

$fnsucc(FnAddress,RetVal,Flag)将RetVal作为 FnAddress处的函数的返回值 如果返回值是一个成功码$fnsucc返回 true 否则false$iment(Address)
返回加载模块列表中的映像入口地址$scmp("string1","string2"):比较  -1 0 1
$sicmp("string1","string2"):比较  -1 0 1它们的差别在于比较时是否忽略大小写。$spat("string","pattern")
根据 string匹配 pattern 计算得到 true or false$vvalid(Address,Length)判断Address起Length的内存是否有效
有效返回1 否则 0 

C++表达式

支持C++的操作符 
包括 . ->C++会把数值作为十进制 所以 要加上 0x

注释

支持两个注释方式  * 和 $$

* 后所有都会被当做注释$$ 到 ; 结束为注释

6.例子

我们的要求是 打开CreateFileA函数 并且判断是不是 c:1212.txt

如果是就断点 如果不是就继续

命令行是

bp kernel32!CreateFileA "$<D:\\test.txt"

在D:\\test.txt的内容是

as /ma ${/v:fname} poi(esp+4)
.if ($sicmp("${fname}","c:\1212.txt")=0) {.echo ${fname}} .else{gc}

我们打入断点指令后

g运行程序

 

发现在原本读取 1212.txt的地方中断了

到此 windbg的基础就结束了

 


http://www.ppmy.cn/news/404197.html

相关文章

第十四届蓝桥杯大赛软件赛CB国赛-填空题(题目解析+完整代码)

前言 考完蓝桥杯了以后一直在咕咕咕, 所以题解直到现在才写出来&#xff08;&#xff09; 欢迎访问我的个人博客&#xff01; 第一题 题目描述 小蓝在黑板上连续写下从 1 到 2023 之间所有的整数&#xff0c;得到了一个数字序列&#xff1a; S 12345678910111213 . . . …

MEGA这个网盘你可以拥有,超级良心

MEGA 官网链接&#xff1a;https://mega.nz 这个网盘的特色 1.不会限速2.国内可用&#xff08;即使不会翻墙&#xff09;3.网盘云端加密&#xff0c;资源不会被封杀。4.官方还提供了Linux客户端 之后就会弹出mega的界面。界面看上去非常友好。接下来我们创建一个账号开始登陆…

访问mega网盘 的方法

目前默认状态下Mega是被和(%$)谐的。所以解决的思路是修改hosts文件。 1. hosts 文件的位置&#xff1a; Windows的位置为&#xff1a; C:\Windows\System32\drivers\etc\hostsLinux的位置为 /ect/hosts 2. 修改方法&#xff1a;首先打开hosts文件, windows下&#xff0c;将…

Samsung/三星Galaxy Mega 5.8(I9158/移动版) root教程_方法

Samsung/三星Galaxy Mega 5.8&#xff08;I9158/移动版&#xff09;的root教程在这里整理了一下&#xff0c;之前有机友说自己的手机想删除系统自带的一些无用软件&#xff0c;可是怎么也删除不了&#xff0c;所以需要先进行root才可以删除&#xff0c;不然的话是 删除不了的&a…

介绍一个好用的网盘MEGA

前言&#xff1a;偶然发现一个不错的网盘mega.nz&#xff0c;因为百度和360网盘老删我的小片片。。。 MEGA网盘有免费50G存储&#xff0c;客户端&#xff08;Windows,Linux和Chrome插件都有&#xff09;可以自动备份你所指定的文件夹&#xff0c;对咱们来说重要的就是自己写的程…

如何使用Mega cc

如何使用Mega cc Table of Contents 1 github地址&#xff1a;2 下载3 使用 3.1 安装3.2 输入文件3.3 输出文件3.4 运行MEGA-CC3.5 MEGA-Proto (分析模版)3.6 Demo1&#xff1a;实例13.7 Demo2: 实例23.8 自我实例 4 mao 文件简单解析5 在Linux下如何使用 1 github地址&#xf…

Mega的简单使用

Table of Contents 1 Mega画树的简单应用2 fas格式文件的准备3 用生成的.meg画树4 生出树的处理 4.1 修改内容&#xff0c;添加标注4.2 导出4.3 后面随着学习的进行继续修改&#xff0c;增加。 1 Mega画树的简单应用 2 fas格式文件的准备 首先我们要准备的就是fas的需要进行画…

mega-nerf安装流程

我之前记得mega-nerf要求的cuda版本是大于11.3&#xff0c;我手头只有一台服务器符合&#xff0c;就只在那上面安了。昨天一看似乎只要>11.1了,这样一来我手头的服务器就都可以用了。或者我有什么细节没记清&#xff0c;还有什么要求导致我之前只在一台服务器上安mega-nerf&…