From 115b05b1e701175a9584e6ca578766c00d21c18c Mon Sep 17 00:00:00 2001 From: chn <897331845@qq.com> Date: Wed, 25 Dec 2019 21:55:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E8=83=BD=E7=94=A8=E4=BA=86?= =?UTF-8?q?=EF=BC=8C=E4=BD=86=E8=BF=98=E6=98=AF=E6=9C=89=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common.h | 2 +- src/rkp-ua.c | 25 +++++++------ src/rkpManager.h | 63 +++++++++++++++++++++++---------- src/rkpSettings.h | 4 +-- src/rkpStream.h | 90 +++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 142 insertions(+), 42 deletions(-) diff --git a/src/common.h b/src/common.h index 0a00cd4..e9abfc7 100644 --- a/src/common.h +++ b/src/common.h @@ -22,7 +22,7 @@ static unsigned char str_ua_rkp[16]; void* rkpMalloc(unsigned size) { - void* p = kmalloc(size, GFP_KERNEL); + void* p = kmalloc(size, GFP_NOWAIT); if(p == 0) printk("rkp-ua: malloc failed.\n"); return p; diff --git a/src/rkp-ua.c b/src/rkp-ua.c index e0a0544..ba4045c 100644 --- a/src/rkp-ua.c +++ b/src/rkp-ua.c @@ -2,7 +2,6 @@ static struct nf_hook_ops nfho; static struct rkpManager* rkpm; -static DEFINE_MUTEX(lock); unsigned int hook_funcion(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { @@ -15,7 +14,9 @@ unsigned int hook_funcion(void *priv, struct sk_buff *skb, const struct nf_hook_ return NF_ACCEPT; if(!rkpSettings_capture(skb)) return NF_ACCEPT; - return NF_ACCEPT; +#ifdef RKP_DEBUG + printk("hook_function captured a packet.\n"); +#endif rtn = rkpManager_execute(rkpm, skb); n_skb_captured++; @@ -24,15 +25,17 @@ unsigned int hook_funcion(void *priv, struct sk_buff *skb, const struct nf_hook_ printk("rkp-ua: Captured %d packages.\n", n_skb_captured); n_skb_captured_lastPrint *= 2; } +#ifdef RKP_DEBUG + printk("hook_function end.\n"); +#endif return rtn; } static int __init hook_init(void) { int ret; - mutex_init(&lock); - rkpm = rkpManager_new(&lock); + rkpm = rkpManager_new(); memcpy(str_ua_rkp, "RKP/", 4); memcpy(str_ua_rkp + 4, VERSION, 2); @@ -44,18 +47,21 @@ static int __init hook_init(void) nfho.priority = NF_IP_PRI_RAW; #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) - // ret = nf_register_net_hook(&init_net, &nfho); + ret = nf_register_net_hook(&init_net, &nfho); #else - // ret = nf_register_hook(&nfho); + ret = nf_register_hook(&nfho); #endif printk("rkp-ua: Started, version %s\n", VERSION); printk("rkp-ua: nf_register_hook returnd %d.\n", ret); printk("rkp-ua: autocapture=%c, mark_capture=0x%x, mark_first=0x%x.\n", 'n' + autocapture * ('y' - 'n'), mark_capture, mark_first); - printk("rkp-ua: str_preserve:\n"); + printk("rkp-ua: str_preserve: %d\n", n_str_preserve); for(ret = 0; ret < n_str_preserve; ret++) printk("\t%s\n", str_preserve[ret]); +#ifdef RKP_DEBUG + printk("str_ua_rkp: %s\n", str_ua_rkp); +#endif return 0; } @@ -64,12 +70,11 @@ static void __exit hook_exit(void) { if(rkpm != 0) rkpManager_delete(rkpm); - mutex_destroy(&lock); #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) - // nf_unregister_net_hook(&init_net, &nfho); + nf_unregister_net_hook(&init_net, &nfho); #else - // nf_unregister_hook(&nfho); + nf_unregister_hook(&nfho); #endif printk("rkp-ua: Stopped.\n"); } diff --git a/src/rkpManager.h b/src/rkpManager.h index e6a4d44..608127c 100644 --- a/src/rkpManager.h +++ b/src/rkpManager.h @@ -5,32 +5,33 @@ struct rkpManager { struct rkpStream* data[256]; // 按照首包的两端口之和的低 8 位放置 time_t last_active; - struct mutex* lock; // 线程锁,这个需要外部静态地生成后,把指针传进来 + spinlock_t lock; // 线程锁 }; -struct rkpManager* rkpManager_new(struct mutex*); +struct rkpManager* rkpManager_new(void); void rkpManager_delete(struct rkpManager*); -u_int8_t rkpManager_execute(struct rkpManager*, struct sk_buff*); // 处理一个数据包。返回值为 rkpStream_execute 的返回值。 +int rkpManager_execute(struct rkpManager*, struct sk_buff*); // 处理一个数据包。返回值为 rkpStream_execute 的返回值。 +int __rkpManager_execute(struct rkpManager*, struct sk_buff*); void rkpManager_refresh(struct rkpManager*); // 清理过时的流 -void __rkpManager_lock(struct rkpManager*); -void __rkpManager_unlock(struct rkpManager*); +void __rkpManager_lock(struct rkpManager*, unsigned long*); +void __rkpManager_unlock(struct rkpManager*, unsigned long); -struct rkpManager* rkpManager_new(struct mutex* lock) +struct rkpManager* rkpManager_new(void) { - struct rkpManager* rkpm = rkpMalloc(sizeof(struct rkpStream)); + struct rkpManager* rkpm = rkpMalloc(sizeof(struct rkpManager)); if(rkpm == 0) return 0; memset(rkpm -> data, 0, sizeof(struct rkpStream*) * 256); - rkpm -> lock = lock; - mutex_init(rkpm -> lock); + spin_lock_init(&rkpm -> lock); return rkpm; } void rkpManager_delete(struct rkpManager* rkpm) { - // __rkpManager_lock(rkpm); unsigned i; + unsigned long flag; + __rkpManager_lock(rkpm, &flag); for(i = 0; i < 256; i++) { struct rkpStream* rkps = rkpm -> data[i]; @@ -41,19 +42,27 @@ void rkpManager_delete(struct rkpManager* rkpm) rkps = rkps2; } } - // __rkpManager_unlock(rkpm); + __rkpManager_unlock(rkpm, flag); rkpFree(rkpm); } -u_int8_t rkpManager_execute(struct rkpManager* rkpm, struct sk_buff* skb) +int rkpManager_execute(struct rkpManager* rkpm, struct sk_buff* skb) +{ + unsigned long flag; + int rtn; + __rkpManager_lock(rkpm, &flag); + rtn = __rkpManager_execute(rkpm, skb); + __rkpManager_unlock(rkpm, flag); + return rtn; +} +int __rkpManager_execute(struct rkpManager* rkpm, struct sk_buff* skb) { #ifdef RKP_DEBUG printk("rkp-ua: rkpManager_execute start.\n"); printk("\tsyn %d ack %d\n", tcp_hdr(skb) -> syn, tcp_hdr(skb) -> ack); - printk("\tsport %d dport %d\n", tcp_hdr(skb) -> source, tcp_hdr(skb) -> dest); + printk("\tsport %d dport %d\n", ntohs(tcp_hdr(skb) -> source), ntohs(tcp_hdr(skb) -> dest)); printk("\tid %d\n", (ntohs(tcp_hdr(skb) -> source) + ntohs(tcp_hdr(skb) -> dest)) & 0xFF); #endif - __rkpManager_lock(rkpm); rkpm -> last_active = now(); if(rkpSettings_first(skb)) // 新增加一个流或覆盖已经有的流 @@ -87,12 +96,20 @@ u_int8_t rkpManager_execute(struct rkpManager* rkpm, struct sk_buff* skb) // 插入新的流 if(rkpm -> data[id] == 0) + { rkpm -> data[id] = rkps_new; +#ifdef RKP_DEBUG + printk("rkpManager_execute: add a new stream %d to an empty list.\n", id); +#endif + } else { rkpm -> data[id] -> prev = rkps_new; rkps_new -> next = rkpm -> data[id]; rkpm -> data[id] = rkps_new; +#ifdef RKP_DEBUG + printk("rkpManager_execute: add a new stream %d to an unempty list.\n", id); +#endif } return NF_ACCEPT; @@ -103,11 +120,16 @@ u_int8_t rkpManager_execute(struct rkpManager* rkpm, struct sk_buff* skb) u_int8_t id = (ntohs(tcp_hdr(skb) -> source) + ntohs(tcp_hdr(skb) -> dest)) & 0xFF; struct rkpStream* rkps = rkpm -> data[id]; #ifdef RKP_DEBUG - printk("rkpStream_belong %d\n", (int)rkpStream_belongTo(rkps, skb)); + printk("rkpStream_execute id %d\n", id); #endif while(rkps != 0) if(rkpStream_belongTo(rkps, skb)) + { +#ifdef RKP_DEBUG + printk("rkp-ua::rkpStream::rkpStream_execute: Target stream %u found.\n", id); +#endif return rkpStream_execute(rkps, skb); + } else rkps = rkps -> next; printk("rkp-ua::rkpStream::rkpStream_execute: Target stream %u not found.\n", id); @@ -119,6 +141,8 @@ void rkpManager_refresh(struct rkpManager* rkpm) { time_t n = now(); unsigned i; + unsigned long flag; + __rkpManager_lock(rkpm, &flag); for(i = 0; i < 256; i++) { struct rkpStream* rkps = rkpm -> data[i]; @@ -138,13 +162,14 @@ void rkpManager_refresh(struct rkpManager* rkpm) else rkps = rkps -> next; } + __rkpManager_unlock(rkpm, flag); } -void __rkpManager_lock(struct rkpManager* rkpm) +void __rkpManager_lock(struct rkpManager* rkpm, unsigned long* flagp) { - mutex_lock(rkpm -> lock); + spin_lock_irqsave(&rkpm -> lock, *flagp); } -void __rkpManager_unlock(struct rkpManager* rkpm) +void __rkpManager_unlock(struct rkpManager* rkpm, unsigned long flag) { - mutex_unlock(rkpm -> lock); + spin_unlock_irqrestore(&rkpm -> lock, flag); } \ No newline at end of file diff --git a/src/rkpSettings.h b/src/rkpSettings.h index 1a05c5b..8521d3c 100644 --- a/src/rkpSettings.h +++ b/src/rkpSettings.h @@ -24,8 +24,8 @@ bool rkpSettings_capture(const struct sk_buff* skb) { #ifdef RKP_DEBUG - if(ntohl(ip_hdr(skb) -> daddr) != (216 << 24) + (24 << 16) + (178 << 8) + 192 && ntohl(ip_hdr(skb) -> saddr) != (216 << 24) + (24 << 16) + (178 << 8) + 192) - return false; + // if(ntohl(ip_hdr(skb) -> daddr) != (216 << 24) + (24 << 16) + (178 << 8) + 192 && ntohl(ip_hdr(skb) -> saddr) != (216 << 24) + (24 << 16) + (178 << 8) + 192) + // return false; #endif if(!autocapture) diff --git a/src/rkpStream.h b/src/rkpStream.h index 2f1015a..ac3ea63 100644 --- a/src/rkpStream.h +++ b/src/rkpStream.h @@ -28,6 +28,7 @@ int32_t __rkpStream_seq_scanEnd(struct rkpStream*); // 返回 buff_scan void __rkpStream_insert_auto(struct rkpStream*, struct rkpPacket**, struct rkpPacket*); // 在指定链表中插入一个节点 void __rkpStream_insert_end(struct rkpStream*, struct rkpPacket**, struct rkpPacket*); +struct rkpPacket* __rkpStream_pop_end(struct rkpStream*, struct rkpPacket**); bool __rkpStream_scan(struct rkpStream*, struct rkpPacket*); // 在包的应用层搜索 ua 头的结尾 void __rkpStream_modify(struct rkpStream*); // 在已经收集到完整的 HTTP 头后,调用去按规则修改 buff_scan 中的包 @@ -153,7 +154,11 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) // 接下来是恰好是 buff_scan 的后继数据包的情况,先分状态讨论,再一起考虑 buff_disordered 中的包 #ifdef RKP_DEBUG - printk("\tdesired packet judged.\n"); + printk("\tdesired packet judged.\n"); + unsigned char* temp = rkpMalloc((rkpPacket_appLen(p) + 1) * sizeof(unsigned char)); + memcpy(temp, rkpPacket_appBegin(p), rkpPacket_appLen(p)); + temp[rkpPacket_appLen(p)] = 0; + printk("\tpacket content: %s\n", temp); #endif unsigned rtn; // 如果是在 sniffing 的情况下,那一定先丢到 buff_scan 里,然后扫描一下看结果,重新设定状态 @@ -162,8 +167,8 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) #ifdef RKP_DEBUG printk("\t\tsniffing.\n"); #endif - // 丢到 buff_scan 里 - __rkpStream_insert_end(rkps, &(rkps -> buff_scan), p); + // 丢到 buff_scan 里,记得一会儿如果要 accept,还要拿出来,以及更新序列号 + __rkpStream_insert_end(rkps, &rkps -> buff_scan, p); if(__rkpStream_scan(rkps, p)) // 扫描到了 { #ifdef RKP_DEBUG @@ -177,10 +182,9 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) { struct rkpPacket* p2 = p; p = p -> next; - rkps -> seq_offset = rkpPacket_seq(p2) + rkpPacket_appLen(p2); // 别忘了更新偏移 + // rkps -> seq_offset = rkpPacket_seq(p2) + rkpPacket_appLen(p2); 不需要更新偏移,因为最后一个包等会儿 accept 的时候会更新 rkpPacket_send(p2); } - rkps -> buff_scan = 0; // 设定状态为等待 rkps -> status = __rkpStream_waiting; // accept @@ -189,7 +193,7 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) // 没有扫描到,那么 stolen else { - if(rkpPacket_psh(p)) // 如果同时没有 psh,就偷走 + if(!rkpPacket_psh(p)) // 如果同时没有 psh,就偷走 rtn = NF_STOLEN; #ifdef RKP_DEBUG printk("\t\t\thttp head end not matched.\n"); @@ -221,12 +225,18 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) // 只要有 psh,肯定接受 rtn = NF_ACCEPT; } + if(rtn == NF_ACCEPT) // 记得再 pop 出来! + { + __rkpStream_pop_end(rkps, &rkps -> buff_scan); + rkps -> seq_offset = rkpPacket_seq(p) + rkpPacket_appLen(p); + } } else // waiting 的状态,检查 psh、设置序列号偏移、然后放行就可以了 { #ifdef RKP_DEBUG printk("\t\tsniffing.\n"); #endif + rkps -> seq_offset = rkpPacket_seq(p) + rkpPacket_appLen(p); if(rkpPacket_psh(p)) rkps -> status = __rkpStream_sniffing; rtn = NF_ACCEPT; @@ -372,6 +382,31 @@ void __rkpStream_insert_end(struct rkpStream* rkps, struct rkpPacket** buff, str printk("rkp-ua: __rkpStream_insert_end end.\n"); #endif } +struct rkpPacket* __rkpStream_pop_end(struct rkpStream* rkps, struct rkpPacket** buff) +{ +#ifdef RKP_DEBUG + printk("rkp-ua: __rkpStream_pop_end start.\n"); +#endif + if(*buff == 0) + { + printk("__rkpStream_pop_end: pop from an empty list.\n"); + return 0; + } + else + { + struct rkpPacket* rkpp; + for(rkpp = *buff; rkpp -> next != 0; rkpp = rkpp -> next); + if(rkpp -> prev == 0) + *buff = 0; + else + rkpp -> prev = rkpp -> prev -> next = 0; + return rkpp; + } +#ifdef RKP_DEBUG + printk("rkp-ua: __rkpStream_insert_end end.\n"); +#endif +} + bool __rkpStream_scan(struct rkpStream* rkps, struct rkpPacket* rkpp) { @@ -381,6 +416,9 @@ bool __rkpStream_scan(struct rkpStream* rkps, struct rkpPacket* rkpp) unsigned char* p; for(p = rkpPacket_appBegin(rkpp); p != rkpPacket_appEnd(rkpp); p++) { +#ifdef RKP_DEBUG + printk("rkp-ua: __rkpStream_scan matching %c.\n", *p); +#endif if(*p == str_head_end[rkps -> scan_matched]) rkps -> scan_matched++; else @@ -411,14 +449,25 @@ void __rkpStream_modify(struct rkpStream* rkps) struct rkpPacket *ua_begin_rkpp, *ua_end_rkpp, *rkpp = rkps -> buff_scan; // 匹配 "User-Agent: " 的阶段 +#ifdef RKP_DEBUG + printk("matching User-Agent: \n"); +#endif for(;rkpp != 0 && ua_begin_matched != strlen(str_ua_begin); rkpp = rkpp -> next) { unsigned char* p; for(p = rkpPacket_appBegin(rkpp); p != rkpPacket_appEnd(rkpp); p++) { +#ifdef RKP_DEBUG + printk("rkp-ua: __rkpStream_modify: matching %c.\n", *p); +#endif // 检查匹配 http 头结尾的情况 if(*p == str_head_end[head_end_matched]) + { head_end_matched++; +#ifdef RKP_DEBUG + printk("rkp-ua: __rkpStream_modify: head end matched.\n"); +#endif + } else head_end_matched = 0; if(head_end_matched == strlen(str_head_end)) @@ -432,10 +481,15 @@ void __rkpStream_modify(struct rkpStream* rkps) // 检查匹配 "User-Agent: " 的情况 if(*p == str_ua_begin[ua_begin_matched]) + { ua_begin_matched++; +#ifdef RKP_DEBUG + printk("rkp-ua: __rkpStream_modify: ua begin matched.\n"); +#endif + } else ua_begin_matched = 0; - if(ua_end_matched == strlen(str_ua_begin)) + if(ua_begin_matched == strlen(str_ua_begin)) { #ifdef RKP_DEBUG printk("rkp-ua: __rkpStream_modify: ua found.\n"); @@ -457,16 +511,32 @@ void __rkpStream_modify(struct rkpStream* rkps) } // 匹配 "\r\n" 和需要忽略的关键字的阶段 +#ifdef RKP_DEBUG + printk("matching \\r\\n\n"); +#endif + if(n_str_preserve > 0) keyword_matched = rkpMalloc(n_str_preserve * sizeof(unsigned)); memset(keyword_matched, 0, n_str_preserve * sizeof(unsigned)); - for(;rkpp != 0 && ua_end_matched != strlen(str_ua_end); rkpp = rkpp -> next) + for(rkpp = ua_begin_rkpp; rkpp != 0 && ua_end_matched != strlen(str_ua_end); rkpp = rkpp -> next) { unsigned char* p; - for(p = ua_begin_p; p != rkpPacket_appEnd(rkpp); p++) + if(rkpp == ua_begin_rkpp) + p = ua_begin_p; + else + p = rkpPacket_appBegin(rkpp); + for(; p != rkpPacket_appEnd(rkpp); p++) { // 检查匹配 "\r\n" 的情况 - if(*p == str_head_end[ua_end_matched]) +#ifdef RKP_DEBUG + printk("rkp-ua: __rkpStream_modify: matching %c.\n", *p); +#endif + if(*p == str_ua_end[ua_end_matched]) + { ua_end_matched++; +#ifdef RKP_DEBUG + printk("rkp-ua: __rkpStream_modify: ua end matched.\n"); +#endif + } else ua_end_matched = 0; if(ua_end_matched == strlen(str_ua_end))