首页
论坛
课程
招聘

[原创]NDIS6 X86通用hook代码

2011-11-29 10:07 17838

[原创]NDIS6 X86通用hook代码

2011-11-29 10:07
17838
原理参见http://www.opscn.com/index.php?action=vthread&forum=1&topic=15
/*
 * 安装ndis协议hook
 */
int init_ndis_hook(void* ProtoBlock)
{
        PNDIS60_PROTOCOL_BLOCK protocol = ProtoBlock;
        PNDIS_OPEN_BLOCK TcpOpenBlock = NULL;        
        PUNICODE_STRING BindDeviceName = NULL;
        PUNICODE_STRING RootDeviceName = NULL;
        unsigned char *buf = NULL;

        KdPrint(("init_ndis_hook:%x %x\n", protocol, protocol->NextProtocol));
        ndisFindMiniportOnGlobalList = search_ndisFindMiniportOnGlobalList();

        while (protocol = protocol->NextProtocol) {
                PUNICODE_STRING Name = NULL;
                Name = &protocol->Name;

                KdPrint(("Enume protocol %wZ\n", Name));
                if (0 == wcsncmp(Name->Buffer, (const wchar_t*)&L"TCPIP", Name->Length>>1)){
                        TcpOpenBlock = protocol->OpenQueue;
                        break;
                }
        }
        
        if (!TcpOpenBlock)
                return -1;

        KdPrint(("TcpOpenBlock %x %x\n", TcpOpenBlock, MmUserProbeAddress));
        ndis_hook_info.OpenBlock = TcpOpenBlock;

        /* 搜索BindDeviceName以及RootDeviceName */
        for (buf = (unsigned char*)TcpOpenBlock; buf < (unsigned char*)TcpOpenBlock + 0x500; buf+=4) {
                if (*(PULONG)(buf) > MmUserProbeAddress
                        && **(PULONG*)(buf) == 0x005e005c 
                        && **(PULONG*)(buf + 4) == 0x005e005c) {
                        BindDeviceName = *(PUNICODE_STRING*)buf;
                        RootDeviceName = *(PUNICODE_STRING*)(buf + 4);
                        ndis_hook_info.RootDeviceName = RootDeviceName;
                        KdPrint(("tcp root dev %wZ\n", RootDeviceName));
                        break;
                }
        }

        /* 搜索 ReceiveNetBufferLists 地址 */
        for (buf = (unsigned char*)TcpOpenBlock; buf < (unsigned char*)TcpOpenBlock + 0x500; buf+=4) {
                if (*(PULONG)(buf) > MmUserProbeAddress
                        && *(PULONG)(buf) == *(PULONG)(buf + 4)
                        && *(PULONG)(buf) == *(PULONG)(buf + 12)) {
                        /* buf->tcpip!FlReceiveNetBufferListChain */
                        ndis_hook_info.POpenBlockReceiveHandler = (PVOID*)(buf + 8);
                        ndis_hook_info.ReceiveNetBufferLists = *(PVOID*)(buf + 8);
                        KdPrint(("ReceiveNetBufferLists:%x\n", *(PVOID*)(buf + 8)));
                        break;
                }
        }

        /* 搜索底层 miniblock数据发送函数 */
        if (ndisFindMiniportOnGlobalList && RootDeviceName) {
                PNDIS_MINIPORT_BLOCK miniBlock = ndisFindMiniportOnGlobalList(RootDeviceName);
                if (miniBlock) {
                        /* 0x16c NextSendNetBufferListsHandler  偏移地址NDIS6中固定 */
                        PVOID NextSendNetBufferListsHandler = *(PVOID*)((char*)miniBlock + 0x16c);
                        ndis_hook_info.MiniBlock = miniBlock;
                        ndis_hook_info.PMiniBlockNextSndHandler = (PVOID*)((char*)miniBlock + 0x16c);
                        ndis_hook_info.NextSendNetBufferListsHandler = NextSendNetBufferListsHandler;
                        KdPrint(("miniBlock: %x %x\n", miniBlock, NextSendNetBufferListsHandler));
                        
                } else {
                        KdPrint(("ndisFindMiniportOnGlobalList failed!\n"));
                }
        }

        /* 进行NDIS60的HOOK处理 */
        if (ndis_hook_info.POpenBlockReceiveHandler) 
                *ndis_hook_info.POpenBlockReceiveHandler = HookReceiveNetBuferLists; 

        if (ndis_hook_info.PMiniBlockNextSndHandler)
                *ndis_hook_info.PMiniBlockNextSndHandler = HookSendNetBufferLists;

        return 0;
}



