首页
社区
课程
招聘
[原创][逆向]Dell风扇控制驱动源码(已修正并重新上传)
2006-9-14 23:00 9125

[原创][逆向]Dell风扇控制驱动源码(已修正并重新上传)

2006-9-14 23:00
9125
[修正说明]
已经重新上传
-----------------------------------------------
1.C源代码中有一处遗漏, 会导致驱动向应用程序返回结果错误, 在DellFanDriver.c中

2.逆向分析的IDB文件中, INIT:00010818处有个笔误, 这一行中的IRP_DEVICE_CONTROL应该是IRP_MJ_DEVICE_CONTROL, 中间丢了"MJ"

3.DispatchIoControl函数中一处数据结构分析有误, 已修正

刚开学天天赋闲, 无聊中翻起老帖, 无意中看到Isaiah兄写的控制Dell风扇的程序, 可惜的是没有驱动源码, 于是心血来潮, 搞了三个小时, 终于把Dell风扇控制驱动的源码搞定了, 附件里有全部C源码和IDA分析生成的IDB文件(需要IDA4.9或者看雪论坛的5.0版本方可正常打开), 另外工程中附带了Isaiah兄写的程序(没有修改)供大家参考, 在此对Isaiah兄表示感谢

Isaiah兄的帖子
http://bbs.pediy.com/showthread.php?s=&threadid=27805&highlight=dell

限于本人水平, 加之驱动没有测试过, 程序中错误和疏漏一定不少, 明天我会到学校机房找一台dell机器测试一下, 如果有错误还请各位多多指教.

由于懒得写驱动程序中那一堆令人厌烦的例行公事式的代码, 程序的框架是用DriverWorks生成的(没有用Driver C++ FrameWork). 所以源代码中基本上是框架代码, 控制风扇的核心在于DispatchIoControl函数中(C源码中对应的函数名是DellFanDriverDeviceIoControlDispatch, DriverWorks生成的函数名),大家也只需要看这个函数就可以了, 如果想看全部代码请看打开IDB文件看, 那儿的代码要简洁明了很多.

另外还有一点要说明的,驱动源码中更改了设备名称和符号链接名, 因为我觉得原来的太丑了

原设备名为\Device\#!#!
原符号链接名为\DosDevices\#!#!

源代码中设备名为\Device\DellFanDriver
符号链接名为\??\DellFanDriver

打开驱动的时候, CreateFile指定的文件名也要做相应修改

代码中, 直接操作风扇的是这两句

out        0B2h, al;Interrupt Controller #2, 8259A
out        84h, al;

------------------------------------------------------------------------------------------------

