当前位置: 首页 > news >正文

学习pwn需要的基本汇编语言知识

🙋‍♀️ 博主介绍:暗流者
⭐ 本期精彩:学习pwn需要的基本汇编语言知识
🏆 热门专栏:带你从C语言和汇编角度入门pwn
🚀 专栏亮点:零基础友好 | 实战案例丰富 | 循序渐进教学 | 代码详细注释
💡 学习收获:从语言角度入门pwn,为您的pwn之路打好基础

🔥 如果觉得文章有帮助,别忘了点赞👍 收藏⭐ 关注🚀,你的支持是我创作的最大动力!

目录

前言:

一、寄存器架构

二,基础指令

一、数据传送指令

二、算术运算指令

三、位操作指令

四、控制转移指令

五、栈操作指令

六、系统调用指令对比

七、核心数据定义指令

八、64位专属指令

三.构建内存空间

一.寄存器构建

二、函数调用中的协作流程

PUSH 执行流程(以 32位 push eax 为例):

POP 执行流程(以 32位 pop ebx 为例):

call 指令

ret 指令




 

前言:

我计划用几次用C语言和汇编语言的角度讲完整个pwn的基础知识点,会涉及32位汇编和64位汇编的讲解,但是在pwn中的gdb工具分析时,需要你认识内联汇编(支持C语言和汇编出现在同一个程序中),内联汇编没什么新的知识点,但是有些东西还是需要你知道

C语言方面的话并不需要你的能力很强,懂得一些基本的操作(数组,指针,结构),数据结构(链表,栈,树,图)等等,总之我会从C语言的角度去说PWN中的一些基本结构

这是第一天,我将从汇编语言的基础知识点出发,因为可能很多人学汇编语言是学习的16位汇编,但是pwn题目中都是32位和64位汇编,所以在这里我就简单讲一下32位和64位汇编,一些汇编语言的基础操作就不讲了,我只讲一下32位和64位汇编不同的地方,这里我讲一些pwn中常见的汇编知识

一、寄存器架构

32位(x86)

  • 通用寄存器(8个): EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP

  • 段寄存器: CS, DS, ES, FS, GS, SS

  • 特殊寄存器: EIP(指令指针), EFLAGS(状态标志)

64位(x86-64)

  • 扩展通用寄存器(16个): RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, R8-R15(新增8个64位寄存器)

  • 保留部分寄存器: 段寄存器(除FS/GS外)基本弃用

  • 特殊寄存器: RIP(64位指令指针), RFLAGS

