linux管道写满程序崩溃,(linux)从进程和管道解析炸弹函数(5个字符如何让你的windows3秒钟崩溃)...

1 进程

1.1进程介绍

进程是程序执行时的一个实例,从内核来看,进程就是分配系统资源(CPU时间,内存等)的基本单位,进程的优点:进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它的进程产生影响。进程的缺点:就是在进程切换时,耗费的资源大,相对于线程来说,线程速度是进程速度的几十倍,因为一个进程可以由多个线程组成,线程与同属于一个进程的其它线程共享进程全部资源,但线程没有独立的地址空间,一个线程崩溃相当于整个进程崩溃。所以多进程的程序要比多线程的程序健壮。

1.2 进程所需条件

一个进程至少具备四个条件,用来管理进程的task_struct结构的进程描述符,该结构体包含进程所需的所有信息;必须有一段可执行的代码;必须有具备它的独立空间;必须具备独立的内核堆栈,目的是代码从内核态进入用户态时,必须保护内核现场,使其能够恢复。

1.3 创建进程所需的函数

创建进程时需要用到fork机制,即写时复制,这也是fork()函数的原理;从内核源码解析来看利用get_empty_process()函数来获得最新的进程号,find_empty_process(void)函数来找到空闲的进程号,利用copy_mm()函数复制父进程的内存描述符,再利用copy_process()函数从父进程中拷贝进程信息,使用“写时复制”技术创建子进程,把子进程所需的父进程里空间会原模原样地复制到子进程中,只有真需要分配独立的内存空间时,才会发生缺页中断,分配全新的内存空间。而exec函数族的作用就是在调用进程内部执行一个可执行文件。

1.4 Linux进程的几种状态

Linux进程中有5种进程状态,源码volatile long state下state的成员有TASK_RUNNING、TASK_INTERRUPTIBLE、TASK_UNINTERRUPTIBLE、TASK_STOPPED、TASK_TRACED五种状态,TASK_RUNNING表示进程要么是执行态,要么是正要准备执行,正在等待CPU时间片的调度;TASK_INTERRUPTIBLE表示该进程因为等待一些条件而被阻塞所处的状态,一旦条件成立就会从阻塞态迅速转化为就绪状态TASK_RUNNING;TASK_UNINTERRUPTIBLE与阻塞态类似,但不能通过接受一个信号来唤醒,对于处于TASK_UNINTERRUPIBLE状态的进程,只有它所等待的资源可用的时候,它才会被唤醒;TASK_STOPPED进程被停止执行,当进程收到SIGSTOP等类似特定信号之后就会进入该状态;TASK_TRACED表示进程被debugger等进程监视,当一个进程被另外一个进程所监视时,每一个信号都会让进程进入该状态;还有2种终止状态EXIT_ZOMBIE和EXIT_DEAD,EXIT_ZOMBIE表示进程的执行被终止,但是其父进程还没有使用wait()等系统调用来获知它的终止信息,此时进程成为僵尸进程;EXIT_DEAD表示进程的最终状态,Linux进程几种基本状态的转换如图1-1

ed10ff9ba6310e1d25ce45c092b3b2cc.png

图1-1 进程状态转换

2  管道

2.1 管道的介绍

两个相互独立的进程就是通过管道来互相通信的,管道是进程间通信的一种手段之一,管道是一种特殊的文件,它不属于文件系统,而是一种独立的文件系统,有自己的数据结构,按照管道的适用范围分为无名管道和命名管道。

2.1.1 无名管道

无名管道主要应用于父进程与子进程之间,或者近亲进程,在Linux系统中可以通过系统调用建立起一个单向的通信管道,并且这种关系只能通过父进程来建立。所以每个管道都是单向的,当需要双向时再建立起两个管道,一个写一个读,遵循“先进先出”原则。

2.1.2 命名管道

命名管道是解决无名管道这种只能用于近亲关系的进程通信的缺陷,命名管道是建立在实际的磁盘介质或文件系统中上有名字的文件,任何进程可以在任何的时间通过文件名或路径与该文件建立联系,需要FIFO文件类型来实现。

2.2 管道的实现机制

管道是一个环形缓冲区,是内核管理的一个缓冲区,管道的一端连接一个进程的输出,这个进程会向管道放入信息,管道的另外一端连接另外一个进程的输入,这个进程取出被放入管道的信息。当管道中没有信息时,从管道中读取的进程会等待,直到另一端放入信息,当管道放满信息的话,尝试放入信息的进程就会等待,直到另一端的进程取出信息,当两个进程交互过程都结束时,管道会自动消失,如图2-1

818b18b4c1f0647953651099465b2a6e.png

图2-1

2.3 管道的实现细节

