20242407 2026-2027-1 《网络与系统攻防技术》实验一实验报告

20242407 2026-2027-1 《网络与系统攻防技术》实验一实验报告

1. 基础知识

1.1 二进制程序分析基础

1.1.1 Linux ELF可执行文件

Linux系统中的可执行程序通常采用ELF(Executable and Linkable Format,可执行与可链接格式)文件格式。

ELF是一种用于描述可执行文件、目标文件以及动态链接库的文件格式,其中包含了程序运行所需的各种信息,例如:

  • 程序入口地址;
  • 代码段位置;
  • 数据段位置;
  • 程序加载方式;
  • 符号信息等。

一个典型的ELF文件主要包含以下几个部分:

ELF Header
    |
    ↓
Program Header Table
    |
    ↓
代码段(.text)
    |
    ↓
数据段(.data/.bss)
    |
    ↓
Section Header Table

其中,与本实验关系最密切的是代码段(.text)。

代码段保存程序实际执行的机器指令,例如:

  • 函数代码;
  • 条件跳转指令;
  • 无条件跳转指令;
  • 函数调用指令。

本实验中的目标程序pwn1就是一个Linux ELF可执行文件。
由于实验目标是:

  • 修改程序执行流程;
  • 调用隐藏函数getShell;
  • 利用程序漏洞控制执行过程;

因此首先需要对ELF文件进行分析,了解程序内部函数结构以及机器指令布局。

1.1.2 程序从源代码到机器码的过程

计算机CPU不能直接执行C语言等高级语言代码,而只能执行机器指令。

一个程序通常经历以下过程:

源代码
  |
  ↓
编译器
  |
  ↓
汇编代码
  |
  ↓
机器码
  |
  ↓
ELF可执行文件

其中:

  • 高级语言方便程序员编写;
  • 汇编语言描述CPU执行逻辑;
  • 机器码是CPU最终执行的数据。

例如:
高级语言:

return 0;

经过编译后会转换为汇编指令:

mov eax,0

最终转换为CPU能够识别的机器码。

在网络攻防和逆向分析过程中,研究人员通常面对的是已经编译完成的二进制程序,因此需要通过反汇编技术恢复程序逻辑。

1.1.3 反汇编分析

反汇编(Disassembly)是将机器码转换为汇编代码的过程。

由于二进制程序中没有直接可阅读的源代码,因此反汇编是分析程序行为的重要方法。

通过反汇编,可以获取:

  • 程序包含的函数;
  • 函数之间的调用关系;
  • 跳转指令的位置;
  • 关键地址信息。

本实验中主要使用:

objdump -d pwn1

对pwn1进行反汇编。

通过分析输出结果,可以定位:

  • main函数;
  • foo函数;
  • getShell函数。
    其中:
  • main函数负责程序主要流程;
  • foo函数负责处理用户输入;
  • getShell函数虽然存在,但是正常流程不会调用。

因此,反汇编分析是后续修改程序流程和构造攻击payload的基础。

1.2 x86汇编指令与程序控制流

1.2.1 程序控制流概念

CPU执行程序的本质是不断读取当前地址中的机器指令,然后执行对应操作。

正常情况下,程序按照指令地址顺序执行。

但是函数调用、条件判断和跳转指令会改变CPU执行位置。

例如:

call foo

表示调用foo函数。

jmp address

表示直接跳转到指定地址。

因此,程序的执行流程实际上由大量控制流指令决定。

本实验中的三个实验方法,本质上都是改变程序控制流:

  • 方法一:修改机器指令改变控制流;
  • 方法二:覆盖返回地址改变控制流;
  • 方法三:跳转执行Shellcode改变控制流。

1.2.2 CMP指令

CMP(Compare)指令用于比较两个操作数。

例如:

cmp eax,0

CMP执行:

eax - 0

但是不会保存计算结果,而是修改CPU标志寄存器。

常见标志包括:

  • ZF(Zero Flag):零标志;
  • SF(Sign Flag):符号标志;
  • CF(Carry Flag):进位标志。

后续条件跳转指令会根据这些标志决定是否跳转。

例如:

cmp eax,0
je target

表示:
如果eax等于0,则跳转到target。

本实验要求掌握CMP指令,是因为程序中的条件判断和跳转逻辑通常由CMP和条件跳转共同完成。

1.2.3 JMP指令

JMP(Jump)是无条件跳转指令。

格式:

jmp address