二,基础指令
一、数据传送指令
指令32位示例64位示例功能说明
MOVmov eax, 10mov rax, 10数据传送
LEAlea esi, [ebx+ecx*4]lea rsi, [rbx+rcx*4]地址计算(不访问内存)
XCHGxchg eax, ebxxchg rax, rbx交换数据
MOVZXmovzx eax, byte [mem]movzx rax, byte [mem]零扩展传送
MOVSXmovsx eax, byte [mem]movsx rax, byte [mem]符号扩展传送
二、算术运算指令
指令通用示例功能说明
ADDadd eax, 10 / add rax, 10加法
SUBsub ebx, ecx / sub rbx, rcx减法
INCinc dword [mem]自增(不影响CF标志)
DECdec esi自减(不影响CF标志)
MULmul ecx无符号乘法(EDX:EAX = EAX * ECX)
IMULimul eax, ebx有符号乘法
DIVdiv ecx无符号除法(EAX = EDX:EAX / ECX)
三、位操作指令
指令通用示例功能说明
ANDand eax, 0Fh按位与
ORor ebx, 80h按位或
XORxor eax, eax按位异或(常用清零)
NOTnot ecx按位取反
SHLshl edx, 4逻辑左移
SHRshr eax, 1逻辑右移
SALsal ebx, cl算术左移(同SHL)
SARsar ecx, 3算术右移(保留符号位)
四、控制转移指令
指令32位示例64位示例功能说明
JMPjmp labeljmp label无条件跳转
CALLcall funccall func函数调用
RETretret函数返回
JE/JZje targetje target相等/为零时跳转
JNE/JNZjne targetjne target不相等/非零时跳转
LOOPloop labelloop labelECX/RCX减1,非零跳转
五、栈操作指令
指令32位示例64位示例功能说明
PUSHpush eaxpush rax入栈(ESP/RSP递减)
POPpop ebxpop rbx出栈(ESP/RSP递增)
PUSHApusha✘ 64位移除保存所有通用寄存器
POPApopa✘ 64位移除恢复所有通用寄存器
ENTERenter 16, 0极少使用创建栈帧
LEAVEleaveleave销毁栈帧
六、系统调用指令对比
架构指令参数传递方式
32位int 0x80EAX=调用号, EBX/ECX/EDX/ESI/EDI/EBP=参数
64位syscallRAX=调用号, RDI/RSI/RDX/R10/R8/R9=参数
七、核心数据定义指令
指令全称位数功能说明示例
DBDefine Byte8位定义字节数据num DB 0x55
DWDefine Word16位定义字(2字节)数据buffer DW 1024
DDDefine Doubleword32位定义双字(4字节)数据pointer DD 0x8040000
DQDefine Quadword64位定义四字(8字节)数据addr64 DQ 0x7FFFFFFFFFFF
DTDefine Ten Bytes80位定义10字节数据(浮点专用)float DT 3.1415926535
八、64位专属指令
  1. RIP相对寻址

    asmlea rax, [rip + label]  ; 动态计算地址(位置无关代码)

  2. SWAPGS

    asmswapgs                   ; 切换内核GS寄存器(系统编程)

  3. SYSCALL/SYSRET

    asmsyscall                  ; 快速系统调用
    sysret                   ; 快速系统返回

三.构建内存空间
一.寄存器构建

1.如何构建一段栈空间,需要这三个ebp,esp,ss寄存器

寄存器全称位数核心功能
ESPExtended Stack Pointer32位栈顶指针,始终指向当前栈顶位置
EBPExtended Base Pointer32位栈帧基址,指向当前函数栈帧起点
SSStack Segment16位栈段寄存器,定义栈内存的基地址

高地址 +-----------------+ | 返回地址 | +-----------------+ | 保存的RBP | <-- RBP (当前帧基址) +-----------------+ | 局部变量 | | ... | +-----------------+ | 额外参数 | +-----------------+ 低地址 <-- RSP (栈顶)

二、函数调用中的协作流程

1. 函数进入序言 (Prologue)

asm; 保存调用者的栈帧基址
push ebp        ; ESP自动减4,旧EBP入栈
​
; 建立新栈帧
mov ebp, esp    ; EBP指向当前栈顶(即旧EBP位置)
​
; 分配局部变量空间
sub esp, 16     ; 分配16字节局部变量区

2. 函数内栈操作

asm; 访问参数(假设32位cdecl调用约定)
mov eax, [ebp+8]  ; 第一个参数(返回地址占4字节)
​
; 访问局部变量
mov [ebp-4], eax  ; 存储到第一个局部变量

3. 函数退出尾声 (Epilogue)

asm; 恢复栈指针(释放局部变量)
mov esp, ebp    ; ESP回到栈帧起点
​
; 恢复调用者栈帧
pop ebp         ; 恢复旧EBP,ESP自动加4
​
; 返回(清理参数由调用者负责)
ret

三,栈对齐的问题(32位和64位都需要)

栈对齐(Stack Alignment)是x86架构中极易被忽视却至关重要的机制,尤其在64位系统中直接关系到程序稳定性和性能。本文将通过原理分析、实例演示和解决方案全面解析这一核心问题。

  • 函数调用前RSP必须16字节对齐

  • 调用指令call会压入8字节返回地址

asm; 正确对齐示例
sub rsp, 24   ; 24+8(返回地址)=32 → 16字节对齐
call func
add rsp, 24