以下就是驱动控制风扇的代码(只列出最核心的函数, 其他不是很重要的可以去看附件中的代码和IDB文件)
两个"//*************"之间的是核心
///////////////////////////////////////////////////////////////////////////////////////////////////
//  DellFanDriverDeviceIoControlDispatch
//      Dispatch routine for IRP_MJ_DEVICE_CONTROL requests.
//
//  Arguments:
//      IN  DeviceObject
//              pointer to the device object for our device
//
//      IN  Irp
//              the device i/o control IRP
//
//  Return Value:
//      NT status code.
//
NTSTATUS DellFanDriverDeviceIoControlDispatch(
	IN  PDEVICE_OBJECT  DeviceObject,
	IN  PIRP            Irp
	)
{
	PIO_STACK_LOCATION              irpStack;
	NTSTATUS                        status;
	PDELLFANDRIVER_DEVICE_EXTENSION    deviceExtension;
	PVOID                           inputBuffer;
	ULONG                           inputLength;
	PVOID                           outputBuffer;
	ULONG                           outputLength;
	ULONG							minBufferLen;
	PVOID							sysBuffer;
	ULONG							var1, var2, var3;
	USHORT							result;


	DellFanDriverDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);

	deviceExtension = (PDELLFANDRIVER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

	// Get our IRP stack location
	irpStack = IoGetCurrentIrpStackLocation(Irp);

	// Get the buffer lengths
	inputLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
	outputLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;

	switch (irpStack->Parameters.DeviceIoControl.IoControlCode) 
	{
	case CTL_CODE(0x8001, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS):

		//minimal buffer size requirement
		minBufferLen = 6;

		//check buffer length
		if (inputLength < minBufferLen || outputLength < minBufferLen)
		{
			DellFanDriverDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__":I/O Bufferlength %X | %X is too small\n",inputLength, outputLength);

			status = STATUS_BUFFER_TOO_SMALL;
		}
		else
		{
			//bytes transfered
			Irp->IoStatus.Information  = minBufferLen;

			//************************************************************************************
			//get buffer
			sysBuffer = Irp->AssociatedIrp.SystemBuffer;

			var1 = ((ULONG)((PUCHAR)sysBuffer)[0] << 8) | 0xA3;

			var2 = (ULONG)((PUCHAR)sysBuffer)[1] << 8;

			var3 = (ULONG)((PUCHAR)sysBuffer)[2];

			__asm 
			{
				pushad;

				mov	ebx, var2;
				mov ecx, var3;
				mov eax, var1;

				out	0B2h, al;Interrupt Controller #2, 8259A
					out	84h, al;

				mov result, ax;

				popad;
			}

			((PUSHORT)sysBuffer)[4/sizeof(USHORT)] = result;
			status = STATUS_SUCCESS;
			//************************************************************************************
			DellFanDriverDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"Fan control result:%4X", (ULONG)result);
		}	

		Irp->IoStatus.Status = status;
		IoCompleteRequest (Irp, IO_NO_INCREMENT);
		break;
	default:
		status = STATUS_INVALID_DEVICE_REQUEST;
		Irp->IoStatus.Status = status;
		IoCompleteRequest (Irp, IO_NO_INCREMENT);
		break;
	}

	DellFanDriverDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

	return status;
}

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

上传的附件:
收藏
点赞7
打赏
分享
最新回复 (5)
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
Isaiah 10 2006-9-15 09:54
2
0
强~
收藏,学习~
雪    币: 32403
活跃值: (18860)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 8 2006-9-15 10:03
3
0
如果thebutterfly 能来点逆向技巧就好了
雪    币: 291
活跃值: (208)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
thebutterfly 5 2006-9-15 11:15
4
0
另外还有一些问题没有搞明白
控制风扇时传给驱动的参数有效的有6个字节, 其中0~2这3个字节是传给驱动的参数, 4~5字节是驱动返回给应用程序的结果
问题就是那3个参数到底有什么意义, 这个从驱动中看不出来

还有就是6字节参数的第3字节意义不明

*****
关于逆向技巧的问题, 既然老大发话, 那就不得不说一些了
这个驱动确实非常简单, 只要有一点对驱动的了解就能够看懂了(那个逆向分析的IDB文件), 对于这种简单的东西, 可以按照驱动程序的结构, 从DriverEntry开始一步步来, 从DriverEntry里可以得到驱动的Dispatch函数, AddDevice函数等等, 再对每个函数进行分析即可. 这些函数都有确定的参数和返回值, 分析起来会省不少力气.
相对有一点难度的就是驱动的数据结构, 为了理解驱动的功能这是不得不分析的. 驱动的数据结构比较复杂, 有些是没有公开的, 碰到Union结构的时候, 常常不知道引用的到底是哪个域, 这就靠你对程序功能的理解程度了, 有时也要靠经验

PS: 好像帖中的链接就是自己
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
周子歆 2006-9-15 22:03
5
0
最初由 Isaiah 发布
强~
收藏,学习~
雪    币: 178
活跃值: (134)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
pmma 1 2006-9-16 11:39
6
0
不错,学习学习,老大看来是至少是驱动中牛得级别,嘿嘿
游客
登录 | 注册 方可回帖
返回