执行后:

CPU直接修改指令指针EIP,使程序跳转到目标地址。
例如:

原流程:
main
 |
foo
 |
return

修改后:
main
 |
getShell

只需要改变跳转目标,就可以改变程序执行路径。

本实验第一部分修改机器指令,就是利用类似原理改变程序流程。

1.2.4 JE和JNE指令

JE:
Jump Equal
表示相等时跳转。
例如:

cmp eax,1
je success

如果比较结果相等,则跳转到success。

JNE:
Jump Not Equal
表示不相等时跳转。
例如:

cmp eax,1
jne error

如果比较结果不相等,则跳转。

JE和JNE通常与CMP配合使用,是分析程序逻辑的重要指令。

1.2.5 NOP指令

NOP:
No Operation
表示空操作。
机器码:

90

执行NOP时:

  • 不改变寄存器;
  • 不修改数据;
  • 不改变程序状态。

NOP常用于:

  • 填充空间;
  • 调整代码位置;
  • 构造NOP滑板(NOP Sled)。

在漏洞利用过程中,NOP可以提高代码执行成功率。

1.3 可执行文件修改与机器码分析

1.3.1 机器码与十六进制表示

CPU执行的是二进制机器码。

为了方便查看,通常使用十六进制表示机器码。

例如:

55 89 e5

对应汇编:

push ebp
mov ebp,esp

因此:

  • 修改机器码;
  • 等价于修改程序执行逻辑。

本实验第一部分要求:

能正确修改机器指令改变程序执行流程。

其本质就是:

找到目标机器码位置 → 修改对应字节 → 改变CPU执行行为。

1.3.2 十六进制编辑器

十六进制编辑器用于直接查看和修改二进制文件。

相比修改源代码:
修改二进制文件可以直接影响最终执行文件。

本实验中:

  1. 使用反汇编定位需要修改的位置;
  2. 使用十六进制编辑器修改对应字节;
  3. 保存文件;
  4. 重新执行程序验证。
    因此:

反汇编负责“寻找位置”,十六进制编辑器负责“修改内容”。

1.3.3 小端序存储方式

x86架构采用小端序(Little Endian)存储方式。
例如:
地址:

0x08048520

内存保存:

20 85 04 08

原因:
低有效字节存储在低地址。

在本实验中:

  • 修改跳转地址;
  • 构造payload;
    都需要考虑小端序。

如果地址顺序错误,即使程序成功跳转,也无法执行正确代码。

1.4 函数调用栈与缓冲区溢出漏洞

1.4.1 函数调用栈

程序调用函数时,会在栈空间中创建对应的栈帧(Stack Frame)。

一个典型函数栈结构:

高地址

返回地址
----------------
保存EBP
----------------
局部变量

低地址

其中:

局部变量

保存函数内部使用的数据。

保存EBP

用于恢复调用环境。

返回地址

保存函数执行结束后应该返回的位置。
返回地址决定程序后续执行流程。

1.4.2 call和ret指令

函数调用:

call foo

执行:

  1. 保存返回地址;
  2. 跳转foo。

函数返回:

ret

执行:

  1. 从栈中读取返回地址;
  2. 跳转。

因此:
如果攻击者修改返回地址:

ret
 |
攻击者指定地址

程序执行流程就会被控制。

1.4.3 缓冲区溢出漏洞

缓冲区溢出(Buffer Overflow)产生原因:

程序向固定大小内存区域写入数据时,没有检查输入长度。

例如:

char buffer[20];

如果输入:

AAAAAAAAAAAAAAAAAAAAAAAAAAAA

超过20字节的数据会覆盖后面的栈空间。

可能覆盖:

  • 保存EBP;
  • 返回地址。

如果覆盖返回地址:

程序执行流程就会改变。

1.4.4 BOF攻击流程

一次完整BOF攻击通常包括:

第一步:寻找漏洞

分析程序中存在危险输入的位置。

本实验:
foo函数。

第二步:分析栈布局

确定:

  • buffer位置;
  • 返回地址位置。

第三步:计算偏移

确定需要多少字节数据才能覆盖返回地址。

第四步:构造payload

形式:

padding + target address

本实验:

padding + getShell地址

第五步:执行攻击

程序执行:

foo
 |
ret
 |
getShell
 |
Shell

证明BOF攻击成功。

1.5 Payload构造与Shellcode注入

1.5.1 Payload构造原理

