基本概念

  • exploit:用于攻击的脚本与方案
  • payload:攻击载荷,目标进程被劫持控制流的数据
  • shellcode:调用攻击目标的shell的代码

可执行文件

  • 广义:文件中的数据是可执行代码的文件,.out .exe .sh .py

  • 狭义:文件中的数据是机器码的文件,.out .exe .dll .so

  • windows:PE(Portable Executable)

    • 可执行程序.exe
    • 动态链接库.dll
    • 静态链接库.lib
    • PE文件详细分析见课程报告计算机病毒实验二
  • Linux:ELF(Executable and Linkable Format)

    • 可执行程序.out

    • 动态链接库.so

    • 静态链接库.a

      如下,通过vim编写简单的C程序,使用gcc编译链接得到elf文件:

      image-20250815223931808

      image-20250815223628557

      image-20250815224600078

  • ELF结构

    image-20260414221350574

    • ELF文件头表(ELF header):记录ELF文件的组织结构

    • 程序头表/段表(Program header table)

      • 告诉系统如何创建进程
      • 生成进程的可执行文件必须拥有此结构
      • 重定位文件不一定需要
    • 节头表(Section header table)

      • 记录了ELF文件的节区信息
      • 用于链接目标文件必须拥有此结构
      • 其他类型目标文件不一定需要
    • 磁盘中的ELF(可执行文件)与内存中的ELF(进程内存映像)

    2adaa58a2ff887ca06991b5863fc2ad8_720

    599f2e9587c3b4d28e5618800904a607_720

    查看磁盘中的文件格式:

    image-20250815223735722

    image-20250815223859650

    linux的进程以文件的形式在文件系统中存放一份,在目录/proc/pid/maps下,但要在程序运行的时候看,可以去目录下找系统维护的守护进程看,或者通过gdb看内存空间信息:

    image-20250815225031797

    image-20250815225315899

    image-20250815225343842

    程序运行在内存的物理地址上是实模式,但程序可以直接访问物理地址,对操作系统很不安全,因此需要保护模式,由操作系统给程序划分物理内存,并将物理内存映射为虚拟内存,程序操作虚拟内存,由操作系统再访问对应的物理内存,并且重要的功能不能直接访问,系统提供接口,用户调用后由操作系统进行操作。既然映射由操作系统完成,那程序如果能通过访问不同虚拟内存,分析对应的结果,得到映射关系?

机器码

  1. 地址以字节编码表示:1 Byte = 8 bits
  2. 阅读常以16进制表示:0x3c = 0011 1100

程序运行

虚拟内存

  1. 虚拟内存用户空间每个进程一份,因为每个进程不一定需要整个内存大小的空间,所以操作系统可以分配给每个进程
  2. 虚拟内存内核空间所有进程共享一份(图中内核空间的部分)
  3. 虚拟内存mmap段中的动态链接库仅在物理内存中装载一份
  4. 32位和64位指地址总线传输数据的宽度,所以理论最大内存空间是232B=4GB2^{32}B=4GB或者264B=224TB2^{64}B=2^{24}TB

段(segment)与节(section)

  1. 一个段包括多个节
  2. 段视图用于进程的内存区域的rwx权限划分
  3. 节视图用于ELF文件编译链接时 与 在磁盘上存储时的文件结构的组织
  • 代码段(Text Segment)包含了代码与只读数据
    • .text节
    • .plt节
    • .rodata(read only data)
  • 数据段(Data Segment)包含了可读可写数据
    • .got.plt节:动态链接函数地址
    • .bss节: 未初始全局变量
  • 栈段(Stack Segment):局部变量
image-20250822152958148
  • x、y作为形参,运行的时候32位存入栈,64位存入寄存器。

大端序与小端序

image-20250822153809250

  • 小端序更容易被利用:C语言以\x00表示字符串结尾,如果要覆盖\x0000 2345,从右往左可以进行低地址往高地址的覆盖,但高地址就是\0x4523 0000,从右往左碰到\0x00就结束了。
image-20250822155931722 image-20250822160102693

静态链接的程序执行过程

image-20250822160406250

动态链接的程序执行过程

image-20250822160501699
  • id.so管理第三方代码库的借还

汇编指令

image-20250822161814511

参考资料

【XMCVE 2020 CTF Pwn入门课程】https://www.bilibili.com/video/BV1854y1y7Ro?vd_source=a18525c81c0a5ce9a430410ab6fd6327