WDK7600编译,Windows7 旗舰版SP1测试通过

[推荐]看雪企服平台,提供项目众包、渗透测试、安全分析、定制项目开发、APP等级保护等安全服务!

上传的附件:
最新回复 (20)
MagicFuzzX 2011-11-29 10:22
2
0
膜拜下,这方面的资料好少啊,据说NDIS比文件过滤系统更复杂
邓韬 9 2011-11-29 10:28
3
0
不懂,楼主上面是什么开发环境“?
boywhp 12 2011-11-29 10:28
4
0
是比较少,所以我就发出来,希望给大家一些帮助,当然用正规的filter驱动应该比较正统
不过hook不需要inf什么乱七八糟的,而且指针替换,应该X64都是可以跑,稍微改改即可
boywhp 12 2011-11-29 10:32
5
0
http://bbs.pediy.com/showthread.php?t=141890
VIM编辑器,因为我linux用这个,所以比较顺手一点,VC6老是有一些问题,报什么srb文件错误,BSCMAKE错误,导致无法查看定义,火大ing!
crazybug 2 2011-11-29 12:01
6
0
发一个我写的~
http://www.vxjump.net/files/security_research/ndis_hook.txt
boywhp 12 2011-11-29 12:18
7
0
看了下,站点不错哦~,不过你那没有技术细节,而且感觉不怎么通用,实际上ndis6数据结构还是有很多变化的,能上代码吗?
crazybug 2 2011-11-29 12:59
8
0
恩 NDIS6的数据结构是跟5不一样
我讲了HOOK和MINIPORT HOOK两种~
里面讲到的几种都方法已经在实际产品里大范围使用了~
除了没有代码,我觉得熟悉NDIS的人应该可以看懂我说的东西
morning 1 2011-11-29 13:37
9
0
很多时候,hook 比写 filter省事
长风傲天 1 2011-12-1 18:03
10
0
NDIS里,用IMD,filter的是普通青年,用inline hook的是文艺青年,用指针替换的是.... 介个,你懂的
boywhp 12 2011-12-1 19:27
11
0
inlinehook 无法在X64上面跑,而且如果大家都用IMD,filter的话,指针替换反而很安全的说
object hook流不就是指针替换吗?哈哈,我不懂
长风傲天 1 2011-12-1 22:44
12
0
把PG爆菊了不就好啦~~
boywhp 12 2011-12-2 08:07
13
0
这个基本上才是第三类青年干的。。。噢,你懂的
yboy 2011-12-4 19:57
14
0
学习
PEBOSS 2011-12-4 23:13
15
0
opencn 自己的论坛,自己一个人玩啊
cherryEx 1 2011-12-4 23:20
16
0
我也这么认为
trkzrq 2011-12-5 01:29
17
0
路过,看看热闹。
peaceclub 6 2011-12-5 08:26
18
0
+ 8
+ 0x16c

看到这些常数,我就担心到跨操作系统版本的通用性,能用微软结构尽量用,不要直接偏移。
boywhp 12 2011-12-5 10:45
19
0
这个是X86下的,由于我完全没有64的签名,所以就没有处理64位的了,
+ 0x16c 在目前NDIS6各个版本下都是一样的,这个数据结构没有公开,当然可以自己声明一个,不过这个数据结构比较大,考虑到简洁一点,就直接硬编码了,但是理论上修改成X64的代码应该改动不多。0x16c要修改下,还有那个搜索函数要修改下
cherryEx 1 2011-12-5 11:35
20
0
有点代码可读性的问题,鄙人是这么做的
这些偏移专门放一个地方
#ifdef _WIN64
#define _OPEN_BLOCK_xxx_Offset 0x???
#else
#define _OPEN_BLOCK_xxx_Offset 0x16c
#endif
OnlyLoveMM 2011-12-6 09:46
21
0
这个真可以吗?
游客
登录 | 注册 方可回帖
返回