Windbg断点调试

[作者简介] 
    常用网名: 灯火阑珊
    出生日期: 1995.XX.XX
    生理特征: 男
    个人网站: geons.cn
    E-mail:     [email protected]
    QQ交流:  1090700965
    编程级别: 菜鸟
    职业生涯: 中科院计算所
    历史岗位: 应用软件开发/系统工程
    开发语言: C/C++、C#
    开发工具: Visual Studio 

    研究领域: Windows应用软件开发/Windows驱动开发/系统逆向工程/病毒木马感染分析

[文章主题]

Windbg是Windows驱动调试的重要软件,也是必须学习的软件,前面的博客介绍了一些双机调试的环境配置,只要按照我所说的步骤一步步下来就可以完成环境搭建。

本文主要介绍如何调试sys格式的驱动文件,网上很多资料都说得含糊不清,甚至有博主就是简单翻译外文资料,根本没有实际应用,这篇文章将解决这些问题。

[环境配置]

VM虚拟机(已安装XP系统)

DriverMonitor(安装在XP系统中)

WIN7系统(已安装VM、已安装Windbg)

[测试:在运行之前首先测试下VM与Windbg是否通讯正常,否则是无法完成调试的]

[调试开始]

1、首先在VS中完成代码的书写,并且编译出SYS,生成PDB符号文件。这都是必须的文件,缺一不可。

测试代码如下,可以直接拷贝到VS中编译,当然,编译需要WDK环境配置,之前的文章我已经介绍了。

<span style="font-size:12px;">/*
	模块功能:测试代码
*/
#include "NTDDK.h"

VOID DDK_Unload(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS CreateMyDevice(PDRIVER_OBJECT pDriverObject);

// 驱动入口函数
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
{

	KdPrint(("驱动加载+++\n"));

	// 注册卸载函数
	pDriverObject->DriverUnload = DDK_Unload;

	// 创建设备
	CreateMyDevice(pDriverObject);

	// 调试输出设备创建成功
	KdPrint(("新设备已经创建成功!\n设备名:2016227_DeviceName\n符号链接是[symLinkDDK]\n"));
	return STATUS_SUCCESS;
}

// 卸载驱动
VOID DDK_Unload(IN PDRIVER_OBJECT pDriverObject)
{
	PDEVICE_OBJECT pDevUnload_Object;
	UNICODE_STRING symLinkName;

	KdPrint(("进入卸载函数\n"));

	pDevUnload_Object = pDriverObject->DeviceObject;

	// 删除设备
	IoDeleteDevice(pDevUnload_Object);

	//获取符号连接
	RtlInitUnicodeString(&symLinkName,L"\\??\\symLinkDDK");

	// 删除符号连接
	IoDeleteSymbolicLink(&symLinkName);


	KdPrint(("Kd输出模式:结束卸载函数\n"));

	DbgPrint("DbgPrint输出模式:驱动已经卸载,执行成功!\n");
}


// 创建设备
NTSTATUS CreateMyDevice(PDRIVER_OBJECT pDriverObject)
{
	NTSTATUS  status;
	// 设备对象
	PDEVICE_OBJECT pDevObj;

	// 创建设备名称
	UNICODE_STRING devName;
	UNICODE_STRING symLinkName;

	// 初始化设备名
	RtlInitUnicodeString(&devName,L"\\Device\\2016227_DeviceName");

	// 创建设备
	status = IoCreateDevice(
		pDriverObject,
		0,
		&devName,
		FILE_DEVICE_UNKNOWN,
		0,
		TRUE,
		&pDevObj);

	// 检测设备创建情况
	if(!NT_SUCCESS(status))
	{
		if(status == STATUS_INSUFFICIENT_RESOURCES)
		{
			KdPrint(("资源不足\n"));
		}
		else if(status == STATUS_OBJECT_NAME_EXISTS)
		{
			KdPrint(("设备名称已经存在\n"));
		}
		else if(status == STATUS_OBJECT_NAME_COLLISION)
		{
			KdPrint(("设备冲突\n"));
		}
		return status;

	}
	else
	{
		KdPrint(("设备成功创建\n"));
	}
	// 置于缓冲区运行
	pDevObj->Flags |= DO_BUFFERED_IO;


	// 创建符号连接
	RtlInitUnicodeString(&symLinkName, L"\\??\\symLinkDDK");
	status = IoCreateSymbolicLink(&symLinkName, &devName);

	if(!NT_SUCCESS(status))
	{

		// 删除错误的设备创建
		IoDeleteDevice(pDevObj);
		return status;

	}

	return STATUS_SUCCESS;
}</span>
注意:为了生成可用的PDB符号文件,还需要对DDK做一些处理才可以生成出PDB文件。

Windbg断点调试_第1张图片

Windbg断点调试_第2张图片

最后生成的文件有SYS、PDB

2、将源文件和PDB文件复制到一个新建的文件夹中

3、打开Windbg,将PDB、CPP引用进去,以让windbg有正确的符号连接并且有正确的源码响应。

4、使用windbg打开源文件,F9设置断点。

5、运行windbg,在VM中加载驱动,使用DriverMonitor进行加载。

首先在windbg运行“g”,让Debugging运行起来,然后再进入虚拟机进行加载卸载操作,如果有断点,Windbg会自动命中断点并且显示出来!

[至此]

Windbg调试基本步骤就完成了,当然,最好是根据前面的DDK模板设置来对模板进行修改,达到不用每次都修改生成正确的PDB文件,希望这篇文章对你有帮助,当然如果有其他问题可以直接联系作者进行讨论!


你可能感兴趣的:(windbg,Visual,Studio,驱动开发,系统文件调试)