游客

前置知识之Linux操作系统

一言准备中...

基础概念定义

  • exploit
    用于攻击的脚本与方案
  • payload
    攻击载荷,是目标进程被劫持控制流的数据
  • shellcode
    调用攻击目标的shell的代码
  • 寄存器
    寄存器是直接焊接在CPU上的存储单元,存储空间小,但是因为距离CPU最近,调用速度最快,因此最重要的数据会存在寄存器上
  • 内存RAM
    也称为主存,程序运行后以进程的方式存在于内存中
  • 外存ROM
    例如硬盘,移动USB硬盘

Linux的专业性误区

很多人把Linux称之为操作系统,实则并不是,Linux全称叫做Linux内核,由林纳斯·本纳第克特·托瓦兹(Linus Benedict Torvalds)发明的开源的操作系统内核,而GNU(GNU’s Not Unix!)是一个由理查德·斯托曼(Richard Stallman)于1983年发起的自由软件项目,旨在创建一个与Unix兼容的操作系统,但完全不含任何Unix代码。GNU项目中包括了Shell交互工具、glibc库、gcc编译器等关键工具。由GNU和Linux内核组成了一个完整的Linux操作系统,这才能称之为一个操作系统,而我们可以选择附加安装KDE(K Desktop Enviroment),这是一个GUI可视化桌面,于是形成了我们如今看到的Linux操作系统。

C语言源代码到可执行文件

编译:由C语言源代码生成汇编代码
汇编:由汇编代码生成机器码
链接:将多个机器码的目标文件链接成可执行文件

什么是可执行文件

  • 广义:文件中的数据是可执行代码的文件:.out/.exe/.sh/.py
  • 狭义:文件中的数据是机器码的文件:.out/.exe/.dll/.so

Linux下的可执行程序:ELF(Executable and Linkable Format)
可执行程序.out
动态链接库.so
静态链接库.a

什么是虚拟内存

我们都知道计算机中有物理内存条,它是实实在在插在你的电脑插槽上的。我们作为人类想要操作内存中的数据,首先就要寻址(找到对应数据在内存中的地址),但是物理内存条中的地址过于复杂,以至于大部分正常人类都难以学习和利用,于是操作系统OS帮助我们沟通物理内存条,操作系统将对物理内存条中的数据进行处理,转换成有秩序、易理解、可操作的虚拟内存,因此我们直接操作的基本都是虚拟内存,而非真实的物理内存。
我们要明白,计算机中距离CPU越近的数据越重要,且处理速度越快,越远反之。所以速度上CPU中的寄存器>内存(也叫主存)>外存(硬盘),而我们点击运行可执行程序,CPU会将位于硬盘上的可执行程序拷贝一份到虚拟内存,这个过程有一个从节到段的映射,ELF文件存储在硬盘上,最小存储单元叫做,而拷贝到虚拟内存上,部分节被合并为,在ELF文件层面数据以段的形式存在,在操作系统层面数据以进程方式存在。

ELF的文件结构

ELF在内存中的映像

以下示例图展示了的映射关系。

节(section)与段(Segment)

代码段(Text Segmemt)包含了代码和只读数据

  • .text节
  • .rodata节
  • .hash节
  • .dynsym节
  • .dynstr节
  • .plt节
  • .rel.got节
  • ...

数据段(Data Segment)包含了可读可写数据

  • .data节
  • .dynamic节
  • .got节
  • .got.plt节
  • .bss节
  • ...

栈段(Stack Segment)


  • 一个段包含多个节

  • 段视图用于进程的内存区域的rwx权限划分

  • 节视图用于ELF文件编译链接时与在磁盘上存储时的文件结构的组织

32位和64位进程的内存占用

32位和64位进程区别在于占用大小,2的32次方大约为4GB,因此32位进程占用大概是4GB,而1GB提供给系统内核,这1GB的部分和其他进程共享,而用户态仅能使用3GB,因此文件大小>4GB时,单个32位进程无法通过常规方法将整个文件映射到内存,只能使用例如mmap内存映射分块、扩展寻址技术等方案解决。64位进程同理,但是可利用内存以几何级数增加,现今几乎没有常规单一文件能超过128TB,因此几乎不存在内存映射问题。

程序如何在内存中组织

大端序和小端序

首先我们要明白哪一边是高位,例如0X08049176,76是低位,08是高位,那么我们从76开始读入数据,直到08为止,从低地址到高地址,叫做小端序,大端序反之同理。

进程的执行过程

重要的几个寄存器

eip:存储下一条待执行指令的内存地址,执行完一条指令后自动指向下一条

ebp:作为栈帧锚点,指向当前函数栈帧的基地址

esp:始终指向栈内存的当前顶部,每执行一次push操作,ESP值减4(32位)

eax:扩展累加器寄存器,常用于加法、乘法等运算,是默认的累加器,许多算术指令会默认使用EAX作为操作数或结果寄存器

栈结构

栈结构
                                           +-----------------+
                                           |     retaddr     |
                                           +-----------------+
                                           |     saved ebp   | 32位占用4个字节,64位占用8个字节
                                    ebp--->+-----------------+
                                           |                 |
                                           |                 |
                                           |                 |
                                           |                 |
                                           |                 |
                                           |                 |
                                    esp--->+-----------------+

常用汇编指令

MOV 把源操作数据传递给目标
MOV DATA,SRC

LEA 把源操作数的有效地址传递给指定寄存器
LEA REG,SRC

PUSH 把目标值压栈,同时ESP指针-1字长
PUSH VALUE

POP 把栈顶值弹出到目的存储位置,同时ESP指针+1字长
POP DEST

C语言函数调用栈








敬告

PWN - 二进制安全 的入门门槛较高,远超过单纯的编程技能,需要深入底层原理。

  • 本文作者:Junius
  • 本文链接: https://enc.edu.pl/?post=4
  • 版权声明:本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。
文章很赞!支持一下吧 还没有人为TA充电
为TA充电
还没有人为TA充电
1
1
  • 支付宝打赏
    支付宝扫一扫
  • 微信打赏
    微信扫一扫
感谢支持
文章很赞!支持一下吧
关于作者
20
0
1
0
内卷太严重,已躺平...

世仇

上一篇

PWN环境配置

下一篇
评论区
内容为空

这一切,似未曾拥有

  • 复制图片
按住ctrl可打开默认菜单