首页
社区
课程
招聘
[旧帖] win7 64位驱动开发 tips 0.00雪花
发表于: 2015-8-7 12:28 2430

[旧帖] win7 64位驱动开发 tips 0.00雪花

2015-8-7 12:28
2430
WIN64驱动编程基础教程 链接在这:
http://bbs.pediy.com/showthread.php?t=187348
下面说说我在这方面的看法:

开发环境:  win7 64位 旗舰版;VS 2010 ; C++; WinDDK 7600; VisualDDK-1.5.7 配置的(nt 4 style)开发模版; SSDT, SSSDT hook;

Tips:
1:  64位不再有内嵌汇编, 内嵌汇编应该提出来, 单独成一个 xxx.asm文件, 再在这个文件上点 属性 | 常规 | 项类型(设为: 自定义生成工具);  自定义生成工具 | 命令行(ml64 /c %(fileName).asm), 输出(%(fileName).obj);  
    asm文件中的函数引用需要声明:  extern"C"   函数原型;

2:   64位不再有各种调用约定, 甚至声明为__declspec(naked)都报警, 其参数传递如下:
   
     	TestCall tc;
	tc.__stdcall_fn(10, 15, 16, 20, 21, 22);
000000013F931187  mov         dword ptr [rsp+30h],16h  
000000013F93118F  mov         dword ptr [rsp+28h],15h  
000000013F931197  mov         dword ptr [rsp+20h],14h  
000000013F93119F  mov         r9d,10h  
000000013F9311A5  mov         r8d,0Fh  
000000013F9311AB  mov         edx,0Ah                  //参数++
000000013F9311B0  lea         rcx,[tc]                       //  this 或参数1
000000013F9311B5  call        TestCall::__stdcall_fn (13F93100Ah)  
    


3: 从SSDT(/SSSDT)表中的值到实际函数位置为:
    (取高四字节)(ssdt基地址) + (取低4字节)((ssdt基地址)的低4字节 +(表中的值 >> 4));
       其中, 如果 表中的值 最高位为1, 那么 (表中的值 >> 4后还要将 最高4位置1;呵呵, 也就是 (表中的值) 实际是个有符号32位数
       用宏定义如下:
       #define SSDTValueToCall(_Table_, _Value_) (((_Table_) & 0xffffffff00000000) + (((_Table_) + (((_Value_) & (1<<31) )? (((_Value_) >> 4) | (0xf0000000)) : ((_Value_) >> 4))) & 0xffffffff))
       另外, 上面链接声明, ((_Value_) >> 4)后还要 与0xfffffff0, 那应该是visa的, 本系统不用。

4:    从实际函数位置到表中的值, 呵呵, 取差距, 向左移4, 加上原值的右4位即可

5:  因为附加的驱动不与 SSDT(/SSSDT)基地址 在一个4G内, 所以需要中间跳转, 此时, 不要用更改原有函数内容的方法, 而应该查找函数之间内存空间, 在其中插入跳转指令。
      
UCHAR spareBlock_Write[0xc] = {0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0};//mov rax,FFFFFFFFFFFFFFFF; jmp rax
//	查找函数之间的空闲空间
//    pStart 位于 table基地址 后
//     size == 0xc
//    当然, pStart - - pEnd 需要 使用mdl map进来, 并且, 如果是sssdt, 还需要 KeAttach到gui进程
PUCHAR FindSpareBlockBetweenFuctions(PUCHAR pStart, PUCHAR pEnd, ULONG size)
{
	if (!pStart || !pEnd || !size)
		return NULL;
	for (; pStart < pEnd - size; pStart++)
	{
		//	必须位于ret后面	
		if (*pStart == 0xC2)		//	c2 == ret 8888; c3 == ret;
			pStart +=3;
		else if (*pStart != 0xC3)	
			pStart +=1;
		else
			continue;
		ULONG nNop = 0;
		for (; nNop < size; nNop++)
		{
			if (*pStart != 0x90)	//	0x90 == nop
				break;
			pStart ++;
		}
		if (nNop == size)
			return pStart - size;
	}
	return NULL;
}


[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 111
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持,但写好后,能加载吗?win7系统自身禁止非注册驱动的加载。
2016-1-4 11:13
0
雪    币: 25
活跃值: (506)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
顶!mark下以后方面查找
2016-1-4 12:54
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
mark一下
2016-1-22 09:49
0
游客
登录 | 注册 方可回帖
返回
//