基本能用了,但还是有问题

This commit is contained in:
chn
2019-12-25 21:55:11 +08:00
parent 0f7472efaa
commit 115b05b1e7
5 changed files with 142 additions and 42 deletions

View File

@@ -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;

View File

@@ -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");
}

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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 中的包
@@ -154,6 +155,10 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb)
// 接下来是恰好是 buff_scan 的后继数据包的情况,先分状态讨论,再一起考虑 buff_disordered 中的包
#ifdef RKP_DEBUG
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))