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

linuxsignal符号表6,linux及安全第六周总结——20135227黄晓妍(示例代码)

总结部分:操作系统内核三大功能:进程管理,内存管理,文件系统最核心的是进程管理为了管理,首先要对每一个进程进行

总结部分:

操作系统内核三大功能:

进程管理,内存管理,文件系统

最核心的是进程管理

为了管理,首先要对每一个进程进行描述。进程描述符提供了所有内核需要了解的信息。

进程控制模块:task_struct(抽象task_struct的简化图)

9cd097c577894df8a56dccf7245c701b.jpg

next_task,prev_task进程链表的管理

tty_struct控制台

fs_struct文件系统描述

file_struct打开的文件描述符

mm_struct内存管理的描述

signal_struct信号的描述

Linux-3.18.6/include/linux/sched.h里的代码

79077eec85144701be3384fe34eb68a1.jpg

1235代码state进程运行状态

stack指定进程的内核堆栈

flags每个进程的标识符

c3d8d2958b3c4c08a8fbd271f694d9eb.jpg

1245CONFIG SMP条件编译,多处理器时使用到的。

2940079212fc432185ca1a69b219a39d.jpg

1251on_rq运行队列

58cb5d0c90f24ba3a5181ea2f060fa57.jpg

1295list_head tasks进程链表(双向链表)

linux进程的状态和操作系统原理的描述进程状态有所不同,比如就绪状态和运行状态都是TASK_RUNNING。(这个表示它是可运行的,但是实际上有没有在运行取决于它是否占有CPU)

e64cf97b7f6e496abe0434966c84128a.jpg

1330进程标识符pid

0daea74d90b8454bbdebb98992cef30a.jpg

1349进程的父子关系

118ba5da3f534d51ad528fc9e8f1de69.jpg

1360pid_link pids[PIDTYPE_MAX]进程的哈希表

Linux-3.18.6/arch/x86/include/asm/processor.h

thread_struct(很重要)

676283bcc84d489d91e3f2c37afb04f5.jpg

0f9481fec7804add85b39efa6c6a37e5.jpg

进程的创建概括以及fork()一个进程

Cpu_idle启动两个线程:(0号进程是所有线程的祖先)

Kernel_init用户态的进程启动,所有用户态进程的祖先(1号进程是所有进程的祖先)

Kthreadd所有线程的祖先

在shell命令行创建进程的本质一样:先复制一份进程描述符,0号进程是手工写进代码的,1号进程复制0号的pcb,然后根据1号进程的需要把它的pid等等信息修改    掉,再加载一个init可执行程序。

进程是如何创建:

先看怎么在用户态创建一个子进程

9ea135fb85824bfcb0987cb543fd0cda.jpg

Pid==0是下面两个模块都会被执行,fork()系统调用在父进程子进程各返回一次,父进程中返回0,子进程中返回子进程的pid

理解进程创建过程复杂代码的方法:

系统调用:用户态int0x80(由于是陷入进入内核的,所以机器自动保存与转换堆栈;压入用户ss,压入用户esp,压入EFLAGS,压入cs,压入eip)

中断指令跳转到内和空间sysstem_call(压入eax,把传递参数的寄存器全部压栈)执行结束后RESTORE_ALL(弹栈传递参数的寄存器,弹栈eax,iret弹栈      int0x80压栈的东西)

Fork()的也是一个系统调用,它的过程图

86ad53c554e844939f8e626f742c03d1.jpg

子进程复制了父进程的所有信息,然后做适当修改,它也会调度执行。当它被CPU调度的时候从哪里开始执行呢?子进程在内核里执行,在内核处理程序从哪里开始    执行的?与mykernel类似。

fork,vfork,clone三个系统调用都是通过调用do_fork来创建创建一个新的进程。

先我们设想,它应该如何创建一个进程,我们画一个框架,然后再通过代码求证,再对我们的框架进行修正。

我们的框架:

1.创建新进程都是通过复制父进程的信息。

2.创建新进程的过程中需要做哪些事情:

复制pcb

还需要修改复制的父进程的pcb

还需要分配新的内核堆栈

子进程需要从fork返回到用户态,那么它内核堆栈也需要从父进程中拷贝一些过来,不然不能返回

还有thread.sp(调度到子进程时的内核栈顶)和thread.ip(调度到子进程的第一条指令地址)

浏览创建进程的相关关键代码

ec8dc25c07d3435885e678c88f942e48.jpg

Linux-3.18.6/kernel/fork.c

6f572bca00f1449d9473366e1018cba8.jpg

1632copy_process创建一个进程的主要代码

2a10b9f5a0d6410f97b3edc2e704dc0f.jpg

1240dup_task_struct复制pcb(看具体怎么复制)

625f0d38e1e9432ebf263395dba2e41f.jpg

