科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Linux下的网络HOOK实现以及使用方法

Linux下的网络HOOK实现以及使用方法

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

最近疯狂的研究Linux的种种功能,也颇有心得,这里讲述一下Linux下的Net的Hook,使用net的Hook可以实现很多很多非常底层的功能,比如过滤报文,做防火墙,做代理等等。

作者:skid 来源:赛迪网技术社区 2007年10月14日

关键字: 方法 HOOK Linux 操作系统

  • 评论
  • 分享微博
  • 分享邮件
 

最近疯狂的研究Linux的种种功能,也颇有心得,这里讲述一下Linux下的Net的Hook,使用net的Hook可以实现很多很多非常底层的功能,比如过滤报文,做防火墙,做代理等等。

Now,Let's Go!

使用的是Linux 2.6.19.1的内核代码。

首先是 在./Source/net/netfilter/core.c文件中的函数 nf_register_hook:

static DEFINE_SPINLOCK(nf_hook_lock);

int nf_register_hook(struct nf_hook_ops *reg)

{

struct list_head *i;

spin_lock_bh(&nf_hook_lock);

list_for_each(i, &nf_hooks[reg->pf][reg->hooknum]) {

if (reg->priority < ((struct nf_hook_ops *)i)->priority)

break;

}

list_add_rcu(®->list, i->prev);

spin_unlock_bh(&nf_hook_lock);

synchronize_net();

return 0;

}

EXPORT_SYMBOL(nf_register_hook);

void nf_unregister_hook(struct nf_hook_ops *reg)

{

spin_lock_bh(&nf_hook_lock);

list_del_rcu(®->list);

spin_unlock_bh(&nf_hook_lock);

synchronize_net();

}

EXPORT_SYMBOL(nf_unregister_hook);

int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n)

{

unsigned int i;

int err = 0;

for (i = 0; i < n; i++) {

err = nf_register_hook(®[i]);

if (err)

goto err;

}

return err;

err:

if (i > 0)

nf_unregister_hooks(reg, i);

return err;

}

EXPORT_SYMBOL(nf_register_hooks);

void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)

{

unsigned int i;

for (i = 0; i < n; i++)

nf_unregister_hook(®[i]);

}

EXPORT_SYMBOL(nf_unregister_hooks);

上面分别是四个函数:

nf_register_hook,nf_unregister_hook,nf_register_hooks,nf_unregister_hooks.

功能是注册Hooks函数

输入的参数是struct nf_hook_ops *reg。

下面让我们看一个验证ARP报文的Hook代码,以表示我们如何使用Hook函数实现这种功能。

unsigned int arphook_snd(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in, const struct net_device *out,int (*okfn)(struct sk_buff*))

{

struct arphdr *arp;

struct net_device *dev;

unsigned char * arp_ptr;

unsigned char *sha, *tha;

u32 sip,tip;

unsigned short arpop;

unsigned int status=NF_DROP;

dev=(*skb)->dev;

arp = (*skb)->nh.arph;

arp_ptr= (unsigned char *)(arp+1);

sha = arp_ptr;

arp_ptr += dev->addr_len;

memcpy(&sip, arp_ptr, 4);

arp_ptr += 4;

tha = arp_ptr;

arp_ptr += dev->addr_len;

memcpy(&tip, arp_ptr, 4);

arpop=ntohs(arp->ar_op);

if(!check_ip(&tip,WABLOCK)) /*check block list*/

{

if(arpop==1) /*sending ARP request*/

{

if(!check_ip(&tip,WAARP)) /*if not in list add it*/

add_ip(&tip,WAARP);

}

status=NF_ACCEPT;

}

return(status);

}

下面是初始化一些参数的函数

static int arpstar_init(void)

{

arphkrcv.hook=arphook_rcv; /*arp receive hook*/

arphkrcv.hooknum=NF_ARP_IN;

arphkrcv.pf=NF_ARP;

arphkrcv.priority=NF_IP_PRI_FIRST;

nf_register_hook(&arphkrcv);

arphksnd.hook=arphook_snd; /*arp send hook*/

arphksnd.hooknum=NF_ARP_OUT;

arphksnd.pf=NF_ARP;

arphksnd.priority=NF_IP_PRI_FIRST;

nf_register_hook(&arphksnd);

iphkrcv.hook=iphook_rcv; /*ip rcv hook*/

iphkrcv.hooknum=NF_IP_LOCAL_IN;

iphkrcv.pf=PF_INET;

iphkrcv.priority=NF_IP_PRI_FIRST;

nf_register_hook(&iphkrcv);

tmac=strtomac(trustedmac);

trustip=strtou32(trustedip);

run_timer(0);

return(0);

}

下面是函数结束时候的清理工作

static void arpstar_exit(void)

{

nf_unregister_hook(&arphkrcv); /*clean up time*/

nf_unregister_hook(&arphksnd);

nf_unregister_hook(&iphkrcv);

del_timer(&watimer);

free_list();

kfree(tmac);

}

我们知道Windows下面也有Hook的功能,但是要Hook到Net的底层,一般是使用NDIS来实现,但是Linux就提供了如此强大的功能,让我们不得不佩服Linux的伟大。几天的研究让我越来越对Linux的推崇!而且我想Linux在嵌入式方面的应用会更加广泛!

这几天也在看一些嵌入式的资料,想想,这个世界真的可以因为Linux的改变而改变,相对来说Windows的代码保密性会失去很多嵌入式方面的开发者的!

  相关文章

  利用Hook技术实现键盘监控

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章