Windows 内核之双机调试与windbg命令大全

在今后会有相当的实验环节,对于windows内核实验,调试环境是必不可少的,本章讲解双机调试的环境搭建与常见的WINDBG指令。

准备材料:

VMware workstation : [https://www.vmware.com/go/downloadworkstation-cn]

windows 7 x64 ISO (请使用种子下载工具进行下载):

[ed2k://|file|cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso|3420557312|B58548681854236C7939003B583A8078|/]

windbg: [https://docs.microsoft.com/zh-cn/windows-hardware/drivers/debugger/debugger-download-tools]

安装过程:

首先安装Vmware workstation pro,运行后无脑下一步就OK。

安装完成后界面如

 

接下来创建win7虚拟机,下一步到此画面,选择win7 ISO镜像

扫描二维码关注公众号,回复: 12443226 查看本文章

 

虚拟机较大,注意存储位置是否足够放下大概会占用20~40GB的空间

 

如需修改则作调整

 

在自定义硬件中需要注意内存大小适中,核心暂时定为1个,因为在练习时多核CPU有时会影响练习结果,并且多核上有些数据结构是一个核心一个,所以操作起来相对麻烦。

 

接下来重要的一点:添加一个串口

 

配置为此,注意另一端是应用程序,而非虚拟机

 

安装中

 

安装完成后开始配置windows 调试启动模式

 

接下来配置调式模式设置,一定要注意右下角串口端口,当前端口是2那么设置的调式端口就是2。

 

 

为方便今后调试,将调试启动项设置为默认启动项

 

至此windows启动项设置结束~

设置windbg调试器的快捷方式参数

“<windbg的路径>\windbg.exe" -b -k com:pipe,port=//./pipe/com_WIN7_64,baud=115200,resets=0 -y SRV*<符号存储的路径>*http://msdl.microsoft.com/download/symbols

测试调试环境

重启win7虚拟机,在vmware 加载完毕后 启动windbg快捷方式,windbg将会与windows 建立调试连接

 

windows将等待windbg的下一条指示,此时windows 将会被调试器挂起。

输入 g 指令后,windows将继续运行。

至此win7 与 windbg 的双机调试环境搭建完毕。

接下来了解下windbg的基本操作,以及注意事项

WINDBG 内核调试常用指令

扩展指令
	!process 0 0	枚举进程	(全局句柄表 CID 下标)
	!thread			枚举当前进程线程 (EPROCESS ActiveThread 链表)
	!handle 		枚举当前进程句柄对象信息(EPROCESS 本地句柄表)
	!frame			调用帧
	!devobj			设备对象(句柄表)
	!fileobj		文件对象(句柄表)
	!drvobj			驱动对象(句柄表)
	!findhandle		对象所有引用信息(来自EPROCESS 句柄表)
	!idt 			检索idt表(来自KPCR)
	!sw				切换当前处理器模式 32 <=> 64	
	!sym			显示当前符号设置
	!drivers		显示所有驱动模块		(NtQuerySystemInformation SystemModuleInformation)
	!pte			查找虚拟地址对应得PTE	(EPROCESS->CR3)
	!dml_proc		遍历所有进程及指定进程的线程,多数DML格式
	!vad			进程内存段信息 (EPROCESS->VADRoot)
	!vtop [PageDir,0] VA 显示虚拟地址的PML4E, PDPE, PDE, PE, PhyAddr		(解析地址为页表下标)
	!pcr			查看所有CPU结构信息(KPCR),通过FS(x86) GS(x64)获取
	!poolused		查看当前系统分配pool与pool tag信息(用来查找未释放堆非常合适)

内部指令
	.process 		切换进程		(AttachProcess)
	.thread			切换线程		
	k*				调用栈
	u 				反编译 ,L行数
		f			反编译整个函数,/i当前反编译指令数,/c搜索函数内的call
		b			向前反编译
		r 			BIOS Real mode 代码
	up 				对物理地址反编译
	r				寄存器操作
	p				步过
	t 				步入
	gu				步出
	gc				运行
	bp				断点
	bp address "j()'';''" 条件断点
	s				查找
		s -sa		查找ascii 字符串
		s -su		查找unicode 字符串
		s -v		查找c++的类
		s BaseAddr LSize '字' 0xff "字符串"
		s -[w]		只查询可写数据区域
		s -b,w,d,q	byte,word,dword,qword 四种数据范围
	bp address ".if(){}.elif(){}.else{}"
	#				查询反编译窗口中的任何字符,正则符号注意转义
	~
		s			切换当前处理器
		.			当前线程
		#			当前出现异常,调试时间的线程
		*			所有线程
		number		指定线程
		
	|s				设置当前进程(仅在用户模式下使用)
	||s				设置当前系统(仅在多调试模式下使用)
	??				计算传入的C风格表达式
	.expr			全局表达式的语言格式
		/q			查看支持的语言
		/s 			设置当前解析语言
	?				计算表达式
	bl				断点列表
	bc				删除断点
	bd				禁用
	be				启用
	d 				查看
		b/w/d/q		byte word dword qword
		a 			ascii
		u			unicode
		g  			读取段选择子信息
		l
s
		t 			套入指定结构体,
			-r		递归查看深度(默认为1)
		
	.cxr			切换到异常发生地(参数为异常产生的 _CONTEXT 结构地址)
	xs*				为指定调试事件或异常指定操作方法,或中断
	  sxe			为指定异常做处理
	  xsd,xsn,xsi	不为指定异常处理
		iml			初始化模块加载	(仅内核使用)
		ibp			初始化断点
		out			指定应用程序输出
		ld			模块加载
		ud			模块卸载
		cpr			创建进程
		epr			进程退出
		ct			创建线程
		et			线程退出
		ser			系统错误
	rdmsr			读取MSR寄存器
	wrmsr 			写入MSR寄存器
	wt				追踪所有调用 usermode:(all), kernelmode:(only x86)
	.load wow64exts 加载wow64拓展功能
	.reload			重新加载模块
		/d 			重新加载调试器模块列表中的所有模块
		/f *   		强制调试器立即加载指定文件的符号
		/s 			重新加载系统的模块映射列表中所有模块,如果应用层使用模块名称,则必须使用/s
		/user 		仅仅重新加载应用层符号	
		/u 			卸载所有模块
		/w 			不展开通配符
		
	.browse			单指令窗口,不干扰主窗口,可支持退回
	.cache forcedecodeuse	清空缓存,强制写入内存
	.dump			创建Dump文件
	.chain			查询windbg当前加载的库与插件
	.extmatch cmd	查询windbg所有模块的拓展指令
		/e	mod		枚举或查询指定模块的指令
	.attach			挂接进程
	.detach			取消挂接
	.beep			响一下 
	.time			显示会话开始时间与目标主机时间
	.asm 			设置反调试属性
	.url			网页跳转指令
	.dml_flow		寻找附近的代码,跳转来源与将跳转地址

///   脚本语句	 ///

@"string\\"	=> string\\		字符串不做转义
.							某些语境下代表r/eip
.printf [option] format [,arg1,...]
	/od		debug
	/oD		debug prompt
	/oe		error
	/on		normal
	/op		prompt
	/oP		prompt resigter
	/os		symbols
	/ov		verbose
	/ow		warnning
	
	format:
	%p		pointer
	%N		32bit or 64bit pointer
	%I		(any 64 bit)ULONG64
	%ma		ascii string
	%mu		unicode string
	%msa	ANSI_STRING string
	%msu	UNICODE_STRING string
	%y		symbols information
	%ly		symbols and source line information
	
as				别名
	/ma		str		转换成ansi字符串表示
	/mu		str		转换成unicode字符串表示
	/msa	str		转换成ANSI_STRING结构
	/msu	str		转换成UNICODE_STRING结构
	/x 		1+2		数值,在.echo 中如果要.echo输出,需要放在.block下
	/f		E:\...	读出文件内容
	/c 		code	代码,需要整段代码,引用时将标识符转换为代码
al				列出所有别名
ad *			删除(所有)别名
${as}			展开as宏
${/d:as}		是否定义as宏
${/n:as}		as宏名称本身
${/f:as}		展开as宏,不存在则为空

j 				类似.if,语法:j bool 表达式1;表达式2
z				类似于.do{}(),语法:表达式1;z(bool)

.sleep			暂停n毫秒
.block 			块展开as宏
.if				如果 ,语法 .if( bool ){}
.elsif			否则如果,语法 .if(bool){}.elsif(bool){}
.else			否则 ,语法 if(bool){}.else{}
.break			跳出循环
.continue		结束本次循环
.do				do-while,语法 do{}(bool)
.for			语法:for(init;bool;add){}
.foreach		对指令执行结果的每一个单词传入标识符,语法:foreach(标识符 {指令}){.echo "标识符"}
	/s			对字符串的每一个单词传入标识符,语法:foreach(标识符 "字符串"){.echo "标识符"}
	/f			对文件内容每一个单词传入标识符,语法:foreach(标识符 文件路径){.echo "标识符"}

.catch			异常捕获 .catch{代码}		
.leave			退出到.catch外

.openlog file	打开日志
.logclose		关闭日志
.logfile		查看当前日志文件

poi				取地址值,语法 poi(address)
	预定义函数宏 		

masm 内置宏
$iment			通过模块获得入口点,语法:$iment(Address))
$scmp			字符串对比,C++: strcmp
$sicmp			字符串对比,C++: stricmp
$spat			正则,语法 $spat("str", "pattern")
$vvalid			探测内存有效性,语法:$vvalid(Address,lenght)

C 内置宏
#CONTAINING_RECORD(Addr, Type, Field)			LIST_ENTRY结构寻址
#FIELD_OFFSET(Struct, Field)				取得字段偏移
#RTL_CONTAINING_FIELD(Struct, Size, Field)	字段是否在大小范围内
#RTL_FIELD_SIZE(Struct, Field)				字段大小

	windbg预定义宏 		
	$ntnsym			nt
	$ntwsym			ntdll
	$ntsym			当前环境来决定是ntdll还是nt
	$exentry		进程入口点
	$proc			EPROCESS
	$thread			ETHREAD
	$peb			PEB
	$teb			TEB
	$tpid			进程ID
	$tid			线程ID
	$bp id			断点对应地址DML	Debuggee markup language

///		DML (Debuggee Markup Language)	///
相关指令
	.dml_start filename			解析文件内容为DML,并且打印
	.dml_flow address1 address2	从address1开始,有多少个地址访问到从address2,和将要跳转到哪。
	
相关标签
	<link cmd="command"> Descriptor </link>		//链接
	<b></b>										//粗体
	<i></i>										//斜体
	<u></u>										//下划线
	<col fg bg></col>									//设置子图颜色
	<exec cmd=""></exec>						//指令执行
	<altlink name cmd/>									//右键菜单下

 

猜你喜欢

转载自blog.csdn.net/xuandao_ahfengren/article/details/111934666