当前位置: 首页 > 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.dtcms.com/a/292121.html

相关文章:

  • 漫画版:细说金仓数据库
  • LangGraph基础教程
  • 理解后端开发中的API设计原则
  • 哈希算法(Hash Algorithm)
  • 2025乐彩V8影视系统技术解析:双端原生架构与双H5免签封装实战 双端原生+双H5免签封装+TV级性能优化,一套代码打通全终端生态
  • Visual Studio Code 远端云服务器开发使用指南
  • gflags使用
  • Java 大视界 -- Java 大数据在智能交通自动驾驶车辆与周边环境信息融合与决策中的应用(357)
  • 新手向:基于Python的桌面便签与待办事项管理工具
  • [ARM]MDK出现报错error: A\L3903U的解决方法
  • Gradio, Streamlit, Dash:AI应用开发的效率之选
  • C# 析构函数
  • Unity中,Panel和 Canvas的区别
  • 矩阵中QR算法分解简介和基于Eigen库使用示例
  • Qt Creator集成开发环境使用指南
  • React Three Fiber 实现昼夜循环:从光照过渡到日月联动的技术拆解
  • “闪存普惠”如何一步到位? 华为在商业市场破题
  • 华为视觉算法面试30问全景精解
  • Node.js:RESPful API、多进程
  • GoLang教程006:循环控制语句
  • HTML结构解析
  • Python 图像处理库Pillow
  • 智能制造——解读52页汽车设计制造一体化整车产品生命周期PLM解决方案【附全文阅读】
  • 中小制造企业如何对技术图纸进行管理?
  • Dockerfile 详解
  • 客户案例 | Jabil 整合 IT 与运营,大规模转型制造流程
  • 生存分析机器学习问题
  • 跨越语言壁垒!ZKmall开源商城多语言架构如何支撑电商全球化布局
  • Web3与区块链如何革新网络安全——走在前沿
  • 「Linux命令基础」用户管理