4.pop和push指令

pop和push指令用于压栈和出栈

PUSH 执行流程(以 32位 push eax 为例)
  1. ESP 减 4(栈指针下移) ESP = ESP - 4

  2. 将 EAX 值写入 ESP 指向的地址 [ESP] = EAX

  3. 更新 EFLAGS 寄存器(不影响标志位)

plaintext

执行前:          执行后:
高地址           高地址
┌─────────┐       ┌─────────┐ 
│         │       │  EAX值  │ ← ESP
├─────────┤       ├─────────┤
│         │ ← ESP │         │
└─────────┘       └─────────┘
低地址           低地址
POP 执行流程(以 32位 pop ebx 为例)
1. 读取 ESP 指向的值`EBX = [ESP]`
2. ESP 加 4(栈指针上移)`ESP = ESP + 4`
3. 更新 EFLAGS 寄存器(不影响标志位)

5.ret和call指令

call 指令

  • 作用call 指令将当前的 IP(指令指针)或 CS:IP(段寄存器和指令指针)压入栈中,然后跳转到指定的函数地址,从而实现子程序的调用。

  • 执行流程

    - 1. 将当前的 IP 或 CS 和 IP 压入栈中(相当于 `push IP`)。2. 跳转到目标地址(相当于 `jmp near ptr 标号`)。
    - **示例**:`call 标号`(近转移)相当于执行 `push IP` 和 `jmp near ptr 标号` 。

ret 指令

  • 作用ret 指令用于从子程序返回到调用点,它通过从栈中弹出返回地址,并将其加载到 IP 寄存器中,从而恢复程序的执行流程。

  • 执行流程

    - :1. 从栈中弹出返回地址(相当于 `pop IP`)。2. 将返回地址加载到 IP 寄存器中,程序继续执行。
    - **示例**:`ret` 指令相当于执行 `pop IP`,并更新 SP 寄存器(栈指针)。

    总结

  • 本博客将从C语言与汇编语言的角度系统讲解PWN基础,涵盖32位和64位汇编差异、寄存器架构、常用指令及栈操作等核心内容,帮助读者深入理解程序执行机制。

http://www.lryc.cn/news/596572.html

相关文章:

  • 快速了解pandas库
  • Unity之C# 脚本与Unity Visual Scripting 交互
  • 嵌入式开发学习(第三阶段 Linux系统开发)
  • Model Control Protocol 使用MCP进行各种任务适配,调用工具和资源进行客户端开发
  • 基于AD7147电容触摸芯片与STC12C5A60S2单片机方案
  • SQL基础④ | 多表查询篇
  • AG32 mcu+cpld 联合编程(概念及流程)
  • OpenMVG OpenMVS 安装全流程常见问题与解决方法总结
  • 学习软件测试的第十九天
  • imx6ull-系统移植篇18——linux顶层 Makefile(下)
  • API是什么,如何保障API安全?
  • Springboot和postman的使用
  • XSS内容分享
  • 智能泵房监控系统:物联网应用与智能管理解决方案
  • Qt中QObject类的核心作用与使用
  • Qt 事件处理机制深入剖析
  • List<UserInfo> list = new ArrayList<>();为什么要这样创建数组?
  • 如何用keepAlive实现标签页缓存
  • 从 COLMAP 到 3D Gaussian Splatting
  • 滑动窗口经典问题整理
  • langchain4j之RAG 检索增强生成
  • Linux操作系统之线程(六):线程互斥
  • TCP day39
  • 质量即服务:从测试策略到平台运营的全链路作战手册
  • 重生学AI第十九集:VGG16的使用以及模型的保存与加载
  • 【期末考试复习】计算机组成原理 - 直接补码阵列乘法器
  • 【接口自动化】pytest的基本使用
  • CSS+JavaScript 禁用浏览器复制功能的几种方法
  • web登录页面
  • 黑马点评练习题-给店铺类型查询业务添加缓存(String和List实现)