Добрый день, мне надо прочесть из ядра данные выводимые через /proc/kallsyms , но я хз как грамотно это сделать. Т.К. это не файл, то я не могу получить inode->i_size (точнее могу, но данное значение там равно нулю). Собственно , основная проблема, только в том, чтоб узнать точный размер выводимых данных /proc/kallsyms .. Как это сделать?
7mm Как правильно определить конец файла? и произвести это чтение? в ядре для чтения заданного файла я использую vfs_read , с заданной позиции f_pos (с самого начала файла). Как мне определить конец файла? (f_pos указывающую на конец)
А, так вы из ядра читаете... А зачем вам читать /proc/kallsyms, если вся генерируемая в него инфа доступна в ядре? Посмотрите, в kernel/kallsyms.c реализация. Кстати, есть замечательная функа kallsyms_on_each_symbol. Выполнит Ваше действие над каждым из символов
7mm Мне нужно в /proc/kallsyms найти адреса ptype_all и ptype_base они не экспортируемые . Собираюсь эт сделать так: Читаю вывод из /proc/kallsyms в буфер, далее ищу имена переменных, далее определяю текстовые адреса этих переменных, и получаю адрес в hex . Всё просто, а ступор в человеческом чтении kallsyms Насчёт kallsyms_on_each_symbol.... не понял как работает /* Call a function on each kallsyms symbol in the core kernel */ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, unsigned long), void *data); =(
featurelles А что непонятно? Из написанного ясно, что kallwyms_on_each_symbol, вызывает функцию-аргумент fn для каждого символа, причём передаёт в каждый вызов fn указатель на пользовательские данные data, а так же указатель на имя символа (char*), указатель на модуль в котором содержится символ (struct module*), и адрес символа (unsigned long). Или поведение функции не соответствует тому, что я от неё ожидаю?
Видимо всёже мне придётся делать, именно так как первоначально хотел. (считать вывод kallsyms и далее разбор) Вопрос остаётся открытым. После компиляции модуля, с включением в его код kallsyms_on_each_symbol Building modules, stage 2. MODPOST 1 modules FATAL: modpost: GPL-incompatible module My_Module_Init.ko uses GPL-only symbol 'kallsyms_on_each_symbol' (модуль будет не под GPL лицензией)
Я вот что-то не пойму, а как вы будете искать ptype_all и ptyp_base через kallsyms, если они неэкспортируемы (объявлены как static)?.. По-моему, тут нужно искать те символы (функции), где используются эти переменные, а затем использовать дизассемблер (хотя бы длин) и парсить их? Кстати, есть символ dev_base_lock, который объявлен сразу же после ptype_all и ptyp_base (dev/core.c) и экспортируется через EXPORT_SYMBOL. Попробуйте использовать это обстоятельство, может быть они и после сборки будут лежать рядом?..
7mm Считаю весь вывод kallsyms , парсингом найду ptype_all и ptype_base , определю их текстовые адреса , потом переведу эти адреса в hex и буду по этим адресам обращаться) Я так ко всем не экспортируемым функциям и переменным обращался. (правда использовал раньше не kallsyms а system.map )
Может я чего не понимаю, но в /proc/kallsyms их быть не должно, так как не экспортируются. Сейчас под рукой линукса нет, может вы дадите вывод: cat /proc/kallsyms | grep ptype_{all,base} ?
@localhost ~]$ cat /proc/kallsyms | grep 'ptype_all' c0611060 d ptype_all @localhost ~]$ cat /proc/kallsyms | grep 'ptype_base' c0610fe0 d ptype_base @localhost ~]$ cat /proc/kallsyms | grep ptype_{all,base} grep: ptype_base: Нет такого файла или каталога
Я всё ещё не знаю, как нормально прочесть вывод /proc/kallsyms Если выделить здоровенный буфер, чтоб туда весь вывод запихнуть из /proc/kallsyms , и применить vfs_read , то в буфер считается только начало Вот что будет прочитано Код (Text): un 5 21:35:12 localhost kernel: c0100000 T startup_32 Jun 5 21:35:12 localhost kernel: c0100000 T _text Jun 5 21:35:12 localhost kernel: c0100079 t bad_subarch Jun 5 21:35:12 localhost kernel: c0100079 W xen_entry Jun 5 21:35:12 localhost kernel: c010007b t default_entry Jun 5 21:35:12 localhost kernel: c0101000 T wakeup_pmode_return Jun 5 21:35:12 localhost kernel: c010104c t bogus_magic Jun 5 21:35:12 localhost kernel: c010104e t save_registers Jun 5 21:35:12 localhost kernel: c010109d t restore_registers Jun 5 21:35:12 localhost kernel: c01010c0 T do_suspend_lowlevel Jun 5 21:35:12 localhost kernel: c01010d6 t ret_point Jun 5 21:35:12 localhost kernel: c01010e8 T _stext Jun 5 21:35:12 localhost kernel: c0101100 T do_one_initcall Jun 5 21:35:12 localhost kernel: c01012d0 t run_init_process Jun 5 21:35:12 localhost kernel: c01012f0 t init_post Jun 5 21:35:12 localhost kernel: c01013f0 T name_to_dev_t Jun 5 21:35:12 localhost kernel: c0101620 t create_dev Jun 5 21:35:12 localhost kernel: c0101680 t T.710 Jun 5 21:35:12 localhost kernel: c01016f0 t T.695 Jun 5 21:35:12 localhost kernel: c0101730 t create_dev Jun 5 21:35:12 localhost kernel: c0101790 t trace_kmalloc Jun 5 21:35:12 localhost kernel: c0101800 T lgstart_cli Jun 5 21:35:12 localhost kernel: c010180a T lgend_cli Jun 5 21:35:12 localhost kernel: c010180a T lgstart_pushf Jun 5 21:35:12 localhost kernel: c010180f T lgend_pushf Jun 5 21:35:12 localhost kernel: c0101810 T lg_irq_enable Jun 5 21:35:12 localhost kernel: c0101827 t send_interrupts Jun 5 21:35:12 localhost kernel: c0101834 T lg_restore_fl Jun 5 21:35:12 localhost kernel: c0101844 T lguest_iret Jun 5 21:35:12 localhost kernel: c0101849 T lguest_noirq_start Jun 5 21:35:12 localhost kernel: c0101851 T lguest_noirq_end Jun 5 21:35:12 localhost kernel: c0101860 t __raw_callee_save_save_fl Jun 5 21:35:12 localhost kernel: c0101868 t __raw_callee_save_irq_disable Jun 5 21:35:12 localhost kernel: c0101870 t save_fl Jun 5 21:35:12 localhost kernel: c0101880 t irq_disable Jun 5 21:35:12 localhost kernel: c01018a0 t lguest_write_idt_entry Jun 5 21:35:12 localhost kernel: c01018d0 t lguest_load_idt Jun 5 21:35:12 localhost kernel: c0101920 t lguest_load_gdt Jun 5 21:35:12 localhost kernel: c0101970 t lguest_write_gdt_entry Jun 5 21:35:12 localhost kernel: c01019a0 t lguest_set_ldt Jun 5 21:35:12 localhost kernel: c01019b0 t lgu Жду предложений, как хотябы данные выводимые из /proc/kallsyms считать?
Код (Text): 1 #include <fcntl.h> 2 #include <sys/stat.h> 3 4 int main(int argc,char** argv){ 5 int file; 6 char buffer[4096]; 7 if ((file = open("/proc/kallsyms",O_RDONLY)) == -1) return 1; 8 while(read(file,(void*)&buffer,sizeof(buffer))){ 9 write(1,buffer,sizeof(buffer)); 0 memset((void*)&buffer,0,sizeof(buffer)); 1 } 2 close(file); 3 }
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> int read_file(char *fn) { struct file *file; unsigned long offset; char *buf; int buf_len; int ret = -EBADF; file = filp_open(fn, O_RDONLY, 0); if (IS_ERR(file)) return ret; buf = kmalloc(buf_len, GFP_KERNEL); if (buf == NULL){ filp_close(file, current->files); return -ENOMEM; } offset = 0; //читать до конца файла while((ret = kernel_read(file, offset, buf, buf_len))>0){ offset+=ret; ... // ваши операции } kree(buf); filp_close(file,current->files); return (ret=>0) ? offset : ret; }