Payload不是简单的数据输入,而是经过设计的攻击数据。

典型结构:

填充数据 + 控制数据

其中:

填充数据:

用于覆盖目标区域。

控制数据:

用于改变程序执行流程。

本实验中控制数据:

getShell函数地址

1.5.2 Shellcode基础

Shellcode是一段可以直接执行的机器代码。

与调用已有函数不同:

Shellcode攻击流程:

准备Shellcode
        |
        ↓
注入内存
        |
        ↓
改变执行流程
        |
        ↓
CPU执行Shellcode

Shellcode不依赖程序原本存在的函数,因此更加灵活。

1.5.3 Shellcode与本实验关系

本实验第三部分要求:
注入自己制作的Shellcode并运行。

通过该过程可以理解:

  • 代码注入;
  • 控制流转移;
  • CPU执行机器代码。

前三种方法本质都是:

控制程序执行位置
        ↓
执行目标代码

区别在于:

  • 修改机器码:改变已有代码路径;
  • BOF攻击:利用漏洞改变返回地址;
  • Shellcode:执行攻击者提供的新代码。

2. 实验内容

本实验围绕pwn1程序完成三个实验目标:

  1. 手工修改可执行文件中的机器指令,改变程序执行流程,使程序跳转到getShell函数。
  2. 利用foo函数存在的BOF漏洞,构造payload覆盖返回地址。
  3. 制作并注入Shellcode,验证自定义代码执行过程。

3. 实验过程

3.1 实验环境准备

在正式进行逆向分析和漏洞利用之前,需要首先确认实验环境以及目标程序是否满足实验要求。

由于本实验需要对Linux
ELF可执行文件进行反汇编分析、动态调试以及二进制修改,因此需要确认:

  • 当前实验环境配置正确;
  • 实验目标程序存在;
  • 程序具有执行权限;
  • 目标文件格式符合实验要求。

首先查看当前实验环境主机名:

hostname

实验要求所有实验操作截图中的主机名需要符合个人实验环境要求,因此首先确认当前实验环境信息。

随后查看当前目录中的实验文件:

ls

确认实验目标程序存在。

为了确认程序权限以及文件类型,进一步执行:

ls -l pwn1_20242407

以及:

file pwn1_20242407

通过上述命令可以确认实验目标文件存在,并且属于Linux
ELF可执行文件,为后续反汇编和调试分析提供基础。

执行结果如下图所示:

3.2 手工修改可执行文件改变执行流程

本部分实验目标是通过修改pwn1可执行文件中的机器指令,改变程序原本的执行流程,使程序能够调用隐藏函数getShell。

正常情况下,程序执行流程如下:

main
 |
foo
 |
return

其中getShell函数虽然存在于程序内部,但是正常执行路径不会调用。

3.2.1 分析pwn1程序结构

由于实验提供的是已经编译完成的二进制文件,并没有直接提供源代码,因此无法通过源码了解程序逻辑。

为了分析pwn1内部结构,需要首先对程序进行反汇编,将机器码转换为可读的汇编代码。

执行:

objdump -d pwn1_20242407

objdump可以对ELF文件中的代码段进行静态反汇编,通过输出结果查看程序中的函数结构以及机器指令。

通过分析反汇编结果,可以定位main、foo以及getShell等关键函数。

执行结果如下图所示:

image.png

从图3-2中可以观察到程序中的主要函数,为后续定位目标函数和修改程序执行流程提供依据。

3.2.2 定位getShell函数地址

通过前面的反汇编分析,可以确认程序中存在getShell函数。

但是,如果希望程序跳转执行getShell,仅知道函数名称是不够的,还需要获得该函数在程序中的具体地址。

因此使用nm工具查看程序符号信息:

nm -n pwn1_20242407 | grep getshell

通过输出结果可以找到getShell函数对应地址。

该地址将在后续修改机器指令以及构造payload过程中使用。

执行结果如下图所示:
image.png

从图3-3中可以得到getShell函数入口地址,为后续分析函数内容和修改程序流程提供依据。

3.2.3 分析getShell函数功能

获得getShell函数地址后,需要进一步确认该函数具体执行内容。

执行:

objdump -d -M intel pwn1_20242407 | grep -A20 "<getShell>"

通过查看getShell函数汇编代码,可以确认该函数能够执行Shell相关操作。

执行结果如下图所示:
image.png

