赞
踩
# 查看/proc/pid/cmdline文件即可
$cat /proc/pid/cmdline
用于遍历Linux所有进程
#define for_each_process(p) \
for (p = &init_task ; (p = next_task(p)) != &init_task ; )
root@curtis-Aspire-E5-471G:/home/curtis/# cat /proc/kallsyms | grep get_cmdline
ffffffffb5c7c1e0 T get_cmdline
ffffffffb65a669c t get_cmdline.cold
/** * get_cmdline() - copy the cmdline value to a buffer. * @task: the task whose cmdline value to copy. * @buffer: the buffer to copy to. * @buflen: the length of the buffer. Larger cmdline values are truncated * to this length. * * Return: the size of the cmdline field copied. Note that the copy does * not guarantee an ending NULL byte. */ int get_cmdline(struct task_struct *task, char *buffer, int buflen) { int res = 0; unsigned int len; struct mm_struct *mm = get_task_mm(task); unsigned long arg_start, arg_end, env_start, env_end; if (!mm) goto out; if (!mm->arg_end) goto out_mm; /* Shh! No looking before we're done */ spin_lock(&mm->arg_lock); arg_start = mm->arg_start; arg_end = mm->arg_end; env_start = mm->env_start; env_end = mm->env_end; spin_unlock(&mm->arg_lock); len = arg_end - arg_start; if (len > buflen) len = buflen; res = access_process_vm(task, arg_start, buffer, len, FOLL_FORCE); /* * If the nul at the end of args has been overwritten, then * assume application is using setproctitle(3). */ if (res > 0 && buffer[res-1] != '\0' && len < buflen) { len = strnlen(buffer, res); if (len < res) { res = len; } else { len = env_end - env_start; if (len > buflen - res) len = buflen - res; res += access_process_vm(task, env_start, buffer+res, len, FOLL_FORCE); res = strnlen(buffer, res); } } out_mm: mmput(mm); out: return res; }
这个函数虽然不是内核导出函数,可以参考文章:Linux内核未导出符号使用方法_Configure-Handle的博客-CSDN博客
#include <linux/kernel.h> #include <linux/module.h> #include <linux/proc_fs.h> #include <linux/sched.h> #include <linux/init.h> #include <linux/kallsyms.h> #define PARM_LENTH 256 static int (*get_cmdline_fn)(struct task_struct *task, char *buffer, int buflen); //static unsigned long (*kallsyms_lookup_name_fn)(const char *name); /* 将获取的buffer中的 ‘\0’替换成空格 */ static void deal_raw_cmdline(char *buffer, unsigned int length) { int i = 0; for (i = 0; i < length; i ++) { if (buffer[i] == '\0') { buffer[i] = ' '; } } } static int __init query_process_param_init(void) { int ret = 0; struct task_struct *tsk = NULL; char buffer[PARM_LENTH] = {0}; #if 0 /* 使用命令cat /proc/kallsyms | grep kallsyms_lookup_name 获取内核函数地址 */ kallsyms_lookup_name_fn = (unsigned long (*)(const char *))0xffffffffab563dd0; /* 这里无法用kallsyms_lookup_name获取函数get_cmdline的地址 */ get_cmdline_fn = (int (*)(struct task_struct *, char *, int)) kallsyms_lookup_name_fn("get_cmdline"); if (get_cmdline_fn == NULL) { printk("Get func get_cmdline address failed\n"); } #endif /* 采用直接赋值的方法获取函数地址 */ get_cmdline_fn = (int (*)(struct task_struct *, char *, int))0xffffffffab67c230; rcu_read_lock(); for_each_process(tsk) { printk("pid -> %d comm -> %s\n", tsk->pid, tsk->comm); if (tsk->mm == NULL) { continue; } memset(buffer, 0, sizeof(buffer)); ret = get_cmdline_fn(tsk, buffer, sizeof(buffer)); if (ret < 0) { continue; } deal_raw_cmdline(buffer, sizeof(buffer)); printk("param : %s\n", buffer); } rcu_read_unlock(); return 0; } static void __exit query_process_param_exit(void) { printk("Query process param exit!\n"); } module_init(query_process_param_init); module_exit(query_process_param_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("curtis");
为什么使用kallsyms_lookup_name()找到函数get_cmdline()地址?
[ 1415.524181] pid -> 1344 comm -> ibus-extension-
[ 1415.524186] /usr/libexec/ibus-extension-gtk3
[ 1415.524189] pid -> 1346 comm -> ibus-x11
[ 1415.524195] /usr/libexec/ibus-x11 --kill-daemon
[ 1415.524198] pid -> 1350 comm -> ibus-portal
[ 1415.524203] /usr/libexec/ibus-portal
[ 1415.524206] pid -> 1361 comm -> at-spi2-registr
[ 1415.524212] /usr/libexec/at-spi2-registryd --use-gnome-session
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。