mirror of
https://github.com/CHN-beta/xmurp-ua.git
synced 2026-01-11 17:29:28 +08:00
基本能用了,但还是有问题
This commit is contained in:
@@ -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;
|
||||
|
||||
25
src/rkp-ua.c
25
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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user