从图3-4中可以观察到,getShell函数内部调用了system函数,可以执行Shell相关操作。 因此,该函数符合实验目标,可以作为程序修改后的跳转目标。

3.2.4 修改机器指令改变执行流程

确定目标函数后,需要进一步修改程序中的机器指令,使程序执行过程中能够跳转到getShell函数。
由于CPU最终执行的是机器码,而不是汇编代码,因此需要使用十六进制编辑工具直接修改二进制文件。
修改过程中需要注意:

  1. 修改位置必须对应正确的机器指令;
  2. 修改后的跳转地址必须为getShell函数地址;
  3. x86架构采用小端序存储方式,地址写入时需要按照低字节优先方式保存。

修改前的二进制文件详细内容如下图所示:
屏幕截图 2026-09-28 115921(1).png
修改后的二进制文件详细内容如下图所示:

修改完成后保存文件,并重新运行程序验证修改效果。

完成二进制文件修改后,需要重新运行程序验证修改是否成功。

执行:

./pwn1_20242407

通过运行结果判断程序控制流是否已经改变。

如果程序成功进入getShell函数,则说明修改位置和跳转地址均正确。

验证结果如下图所示:

屏幕截图 2026-09-28 120115.png

3.3 利用foo函数BOF漏洞攻击

第二部分实验利用foo函数存在的缓冲区溢出漏洞,通过覆盖返回地址控制程序执行流程。

3.3.1 分析foo函数漏洞

为了利用BOF漏洞,需要首先分析foo函数内部结构。

进入gdb调试环境:

gdb pwn1_20242407

查看foo函数:

disassemble foo

执行结果如下图所示:
屏幕截图 2026-09-28 120352.png

从图3-7中可以观察到foo函数的汇编结构。

函数开始位置:

push %ebp mov %esp,%ebp 

表示函数建立新的栈帧。

随后:

sub $0x38,%esp 

表示程序为局部变量分配0x38字节的栈空间。

继续分析可以发现:

lea -0x1c(%ebp),%eax 

程序将栈中ebp-0x1c位置作为输入缓冲区地址。
最关键的是:

call 0x8048330 <gets@plt> 

说明foo函数使用gets函数接收用户输入。

由于gets函数不会检查输入长度,当输入超过缓冲区大小时,多余数据可能覆盖相邻栈空间,包括保存的返回地址。

因此,可以确定foo函数存在缓冲区溢出漏洞,为后续构造payload覆盖返回地址提供基础。

3.3.2 分析函数栈结构并确定偏移

确定foo函数存在缓冲区溢出后,需要进一步分析函数运行时的栈空间结构。

设置断点:

break foo

运行程序:

run

查看当前栈空间:

x/40wx $esp

通过观察栈中的数据分布,可以计算buffer到返回地址之间的偏移量。

结果如下图所示:
image.png
从图3-8可以观察到foo函数执行时栈中的数据分布。

由于函数调用过程中返回地址保存在栈中,因此攻击目标是找到输入缓冲区与返回地址之间的距离。
结合foo函数中的:

sub $0x38,%esp 

可以确定该函数为局部变量预留了0x38字节空间。 后续需要根据实际栈布局计算覆盖返回地址所需的输入长度,并以此构造payload。

3.3.3 构造payload覆盖返回地址

根据前面的栈空间分析结果,已经确定输入缓冲区与函数返回地址之间的偏移量。

通过foo函数反汇编结果可以发现:

lea -0x1c(%ebp),%eax

该指令表示程序将ebp-0x1c位置作为输入缓冲区。

由于x86函数调用过程中,返回地址保存在ebp+4位置,因此输入缓冲区到返回地址之间的距离为:

offset = (ebp+4)-(ebp-0x1c)
       = 0x1c + 4
       = 0x20
       = 32字节

因此,需要填充32字节数据才能覆盖函数返回地址。

同时,根据前面对getShell函数的分析,可以得到目标函数地址:

getShell函数地址:0x0804847d

由于x86架构采用小端序存储方式,因此该地址写入payload时需要转换为:

\x7d\x84\x04\x08

因此,本实验构造的payload结构如下:

32字节填充数据 + getShell地址

其中:

  • 填充数据用于覆盖buffer,并使输入位置到达返回地址;
  • getShell地址用于覆盖原始返回地址,使程序执行ret指令时跳转到getShell函数。

最终payload如下:

"A"*32 + "\x7d\x84\x04\x08"

实际执行命令:

