打印指定进程中的数据

news/2024/11/28 16:03:34/

本次要实现,指定进程pid,和某个字符串变量的地址,在linux内核中将字符串内容打印出来。测试程序的代码如下:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>char* p = "hello, can show this in driver";int main()
{printf("pid = %d\n", getpid());printf("%s  ,addr: %p\n", p, p);getchar();return 0;}

 执行结构如下:

pid = 8208
hello, can show this in driver  ,addr: 0x400628

进程的PID为8208,该进程内字符串的地址是0x400628,字符串的内容是:hello, can show this in driver。

下面是内核部分的代码,主要逻辑是遍历进程列表,找到目标进程,再根据分页的各层级找到目录页表,获取对应的页框。最后根据虚拟地址在页框内的偏移,将字符串打印出来。

static int mem_print(struct inode* inode, struct file*filep)
{struct task_struct * p;// 变量系统中的每个进程for_each_process(p) {// 不是目标进程if (8208 != p->pid){continue;}printk("------\n");printk("state - %X\n", p->state);printk("pid - %X\n", p->pid);struct fs_struct *fs = p->fs;if (NULL != fs){struct path cur_path = fs->pwd;if (NULL != cur_path.dentry){struct dentry *dentry = cur_path.dentry;while (NULL != dentry){printk("d_iname = %s ,", dentry->d_iname);if (0 == strcmp("/", dentry->d_iname)){break;}dentry = dentry->d_parent; // 父目录}}}unsigned long addr = 0x400628; // 目标字符串的虚拟地址struct mm_struct *mm = p->mm;if (NULL != mm){struct vm_area_struct *vm_area = mm->mmap;pgd_t *pgd = pgd_offset(mm, addr);printk("pgd = %ld, %p\n", pgd, pgd);p4d_t *p4d = p4d_offset(pgd, addr);pud_t *pud = pud_offset(p4d, addr);printk("pud = %ld, %p\n", pud, pud);pmd_t *pmd = pmd_offset(pud, addr);printk("pmd = %d, %p\n", pmd, pmd);pte_t *pte = pte_offset_kernel(pmd, addr); // 页表的线性地址struct page *page = pte_page(*pte); // 页框的线性地址if (NULL != page){printk("page = %lx\n", page);printk("flags = %u\n", page->flags);// 地址在页框内的偏移int offset = addr & 0xFFF;printk("offset = %d\n", offset);unsigned long pfn = page_to_pfn(page);printk("pfn = %x\n", pfn);void *p_addr = page_address(page);printk("p_addr = %lx\n", p_addr);printk("data: %s\n", p_addr + offset);}}}return 0;
}

打印的内核日志如下:

[ 5167.042332] ------
[ 5167.042333] state - 1
[ 5167.042334] pid - 2010
[ 5167.042335] d_iname = mem_test ,
[ 5167.042335] d_iname = 网络 ,
[ 5167.042336] d_iname = linux笔记 ,
[ 5167.042336] d_iname = 桌面 ,
[ 5167.042337] d_iname = wang ,
[ 5167.042347] d_iname = home ,
[ 5167.042348] d_iname = / ,
[ 5167.042349] pgd = -122599419764736, 000000003c17b28f
[ 5167.042350] pud = -122596816502784, 00000000867a9350
[ 5167.042351] pmd = 830038032, 0000000005dcf8ab
[ 5167.042352] page = fffff08700184e80
[ 5167.042352] flags = 3221291048
[ 5167.042353] offset = 1576
[ 5167.042353] pfn = 613a
[ 5167.042354] p_addr = ffff907f0613a000
[ 5167.042354] data: hello, can show this in driver
 

 d_iname是pid为8208的进程程序文件所在的各级目录,完整目录是:/home/wang/桌面/linux笔记/网络/mem_test。

日志的最后一行,将目标字符串打印了出来。


http://www.ppmy.cn/news/245376.html

相关文章

2022年全国大学生数学建模竞赛总结

写在前面&#xff1a;伴随着国赛成绩的公布&#xff0c;2022年数学建模国赛在我的心里终于落下帷幕&#xff0c;难忘的三天三夜的旅程现在想起来依旧让我热泪盈眶&#xff0c;是我在大学里面为数不多的的热血的经历&#xff0c;是青春&#xff0c;是汗水&#xff0c;是拼搏。 虽…

C语言3位~7位水仙花数(加强版)

输出水仙花数。输人一个正整数&#xff08;3≤ n ≤7)&#xff0c;输出所有的n位水仙花数。水仙花数是指一个 n 位正整数&#xff0c;它的各位数字的n次幂之和等于它本身。例如153的各位数字的立方和1^35^33^3153。 附&#xff1a;水仙花数又称阿姆斯特朗数。 三位的水仙花数共…

DAC驱动芯片 GP8201 GP8403

GP8403 通过I2C接口&#xff0c;线性转换成0-5V或0-10V的两路模拟电压输出。 一个I2C接口支持8路GP8202并联&#xff0c;通过三位硬件地址A2/A1/A0选择。 输入信号范围12Bit&#xff0c;0x000-0xFFF 0-5V/0-10V输出电压通过内部数据控制 输入I2C信号高电平&#xff1a;2.7V-…

某项目网络实施中的几个关键点解析

项目背景&#xff1a;某网络项目牵涉到旧网升级新网的改造&#xff0c;新增设备比较多的是JUNIPER EX系列交换机(涉及高中低端)&#xff0c;与原有CISCO 系列交换机融合。 1、新核心EX8208&#xff08;主&#xff09;与旧核心CISCO 6506相连&#xff0c;网络架构如图&#xff1…

六、opengles显示YUV数据

工程文件名为&#xff1a;com.example.threetextureyuv 1、yuv回顾 1&#xff09;yuv的由来 是在保持图片质量的前提下降低图片内存大小提供传输效率&#xff0c;并且传统的BGR格式 对于黑白图片不支持亮度的调节。 Y”表示明亮度&#xff08;Luminance、Luma&#xff09;&…

无念品牌用实力吸引硬汉任天野代言,强强联合,够“野”

为致敬抗美援朝无名英雄,由无念颈椎按摩仪形象代言人任天野主演的网络电影《浴血无名川》 ,于4月2日在爱奇艺独播,自开播以来,取得不俗口碑,《浴血无名川》讲述了抗美援朝战争时期,中国志愿军三排排长孟大关(任天野饰)临危受命,带领小队前去解救被困敌后的侦察排,经历了一系列艰…

国庆健身好物推荐

国庆假期到了今年小长假似乎与往年有些不同&#xff0c;周围很多的小伙伴愿意充分利用假期“迈开腿”&#xff0c;以健身的方式拥抱节日&#xff0c;在运动中享受节日的快乐。对于不经常健身的小伙伴来说&#xff0c;有哪些健身好物能派上用场呢&#xff0c;今天就和大家分享一…

语音播报芯片在按摩仪行业的应用分析

语音播报芯片在按摩仪行业的应用分析 芯片是半导体元件产品的统称&#xff0c;是集成电路的载体&#xff0c;是由晶圆分割而成。而语音播报芯片就是可以存储控制播放语音的IC。近年来&#xff0c;智能互交产品的不断涌现为语音播报芯片行业的发展提供了有利的土壤&#xff0c;让…