LINUX.ORG.RU

Ну почему нереально?

Если оно не экспортируется цивилизованно, то можно найти в ядре статичные данные и от них плясать по /dev/kmem. Как я понимаю, тебе нужна структура kbd_table, берешь ее адрес из System.map, читаешь из /dev/kmem по этому адресу, что нужно... ну и т.д.

Murr ★★
()
Ответ на: комментарий от Murr

Я в свое время писал программулину, которая показывает btrace в ядре,
 она примерно этим и занимается, причем "вслепую". Не знаю насколько 
тебе будет это полезно, но во всяком случае предложенный подход в ней 
будет хорошо виден.

/** \file btrace.c

    \brief Shows kernel backtrace of a thread
    
    Backtrace of a thread (does not matter a kernel thread
    or a user thread) of gived pid/tid is extracted by a heuristic
    search of task_struct structures in RAM.
    
    \warning Supported only with 2.6.x kernel series
*/

#define __KERNEL__
#include <linux/sched.h>

extern void* stderr, *stdout;
#define O_RDONLY 0
#define O_LARGEFILE 0100000
#define SMAP_BIN_CLUSTER 100

struct syms {
    char* name;
    unsigned long ptr;
};

typedef struct syms symbol_t;

int asc(symbol_t *f, symbol_t *s) {
    return f->ptr-s->ptr;
}

symbol_t* smap_bin = NULL;
int smap_bin_size;

char* symbol_name(unsigned long eip) {
    int i;
    
    for (i=0; i<smap_bin_size; i++)
	if (smap_bin[i].ptr > eip) break;
	
    return (i>0)?smap_bin[i-1].name:"NULL";
}

char *smap_text = NULL;
int smap_text_size;
unsigned long sfstart = 0, sfend = 0;

void parse_binary() {
    char *s = smap_text;
    char l;
    symbol_t *cur;
    
    printf ("[2] parsing System.map ..."); fflush(stdout);
    
    smap_bin_size = 0;
    
again:

    if ((smap_bin_size % SMAP_BIN_CLUSTER) == 0)
	smap_bin = (void*)realloc(smap_bin, (smap_bin_size+SMAP_BIN_CLUSTER)*sizeof(symbol_t));
    smap_bin_size++;
    cur = &smap_bin[smap_bin_size-1];
    cur->name = s+11;
    cur->ptr = strtoll(s, 0, 16);

    s = strchr(s, '\n')+1; *(s-1) = 0;

    if (!sfstart && !strcmp(cur->name, "scheduling_functions_start_here"))
	sfstart = cur->ptr;

    if (!sfend && !strcmp(cur->name, "scheduling_functions_end_here"))
	sfend = cur->ptr;

//    printf ("found: %s ptr=%lx sfstart=%lx sfend=%lx\n", cur->name, cur->ptr, sfstart, sfend);

    if (*s) goto again;

    printf ("(%d entries)\n", smap_bin_size);
    
    printf ("[3] running qsort ...\n");
    qsort(smap_bin, smap_bin_size, sizeof(symbol_t), asc);
}

void parse_smap() {
    int fd;
    char b[10240],c[1024];
    int n, s = 0;
    
    fd = open("/proc/sys/kernel/osrelease", O_RDONLY);
    if (fd == -1) {
	printf("[-] failed to detect osrelease\n");
	exit(0);
    }
    read(fd, c, sizeof(c));
    close(fd);
    *(strchr(c, '\n')) = 0;
    
    sprintf (b, "/lib/modules/%s/build/System.map", c);
    fd = open(b, O_RDONLY);
    
    if (fd == -1) {
	printf ("[-] '%s' not found, falling back to /boot/System.map\n", c);
	fd = open("/boot/System.map", O_RDONLY);
    }
    
    if (fd == -1) {
	printf ("[-] failed to open System.map\n");
	exit(0);
    }
    
    printf ("[1] reading System.map ..."); fflush(stdout);
    
    do {
	n = read(fd, b, 10240); s += n;
	smap_text = (void*)realloc(smap_text, s);
	memcpy(smap_text+s-n, b, n);    }
    while (n != 0);
    
    close(fd);
    smap_text_size = s;
    
    printf ("(%d bytes)\n", smap_text_size);
    
    parse_binary();
}

