发新话题
打印

[转载]Code for Find Socket in Extreme Way

[转载]Code for Find Socket in Extreme Way

文章作者:coolq
信息来源:中联绿盟

顺便引用madsys的话
引用:
以前我是从各协议的hash表中找socket信息,不过有几个关键的符号没有输出,加载时要知道它们的值才行.
这个方法避免了那个麻烦,而且也比较底层.
Coolq的代码如下:
复制内容到剪贴板
代码:
/*******************************************
* Name  : sock_find.c (PoC)          *
* Author : CoolQ                  *
* Version: 0.0.1                  *
* Kernel : 2.6(general)/RedHat FC2      *
* Usage  : insmod sock_find.ko        *
* Warning: this is ONLY a PoC prog. it   *
*       tranverse the tcp_sock, you   *
*       can write your own prog handle *
*       about udp_sock, raw_sock, etc  *
* Also  : if you have ipv6 support, if  *
*       you are listening on port 23,  *
*       you should find the spicified  *
*       entry in tcp6_sock, not tcp_  *
*       sock!                  *
******************************************/


#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/tcp.h>
#include <asm/string.h>
#include <asm/types.h>

struct array_cache {
      unsigned int avail;
      unsigned int limit;
      unsigned int batchcount;
      unsigned int touched;
};

struct kmem_list3 {
      struct list_head      slabs_partial;  /* partial list first, better asm code*/
      struct list_head      slabs_full;
      struct list_head      slabs_free;
      unsigned long  free_objects;
      int         free_touched;
      unsigned long  next_reap;
      struct array_cache    *shared;
};

struct kmem_cache_s {
/* 1) per-cpu data, touched during every alloc/free */
      struct array_cache    *array[NR_CPUS];
      unsigned int        batchcount;
      unsigned int        limit;
/* 2) touched by every alloc & free from the backend */
      struct kmem_list3     lists;
      /* NUMA: kmem_3list_t  *nodelists[MAX_NUMNODES] */
      unsigned int        objsize;
      unsigned int        flags;  /* constant flags */
      unsigned int        num;   /* # of objs per slab */
      unsigned int        free_limit; /* upper limit of objects in the lists */
      spinlock_t          spinlock;

/* 3) cache_grow/shrink */
      /* order of pgs per slab (2^n) */
      unsigned int        gfporder;

      /* force GFP flags, e.g. GFP_DMA */
      unsigned int        gfpflags;

      size_t            colour;      /* cache colouring range */
      unsigned int        colour_off;    /* colour offset */
      unsigned int        colour_next;   /* cache colouring */
      kmem_cache_t        *slabp_cache;
      unsigned int        slab_size;
      unsigned int        dflags;      /* dynamic flags */

      /* constructor func */
      void (*ctor)(void *, kmem_cache_t *, unsigned long);

      /* de-constructor func */
      void (*dtor)(void *, kmem_cache_t *, unsigned long);

/* 4) cache creation/removal */
      const char          *name;
      struct list_head      next;

/* 5) statistics */
#if STATS
      unsigned long        num_active;
      unsigned long        num_allocations;
      unsigned long        high_mark;
      unsigned long        grown;
      unsigned long        reaped;
      unsigned long        errors;
      unsigned long        max_freeable;
      atomic_t           allochit;
      atomic_t           allocmiss;
      atomic_t           freehit;
      atomic_t           freemiss;
#endif
#if DEBUG
      int              dbghead;
      int              reallen;
#endif
};

/*****************************************
* the kmem_bufctl_t definition is quite *
* differente between FC2 kernel and the *
* general one, FC2 is uint, but the    *
* general kernel is ushort!         *
* **************************************/
typedef unsigned int kmem_bufctl_t;  /* !! for RC2 !! */

#define BUFCTL_END    (((kmem_bufctl_t)(~0U))-0)
#define BUFCTL_FREE    (((kmem_bufctl_t)(~0U))-1)
#define    SLAB_LIMIT    (((kmem_bufctl_t)(~0U))-2)

struct slab{
      struct list_head      list;
      unsigned long        colouroff;
      void              *s_mem;      /* including colour offset */
      unsigned int        inuse;       /* num of objs active in slab */
      kmem_bufctl_t        free;
};

static struct kmem_cache_s *dummy_cachep;
static int    my_array[128];

static inline kmem_bufctl_t *slab_bufctl(struct slab *slabp)
{
      return (kmem_bufctl_t *)(slabp+1);
}

static int mod_init(void)
{

      struct list_head      *p, *q;
      struct kmem_cache_s    *cachep;
      struct slab         *slabp;
    struct tcp_sock        *tcp_sk;
      int              i;
      
      
    /*************************************************************
     * the way we use here is to tranverse the tcp_sock slab,   *
     * get all the active slab objs. there are 3 lists, slabs_  *
     * free, slabs_full, slabs_partial. you can get active objs  *
     * from the full and partial lists.                  *
     * Tip: first we must get the symbol tcp_sock, unfortunately *
     *    the kernel doesn&#39;t EXPORT this symbol. we can use   *
     *    the System.map file located in /boot, but Redhat FC2 *
     *    doesn&#39;t have such entry ( whereas the general has )! *
     *    so, we can create a dummy cache discriptor , use    *
     *    double linked list (kmem_cache_s->next) to get all  *
     *    the cache symbols.                        *
     ************************************************************/
   
      dummy_cachep = kmem_cache_create("dummy_cachep", 128, ARCH_MIN_TASKALIGN,SLAB_PANIC, NULL, NULL);
      list_for_each(p, dummy_cachep->next.prev){
           cachep = list_entry(p, struct kmem_cache_s, next);
           if(cachep->name){
                spin_lock(&cachep->spinlock);
            if(!strcmp(cachep->name, "tcp_sock")){
                /*------------ slabs full ---------------*/
                list_for_each(q, &(cachep->lists.slabs_full)){
                    slabp = list_entry(q, struct slab, list);
                    for(i = 0; i < cachep->num; i++){
                        tcp_sk = slabp->s_mem + i * cachep->objsize;
                        printk("port:%d, ip:%x, state:%d\n",
                            tcp_sk->inet.sport,
                            tcp_sk->inet.saddr,
                            tcp_sk->sk.sk_state);
                    }
                }
                /*---------- slabs partial --------------*/
                list_for_each(q, &(cachep->lists.slabs_partial)){
                    slabp = list_entry(q, struct slab, list);
                    for(i = 0; i < cachep->num; i++)
                        my_array[i] = 0;
                    i = slabp->free;
                    
                    /* get all free objs and store the num in my_array */
                    do{
                        my_array[i] = 1;
                        i = slab_bufctl(slabp)[i];
                    }while(i != BUFCTL_END);
                    
                    for(i = 0; i < cachep->num; i++){
                        if(!my_array[i]){
                            tcp_sk = slabp->s_mem + i * cachep->objsize;
                            printk("port-s:%x, ip:%x, state:%d\n",
                                ntohs(tcp_sk->inet.sport),
                                tcp_sk->inet.saddr,
                                tcp_sk->sk.sk_state);
                        }
                    }
                }
            }
                spin_unlock(&cachep->spinlock);
           }
      }      
      return 0;
}


static void mod_exit(void)
{
      kmem_cache_destroy(dummy_cachep);
}

module_init(mod_init);
module_exit(mod_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("qufuping<at>ercist.iscas.ac.cn");
qq310926是我唯一用号,除此之外有其他号码号自称邪八冰血封情,则非本人。

TOP

发新话题