taskverse学习
简介
taskverse是《linux二进制分析》一书作者编写的一个隐藏进程的检测工具,它使用/proc/kcore来访问内核内存,github的地址在这里:https://github.com/elfmaster/taskverse。
/proc/kcore
这个文件是内核提供的用来遍历内核内存的接口,使用elf文件格式,他的实现在内核文件\fs\proc\kcore.c中,文件的主要操作在proc_kcore_operations中,围绕一个链表kclist_head来组织elf中的各个段。而一个段就代表着一段内存,将这些内存映射成可执行文件的段。看看这些段的信息,在这之前有一个note段,这里面保存着一些其他信息,这里就不分析了,从内核源码里的get_kcore_size可以看出网note段里面放的是什么。
为了解释这个文件的用法,我写了一个简单的例子,代码在这里:https://github.com/smakk/kocre_sample
可以使用readelf -h的命令去查看,可以发现/proc/kcore这个文件是没有节区的,也就是没有办法访问到符号表,这里使用了/proc/kallsyms这个文件来访问符号地址,具体代码如下,根据名字,不断读取符号文件来找到符号地址
//由于/proc/kcore没有节头,找不到符号表,所以通过kallsym来找符号地址
unsigned long get_sym(char* name){
FILE *fd;
char symbol_s[];
int i;
unsigned long address;
char tmp[], type; if ((fd = fopen("/proc/kallsyms", "r")) == NULL)
{
printf("fopen /proc/kallsym wrong\n");
exit(-);
}
while(!feof(fd))
{
if(fscanf(fd, "%lx %c %s", &address, &type, symbol_s)<=){
printf("fscanf wrong\n");
exit(-);
}
if (strcmp(symbol_s, name) == )
{
fclose(fd);
return address;
}
if (!strcmp(symbol_s, ""))
break;
}
fclose(fd);
return ;
}
接着就是/proc/kcore的使用,这里使用一个全局的链表kcore,来表示/kcore的一个段信息中的虚拟地址,文件偏移量和大小,有这3个量就可以访问内存了
struct kcore_list{
struct kcore_list* list;
unsigned long vaddr;
unsigned long offset;
size_t size;
};
struct kcore_list kcore; /*
生成kcore链表,按照虚拟地址升序存放kcore提供的所有的地址空间,而且这些地址空间是不重叠的
*/
void* init_kcore_list(){
int fd = open("/proc/kcore", O_RDONLY);
if(fd < ){
printf("open /proc/kcore wrong\n");
exit(-);
}
Elf64_Ehdr head;
read(fd,&head,sizeof(Elf64_Ehdr));
if(lseek(fd,head.e_phoff,SEEK_SET)<){
printf("lseek /proc/kcore wrong\n");
exit(-);
}
Elf64_Phdr phdr[head.e_phnum];
read(fd,&phdr,sizeof(Elf64_Phdr)*head.e_phnum);
close(fd);
int i;
for(i=;i<head.e_phnum;i++){
struct kcore_list* k_list = malloc(sizeof(struct kcore_list));
k_list->vaddr = phdr[i].p_vaddr;
k_list->offset = head.e_phoff+sizeof(Elf64_Phdr)*i;
k_list->size = phdr[i].p_memsz;
struct kcore_list* tmplist = &kcore;
while(tmplist->list != NULL && tmplist->list->vaddr<k_list->vaddr){
tmplist = tmplist->list;
}
k_list->list = tmplist->list;
tmplist->list = k_list;
//printf("%lx\n",k_list->vaddr);
}
return;
}
现在已经存储完kcore的段信息,要想访问符号虚拟地址指向处的地址,就是要先找出虚拟地址位于哪个段中,然后转换成这个段在文件中的偏移,最终根据文件偏移去访问文件。代码如下:
/*
根据虚拟地址addr,从/proc/kcore这个位置读取size大小的内存
*/
void* get_area(unsigned long addr, size_t size){
void* ret;
struct kcore_list* k_list = kcore.list;
while(k_list != NULL && addr>k_list->vaddr + k_list->size){
k_list = k_list->list;
}
if(addr>=k_list->vaddr && addr+size<k_list->vaddr + k_list->size){
int fd = open("/proc/kcore", O_RDONLY);
if(fd < ){
printf("open /proc/kcore wrong\n");
exit(-);
}
if(lseek(fd,k_list->offset+(addr-k_list->vaddr),SEEK_SET)<){
printf("lseek /proc/kcore wrong\n");
exit(-);
}
ret = malloc(size);
read(fd,ret,size);
close(fd);
}
return ret;
}
最后,使用这个借口,我做了一个简单的使用例子,找到init_task的进程描述符,在内核的进程描述符中,第一个字段表示的是进程状态,这里输出init_task的进程状态,打印这和结果。
int main(){
init_kcore_list();
printf("_text addrs is %lx\n",get_sym("_text"));
void * code = get_area(get_sym("init_task"),);
unsigned long * statue = (unsigned long *)code;
//0代表正在运行,大于0表示停止了
printf("init_task statue is %ld\n", *statue);
return ;
}
taskverse分析
程序入口地址在主目录下的taskverse.c中的mian函数,在taskverse中,可以使用两种寻找符号的方式,一种是kallsyms,另一种是systemmap文件。
值得注意的是elf结构中的mem结构,这里的mem结构放了3个内容
taskverse学习的更多相关文章
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- Unity3d学习 制作地形
这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...
- 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...
- 菜鸟Python学习笔记第一天:关于一些函数库的使用
2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
随机推荐
- ROS机器人开发实践学习笔记3
摘要: 刚刚开始学习ROS,打算入机器人的坑了,参考教材是<ROS及其人开发实践>胡春旭编著 机械工业出版社 华章科技出品.本来以为可以按照书上的步骤一步步来,但是,too young t ...
- Elasticsearch的java客户端JEST的操作
准备 把Elasticsearch安装好 安装百度上有很多资料. 导入必要的包 <parent> <groupId>org.springframework.boot</g ...
- Jmeter Web 性能测试入门 (一):环境配置 (免安装版)
去官网下载并安装java jdk8 去官网下载jmeter binaries最新的zip,并解压到某路径下.(注:由于jmeter-server的限制,放置的路径不要太长,路径不要带空格,例如:D:\ ...
- 服务器 Web服务器 应用服务器区别联系
服务器: 通俗的讲,我们访问一个网站就相当于访问一个服务器的文件,如果想要通过自己的域名来访问一个网站,首先得将域名部署到你的服务器上,然后就可以通过域名访问到你服务器上的网 页文件.ip地址就相当于 ...
- 如何构建自己的docker镜像
需求情况:springboot项目想要部署到docker里面,如何部署? 步骤如下: 1.将jar包上传linux服务器 /usr/local/dockerapp 目录,在jar包所在目录创建名为 D ...
- What do you do as a DevOps?
https://ilhicas.com/2019/08/11/What-you-as-a-Devops.html Introduction In this post I'll just explain ...
- [MyBatis]浅谈如何实现事务处理
要实现事务处理,就得从SqlSession中取出connection来,然后对connection采用setAutoCommit,commit,rollback等操作,最后的时候,不能像JDBC一样关 ...
- 美国top200药品2
python机器学习-乳腺癌细胞挖掘(博主亲自录制视频)https://study.163.com/course/introduction.htm?courseId=1005269003&u ...
- qt ui
/******************************************************************************** ** Form generated ...
- 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_14-异常处理-异常处理的问题分析
这块代码没有异常处理.如果在Service出现了异常代码,在哪里捕获?要么在Servive内捕获,要么在调用service的地方也就是controller内捕获 每个调用service的地方都要去捕获 ...