int btstart;

void print_symbol(unsigned long eip, unsigned long ebp) {
    if (btstart) {
	printf ("\n");
	btstart = 0;
    }
    printf ("<%lx(%s)>\n", eip, symbol_name(eip), ebp);
}

extern pread64(int fd, void*buf, unsigned long size, unsigned long long offset);

int print_ktrace(int fd, unsigned long eip, unsigned long esp, unsigned long ebp) {
    unsigned long nebp, neip;

    if (eip<TASK_SIZE) return 0;

    if (btstart)
	if (eip>sfend || eip<sfstart) return 0;

    print_symbol(eip, ebp);
    
    if (pread64(fd, &nebp, 4, ebp)<0) return 1;
    if (pread64(fd, &neip, 4, ebp+4)<0) return 1;
    
    print_ktrace(fd, neip, 0, nebp);
    return 1;
}

int main (int argc, char *argv[]) {
    int fd, i;
    unsigned long base;
    char buf[PAGE_SIZE];
    struct task_struct *t;
    struct thread_struct *ti;
    unsigned long ebp;
    
    if (argc<2) {
	fprintf (stderr, "usage: ktrace pid\n\n");
	return -1;
    }

    parse_smap();
    
    fd = open("/dev/kmem", O_RDONLY|O_LARGEFILE);
    if (fd<0) {
	perror("failed to open /dev/kmem");
	return -1;
    }

    printf ("[4] searching ...\n"); fflush(stdout);

    for (base=TASK_SIZE; base!=0; base+=32) {
	if (pread64(fd, buf, sizeof(struct task_struct), base)<0) continue;
	
	t = &buf;
	
	if (t->pid != atoi(argv[1]))
	    continue;
	    
	if ((t->leader != 0) && (t->leader != 1))
	    continue;

	if ((unsigned long)t->thread_info<TASK_SIZE)
	    continue;
	    
	ti = &t->thread;
	
	if (pread64(fd, &ebp, 4, (unsigned long)ti->esp)<0)
	    continue;
	    
	btstart = 1;
	if (print_ktrace(fd, ti->eip, ti->esp, ebp)) printf ("\n");
	if (!btstart) break;
    }
    close (fd);
}

Murr ★★
()

Сделал. Все оказалось намного проще -- добавил в драйвере vt
еще один ioctl, по аналогии с KDGKBLED. Две строчки с vt_ioctl.c и одна в kd.h.
Имею теперь в консоли индикатор расклаки клавиатуры в стиле MS-DOS :)

anonymous
()
Ответ на: комментарий от Murr

Понятно что вариант с ioctl не проходит если ядро нельзя трогать. В этом случае, пожалуй, действительно придется через kmem.

anonymous
()
Ответ на: комментарий от anonymous

anonymous:

>Сделал. Все оказалось намного проще -- добавил в драйвере vt
еще один ioctl, по аналогии с KDGKBLED.

Ничего себе проще. Влез в ядро, поменял, пересобрал. :)

P.S. С другой стороны, это, конечно, честнее. :)

Murr ★★
()
Ответ на: комментарий от anonymous

anonymous:

>Понятно что вариант с ioctl не проходит если ядро нельзя трогать. В этом случае, пожалуй, действительно придется через kmem.

Просто, если ты разбираешься в коде ядра и есть возможность пересобрать, то непонятно в чем был изначальный вопрос. :)

Murr ★★
()
Ответ на: комментарий от Murr

ну... в коде ядра я только начинаю разбираться.
соответственно не знаю, существует ли законный способ
эту переменную вытащить. читая исходники этого так просто
не поймешь

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.