基础概念定义
- 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 - 二进制安全 的入门门槛较高,远超过单纯的编程技能,需要深入底层原理。
这一切,似未曾拥有