6b5ca2bad65a4f668a86994ebe6ac125.jpg

320arch_dup_task_struct(tsk,orig)执行复制当前进程

7e51bee6564243d3a0ed5910258b1c97.jpg

293*dst=*src数据结构的指针的值复制

316alloc_thread_info_node(tsk,node),分配内核空间堆栈的作用和thread_info合在一起的集合体

1f95781a736f4a9aa1cd1b48a6248adf.jpg

153实际上是创建了一个一定大小的页面。一部分存放alloc_thread_info,一部分存放堆栈

190bd381500b4ce0b3eed2931920d9f5.jpg

335setup_thread_stack

b30b70e09f3443548c55fdb6f51806e4.jpg

445f4516ad42489e9226d7be2f56c51b.jpg

1240p=dup_task_struct(current);复制子进程的pcb

2457601c19ed4f0e8cd7c51f8e7b045a.jpg

1396 copy_thread

Linux-3.18.6/arch/x86/kernel/process_32.c

135*childregs=task_pt_regs(p);

159*childregs=*current_pt_regs();将父进程的现在的状态信息赋值给子进程(拷贝内核堆栈诗句和指定新进程的第一条指令)

164p.thread.ip通过ret_from_fork得到。

创建的新进程是从哪里开始执行的?

Linux-3.18.6/arch/x86/include/asm/ptrace.h

Pt_regs:系统调用压栈的内容(SAVE_ALL的全部内容)

d3ee281a42f745b2b0431c2fa9790fae.jpg

Linux-3.18.6/arch/x86/kernel/entry_32.s

290entry(ret_from_fork)新进程是从这里开始执行的

cfd5f44959c846509d7510338e26a071.jpg

505syscall exit内核堆栈返回到系统调用以前的状态继续执行

157cc949c2e34a288f926d1d1fed680f.jpg

实验部分:

使用gdb跟踪调试创建新进程的过程

cd LinuxKernel

rm menu –rf

git clone https://github.com/mengning/menu.git

cd menu

mv test_fork.c test.c//覆盖test_fork.c

make rootfs

feb7754e3a3d431ea7cdfaccd8c4b4f3.jpg

看到增加了一个fork

96fcb47e2f07452389afd3c474c94c5b.jpg

24d1efb16a1f4e18a306b96706f93c82.jpg

使用gdb跟踪调试内核

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

# 关于-s和-S选项的说明:

# -S freeze CPU at startup (use ’c’ to start execution)

# -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项

Gdb

(gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表

(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行

cf2d3413c9d34eda9c10bc18e2f73774.jpg

363d2d564f7d4b488a6253e3208e3108.jpg

b sys_clone

b do_fork

b dup_task_struct

b copy_process

b copy_thread

b ret_from_fork

c5d09960c5354aa29954467b08974e4f.jpg

copy_process

c13e05f97761490c9347aa3abd472ee7.jpg

dup_task_struct

68e6875d6e8f40eca71bd875cd3f90b0.jpg

将父进程的现在的状态信息赋值给子进程(拷贝内核堆栈诗句和指定新进程的第一条指令)

e05e23137ef447feb7b803fc810f6866.jpg

将子进程的栈顶保存

766c1c3e2e7d42e4bcb7ce35ffa2cd5c.jpg

线程的pid保存

3d4cc8ae3fef485795bebc0da30f015b.jpg

直到syscall_exit就跟踪不到了。

思考部分:

理解创建一个新进程如何创建和修改task_struct数据结构

一般通过系统调用来创建新的进程。fork(),vfork(),clone()都是通过调用do_fork来创建新进程的。要通过复制父进程的信息pcb(task_struct),然后给新    的子进程分配内核堆栈,再通过copy_process来修改子进程的task_struct.

特别关注新进程是从哪里开始执行的?为什么从哪里能顺利执行下去?即执行起点与内核堆栈如何保证一致。

ce43afda65f144309b26b6074327f4c0.jpg

从ret_from_thread开始执行。子进程被创建以后是在内核运行的,因为从这里开始复制父进程的task_struct,分配内核堆栈,创建进程也是一种系统调用,在内核堆栈中,执行int0x80,保存现场,来保证执行起点和内核堆栈的一致性。



推荐阅读
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 服务器上的操作系统有哪些,如何选择适合的操作系统?
    本文介绍了服务器上常见的操作系统,包括系统盘镜像、数据盘镜像和整机镜像的数量。同时,还介绍了共享镜像的限制和使用方法。此外,还提供了关于华为云服务的帮助中心,其中包括产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题和视频帮助等技术文档。对于裸金属服务器的远程登录,本文介绍了使用密钥对登录的方法,并提供了部分操作系统配置示例。最后,还提到了SUSE云耀云服务器的特点和快速搭建方法。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
author-avatar
梦露的殇_192
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有