CPU与进程的执行

发布于 2023-02-24  224 次阅读


上图所示的code段(也称text段),俗称的代码段,data段就是数据段,其内包含的节如下图

text段里的.text节里面包含的主要内容就是程序中用户自己实现的一些代码逻辑, 数据段里保存了一些数据的节,一般是程序所用到的数据,这些数据并不是代码,如.bss节保存的就是全局偏移量的地址,.data节保存的是程序中所要用到的一般性的数据,.dynamic节记录了程序中动态链接所需要的一些数据。(rwx是读、写、执行的缩写)。

下图是c的源代码在程序或者程序映像中所对应的结构划分。

源代码中的int glb;是声明的一个全局变量,被放在了右图程序映像的Bss区域中,Bss的一个核心的作用就是存放未初始化的全局变量 ,此时该全局变量不会占用磁盘空间,但会占用内存空间;char *str是声明的一个字符指针,并指向了一个字符串,此时为只读不可写的,故放在了程序映像的text段(也称code段,即代码段)中的.rodata节中;int sum 函数实际上也会被编译成一段数据,具体过程大概就是现由c的源代码编转化为汇编代码,汇编代码进一步转化为相应的机器码,并存放到ELF文件中,进而加载到内存中,此时就放在了Text(code)段中(代码段)。 main函数也是同理,以机器码的形式在Text段中存放。int sum函数中的局部变量t是存放在进程执行栈(Stack)中的。接下来是main函数中的代码讲解,main函数中的sum函数调用的内存开销也是在Stack中,void *ptr声明了一个无类型的指针,是一个局部变量,存放在Stack。malloc函数是用来申请0x100大小的空间(malloc函数的具体用法放在文章末尾),而该空间是从Heap中申请获取的。之后的read函数(read函数的用法放在文章末尾)将input进0号文件的一串字符读取到ptr中,而此时这串字符就存在Heap中,c的源代码在内存中的映射关系大致就是这样。

pwn实战中常遇的小端序(LSB),大端序(MSB)一般出现在比较高级的pwn中。

从源代码,到磁盘上的可执行文件,到内存中的进程映像,这个程序就已经执行起来了,执行时是cpu与内存配合执行,如下图:

PC 为程序记述器对应的是cpu里的一个特殊的寄存器,例如AMD64的话就是RIP,总是保存了当前在内存中的代码段中正在执行的代码的地址。PC旁的绿框就是Code箭头的放大。该地址指向的指令会被送到cpu里,经过解码译码等操作之后,将指令执行完毕。大多数情况下指令执行完后会返回寄存器 ,访存指令则是把结果返回内存里。cpu与内存的协作总结就是内存把相应的数据、代码送进cpu,cpu把这些指令执行完毕后,把一些需要的数据重新写回内存中。

cpu与内存的传输通道称为总线,分为数据、地址、指令,通过总线与内存传输数据;cpu可以向内存发出访存指令,当cpu发出访问某地址的指令,对应的内存就把该地址存储的数据反馈给cpu;

cpu中的寄存器:

越靠近cpu的存储器,反馈速度越快,存储容量越小,价格越高昂;越远离cpu的存储器反馈速度慢,存储容量大,价格越便宜。最接近cpu的存储器实际是一种寄存器 ,相当于直接嵌在cpu中,如下图。cache是一个数据缓存的结构,用来区分高端低端cpu的标志,高端的cpu会分多级cache,并且容量大。Register寄存器存放的是当前执行且需要快速做出反应的指令。

见下图 ,Memory为主存(内存),Storage为外存。主存中的数据断电即失效,无法长期稳定存储数据,内存相当于就是存放了当前工作任务的数据。 Storage则可以长期稳定存储数据。如固态硬盘,机械硬盘,SD卡等。外存中的数据首先被加载到主存,再被cpu访问。

amd64寄存器的结构如下(与X86的大同小异):

比较推荐X86入门pwn

RIP寄存器又叫pc,程序记述器。

RAX寄存器存在于cpu中的Register模块里,8bytes长度,64bite。

malloc函数的用法

当我们需要做一个成绩管理系统,人数可能为全校学生,也可能为一个班的学生,当我们开辟一个班的数组大小时,如果要存储整个学校的人数时,会出现内存不够用的情况;当我们开辟全校人数大小的数组时,输入一个班人数的大小时,会出现内存浪费的情况。
为了应对上述问题,我们引入malloc函数。

malloc时动态内存分配函数,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址

malloc函数原型 :

意为分配长度为num_bytes字节的内存块

malloc函数头文件:

malloc函数返回值

如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。

malloc函数使用注意事项:

malloc函数的返回的是无类型指针,在使用时一定要强制转换为所需要的类型。

(敲黑板)重点:在使用malloc开辟空间时,使用完成一定要释放空间,如果不释放会造内存泄漏。
在使用malloc函数开辟的空间中,不要进行指针的移动,因为一旦移动之后可能出现申请的空间和释放空间大小的不匹配

malloc函数使用形式

read函数的用法


穿过云层我试着努力向你奔跑