在Linux中,并没有专门的数据结构来给管道实现,而是借助了file文件系统结构和VFS的索引节点inode,通过将两个 file 结构指向同一个临时的 VFS 索引节点,而这个 VFS 索引节点又指向一个物理页面而实现的。进程1和进程2之间的两个file数据结构中的操作例程地址是不同的,其中一个是向管道中写入数据的例程地址,另一个是从管道中读出数据的例程地址。

2.3.1 管道的读写

管道的读写依赖于管道的读函数pipe_read()和写函数pipe_write()。管道写函数将字节复制到 VFS 索引节点指向的物理内存而写入数据,管道读函数是通过复制物理内存中的字节而读出数据。当写进程向管道写入时,利用标准库函数write(),系统根据库函数传递的文件描述符,找到该进程的file结构,file结构中指定了进行写操作的函数的地址,内核调用该函数完成写入,不过在写入之前需要检查VFS索引节点的信息,看内存是否有足够的空间写入所有的数据,还要确定没有被读进程锁定,否则,写进程就休眠在 VFS 索引节点的等待队列中,管道的读取过程和写入过程类似。当完成所有操作时管道的索引节点被丢弃,共享数据页也被释放。

2.4 管道的用法

用法: command 1 | command 2 他的功能是把第一个命令command 1执行的结果作为command 2的输入传给command 2。

3  爆炸函数fork bomb

3.1 fork bomb 函数介绍

fork bomb :(){:|: &};:是一个简单的bash fork炸弹,是一种利用系统调用fork进行拒绝服务攻击,:()是函数体,:是一个shell内置命令也是一个函数名,所以这段代码只有在bash中才可能产生fork炸弹,内置命令的优先级高于函数,所以执行该代码相当于执行内置命令,通过管道符来把第一个:进程执行的结果作为下一个:进程的输入,无限制的复制自身,相当于刚开始是两个:进程通过pipe进行读写操作,这样就会衍生出四个:进程,无限制的复制自身之后,由于每个进程都有独立的内存空间,而且此时进程的状态是TASK_RUNNING执行的状态,如果没有优先级别更高的进程来迫使它等待,那么进程就会一直复制下去,直到Linux系统的内存达到饱和状态,函数又是以2为的底的指数函数,创建进程的速度非常迅速,能在几秒钟就能把普通电脑的内存全部分配完,导致内存不够,死机,解决方法可以通过修改 vi /etc/security/limits.conf 文件来限制每个用户可以调用的进程

Linux下fork bomb测试,测试使用的是虚拟机,结果如图3-1、3-2

064bd40dd70fc60fe76ca1cd860f4926.png

26526bcb536df2efd61b5c5634d1281b.png

在执行命令过程中,连续敲打了基础fork bomb 进程数量显示在恐怖的增加,最终导致虚拟机卡住,不能动,而且通过虚拟机强制关闭也关闭不了,显示ubuntu繁忙,最终通过任务管理器强制关闭VM虚拟机,导致再一次进入时,ubuntu直接显示无法打开,显示主机正在使用,要求移除虚拟机。重启了电脑之后才恢复过来。

通过修改 vi /etc/security/limits.conf 文件来限制用户可以调用的进程测试结果如图3-3,、3-4

7e8740305468ed2e558ebd28e8a692f4.png

图 3-3 改变root用户所能创建的进程数

d6207f6a364b02005ac690f5b82336ab.png

图 3-4 进入root模式执行fork bomb

结果测试可以通过修改配置文件来限制用户创建的进程数,从而来躲避fork bomb函数

3.2 Windows下的简单fork bomb与实现

命令:%0|%0;在Windows下新建一个文本文档在文件中写入%0|%0,并把后缀名改为.bat之后双击程序运行,查看结果,实现原理与Linux下的fork bomb一样%0是当前正在执行的批处理文件的名称,%0|%0将会永久的递归执行,快速创建许多进程并放慢系统速度。图3-5、图3-6、图3-7为运行结果截图。

d023688971500c24c9449c6fbff2e5b8.png

图3-5 建立文本,写入fork  bomb 并修改后缀

ac37552b94e8ce4633c63a27db7e5338.png

图3-6程序执行3秒后

5a3262d785d7d6f92987fd97e00788c6.png

图3-7 程序执行7秒后

程序执行七秒之后,电脑死机,鼠标不能移动,解决的办法也只有一个就是关机重启电脑才能恢复。

4  结束语

通过这次课程设计,让我更进一步的了解进程的概念,已经进程与线程之间的关系,认识到管道符的强大,也见识到fork bomb的威力,也看到了Linux的魅力所在。课程设计的时间也比较急,想课题也花了不少的时间,不过有了明确的方向之后,一切没有想象中的那么难,或许是自己不够深入,在看Linux内核源码解析的时候看的还是别人的注释版也看的有点迷惑不解,但通过搜索资料,知道某些函数的用处,和实现过程就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值