python3 -c 'import sys;sys.stdout.buffer.write(b"A"*32+b"\x7d\x84\x04\x08")'

执行结果如下图所示:
屏幕截图 2026-09-29 222653.png

从图3-9可以观察到,payload由32字节填充数据和getShell函数地址组成,与前面对函数栈结构以及返回地址偏移的分析结果一致。
该payload将在后续步骤中输入目标程序,用于覆盖函数返回地址。

3.3.4 验证BOF攻击结果

完成payload构造后,将攻击字符串输入目标程序进行验证。

如果返回地址覆盖成功,foo函数执行ret指令时,程序执行流程将发生改变。

正常执行流程:

foo
 |
ret
 |
main继续执行

攻击成功后的执行流程:

foo
 |
ret
 |
getShell
 |
Shell

执行结果如下图所示:
屏幕截图 2026-09-28 120732.png

从图3-10可以观察到,程序成功进入Shell环境,并能够正常执行系统命令。
输入:

whoami

返回当前用户:

kali

随后输入:

id

返回当前用户ID以及用户组信息。

实验结果表明:

  • payload成功覆盖了foo函数返回地址;
  • 返回地址被修改为getShell函数地址;
  • 程序执行流程被成功控制;
  • BOF攻击达到实验目标。

3.4 Shellcode注入实验

前两个实验方法都是利用程序中已经存在的代码实现控制流改变。

而Shellcode注入不依赖程序已有函数,而是将攻击者编写的机器代码注入内存,并控制程序执行该代码。

3.4.1 制作Shellcode

Shellcode是一段可以直接执行的机器代码。

与前面调用程序内部getShell函数不同,Shellcode注入方式不依赖目标程序已有代码,而是由攻击者自行编写机器代码,并将其注入目标内存区域执行。

本实验中,需要首先将目标功能转换为CPU能够识别的机器指令,并以字节形式保存。

Shellcode示例如下:

shellcode = ( b"\x31\xc0..." )

本实验中编写的shellcode具体内容如下图所示:
image.png

从图3-11中可以看到,Shellcode由多组十六进制字节组成,这些字节对应CPU可以直接执行的机器指令。

完成Shellcode制作后,需要进一步构造注入payload,使程序能够跳转到Shellcode所在位置。

3.4.2 构造payload并执行Shellcode

完成Shellcode制作后,需要将Shellcode加入攻击payload,使程序执行流程能够跳转到Shellcode所在位置。

Shellcode注入payload通常由以下几个部分组成:

填充数据 + 返回地址 + NOP滑板 + Shellcode

其中:

  • 填充数据用于覆盖原有栈空间;
  • 返回地址用于改变程序执行位置;
  • NOP滑板用于提高跳转到Shellcode的成功概率;
  • Shellcode为最终执行的机器代码。

本实验中payload结构如下:

payload = b"A"*32
payload += b"\xa0\xcf\xff\xff"
payload += b"\x90"*100
payload += shellcode

其中:

A*32

用于填充缓冲区。

\x90

对应x86架构中的NOP指令,用于构造NOP滑板。

最终追加Shellcode,使程序跳转后执行自定义机器代码。

payload构造过程如下图所示:

完成payload构造后,将其输入目标程序进行执行。

通过gdb查看Shellcode注入后的内存区域:

x/120bx 0xffffcfa0

执行结果如下图所示:


从图3-13中可以观察到,目标内存区域中存在大量:

0x90

说明NOP滑板已经成功写入内存。

随后可以观察到Shellcode对应机器码已经位于目标内存区域。
继续执行程序后输出:

Hi!

说明CPU已经成功执行注入的Shellcode,实验目标完成。

4. 问题及解决方案

问题1:修改机器指令后程序未成功跳转到getShell函数

问题描述

在进行手工修改可执行文件实验时,完成机器码修改后重新运行程序,程序没有按照预期进入getShell函数。

原因分析

通过检查修改过程发现,问题主要出现在目标地址处理过程中。

由于x86架构采用小端序存储方式,函数地址不能直接按照常规十六进制形式写入二进制文件,而需要按照低字节在前的顺序保存。

如果地址格式错误,程序执行跳转指令时会读取错误地址,从而导致程序无法进入目标函数。

解决方案

首先通过符号分析重新确认getShell函数地址:

nm -n pwn1_20242407

获得:

0x0804847d

随后按照小端序转换为:

\x7d\x84\x04\x08

重新修改对应机器指令后,再次运行程序进行验证。

最终程序成功跳转到getShell函数。

问题2:Shellcode调试过程中无法直接判断执行状态

问题描述

在进行Shellcode注入实验时,使用gdb调试程序过程中,调试器无法像普通函数一样直接显示Shellcode函数名称。

原因分析

Shellcode属于运行时动态注入的机器代码,并不是程序编译阶段存在的函数,因此程序符号表中不存在对应信息。
因此,gdb无法通过函数名称定位Shellcode执行位置。

解决方案

通过查看Shellcode注入后的内存区域,分析其中是否存在NOP滑板以及Shellcode机器码:

x/120bx 0xffffcfa0

观察内存中的:

0x90

等NOP指令以及Shellcode对应机器码。
随后继续执行程序:

continue

结合程序输出结果判断Shellcode是否成功执行。

最终确认Shellcode已经成功注入并运行。

5. 学习感悟、思考等

通过本次“逆向破解与BOF”实验,我对程序执行过程以及漏洞利用方法有了更加深入的理解。

在实验开始之前,我对于程序安全问题的理解更多停留在较高层面的概念,例如输入验证不足可能导致安全问题。但是通过本次实验,我认识到程序最终执行的是CPU能够识别的机器指令,程序运行过程中的每一次函数调用、跳转以及返回,本质上都依赖底层的地址和控制流。

在第一个实验方法中,通过修改可执行文件中的机器指令改变程序执行流程,使我理解了程序行为并不是固定不变的。程序最终执行结果取决于内存中的指令内容以及CPU当前执行位置。如果攻击者能够修改关键指令或者跳转地址,就可能改变程序原本设计好的执行逻辑。因此,在软件开发过程中,保护程序执行流程和避免非法修改具有重要意义。

在第二个实验方法中,通过利用foo函数中的缓冲区溢出漏洞完成BOF攻击,我对函数调用栈有了更加直观的认识。之前对于栈、返回地址等概念的理解主要停留在理论层面,而通过实际调试,我观察到了局部变量、保存寄存器以及返回地址在内存中的具体布局。

实验过程中,BOF攻击并不是简单输入大量字符,而是需要经过多个步骤:

  1. 分析目标函数是否存在漏洞;
  2. 确定缓冲区和返回地址之间的距离;
  3. 构造符合要求的payload;
  4. 控制程序返回位置。

这一过程让我认识到,漏洞利用实际上是建立在对程序运行机制深入理解的基础上的,而不是简单依靠某个固定攻击字符串。

在Shellcode注入实验中,我进一步理解了代码注入的基本思想。与前两种方法利用程序中已有代码不同,Shellcode注入尝试让程序执行攻击者提供的新代码。这让我认识到,程序漏洞的危险性不仅体现在数据被破坏,更重要的是攻击者可能进一步控制程序执行权限。

同时,通过本次实验,我也认识到了调试工具在安全分析中的重要作用。在实际实验过程中,并不是所有操作都能够一次成功,例如机器码修改可能导致程序无法正常执行,BOF攻击可能由于偏移计算错误而失败,Shellcode执行过程中也可能出现地址无法识别等情况。

面对这些问题,需要结合反汇编结果、调试信息以及程序运行现象逐步分析原因,而不是盲目修改参数。这种分析问题和解决问题的过程,提高了我使用Linux工具进行程序分析的能力。

从防御角度来看,本实验中的漏洞主要来源于程序设计过程中缺少必要的安全检查。例如:

  • 对用户输入长度缺少限制;
  • 使用不安全的输入函数;
  • 缺少有效的内存保护机制。

因此,在实际软件开发过程中,需要重视安全编码规范,加强输入验证,并合理使用现代操作系统提供的安全保护机制。

通过本次实验,我不仅掌握了ELF分析、反汇编、BOF攻击以及Shellcode注入等技术,也更加理解了攻击与防御之间的关系。网络安全不仅需要了解攻击方法,更需要从攻击过程反向分析系统存在的问题,并设计更加安全可靠的软件。

参考资料

[1] 《深入理解计算机系统(Computer Systems: A Programmer's Perspective)》

[2] 《Linux系统编程(Linux System Programming)》

[3] Intel® 64 and IA-32 Architectures Software Developer’s Manual

[4] 《实验一 逆向破解与BOF》

posted @ 2026-10-01 14:48  syz_serien  阅读(9)  评论(0)    收藏  举报