漏洞狩猎与利用 计算器体系结构 1001 x86-64 汇编课程

Architecture 1001: x86-64 Assembly

课程 https://p.ost2.fyi/courses/course-v1:OpenSecurityTraining2+Arch1001_x86-64_Asm+2021_v1/about
要求:必须熟悉 C 语言编程
推荐C 语言编程课程:https://www.learn-c.org/https://www.edx.org/certificates/professional-certificate/dartmouth-imtx-c-programming-with-linux
课程路线图:https://ost2.fyi/OST2_LP_Vulns_Exploits.pdf

1.环境准备

创建 Broadcom 帐户并登录,下载vmware虚拟机
https://www.vmware.com/products/desktop-hypervisor/workstation-and-fusion

选择 Windows 10专业版,而非其他版本
https://drive.google.com/file/d/1oSyhape3oPsBj07OYxAPtsT7KvDw8WCn/view

建议您仅使用 Windows 10 系统上课。如果您使用 Windows 11,则需要自行调试遇到的任何问题,因为目前该配置不受支持。

Windows VM on Windows Host OS 环境准备教学:https://youtu.be/ZPE9Yva_tys?si=S04VvgmSC4BR9fkN

解压缩文件,将其移动到桌面,然后打开 Visual Studio 解决方案文件 (Arch1001_x86-64_asm.sln)

下载课程幻灯片:https://gitlab.com/opensecuritytraining/arch1001_x86-64_asm_slides_and_subtitles

2.介绍

2.1 为什么要学习汇编语言?

课程视频:https://youtu.be/jAxtQ2k4Naw?si=1FPNL7UwzjyRjimR

2.2 关于这门课程

课程视频:https://youtu.be/EALp2iziAIQ?si=uhmd7PmQTtIsLO_n

可选教程:"Introduction to 64 Bit Assembly Programming for Linux and OS X: Third Edition" by Ray Seyfarth

https://www.amazon.com/gp/product/1484921909/ref=as_li_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=1484921909&linkCode=as2&tag=opensecuinfo-20&linkId=EPDXM3AQYTVSJEET

z-library 搜索(ISBN-13):978-1484921906
https://github.com/z-libraryopp/z-libraryopp.github.io

《统计结构:恶意软件指纹识别与分类分析》:据统计,仅 14 条汇编指令就占了代码的 90%
http://www.blackhat.com/presentations/bh-usa-06/BH-US-06-Bilar.pdf

x86-64 指令频率 pi 图:
https://web.archive.org/web/20221006192057/https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.407.5071&rep=rep1&type=pdf

英特尔最初在迈向 64 位时,曾希望彻底抛弃 x86 架构。这就是 IA64(英特尔 64 位架构),也被称为 Itanium(安腾)。然而,AMD 决定自己将 x86 扩展到 64 位,从而诞生了 AMD64 架构。随着 Itanium 的市场普及极其缓慢,英特尔最终决定咬紧牙关,向 AMD 购买了 64 位扩展技术的授权。
在英特尔的手册中,你会看到 64 位扩展技术被称为 IA32e、EM64T 或 Intel 64(但绝不会叫 IA64——再次强调,IA64 指的是 Itanium,那是一套完全不同的架构)。
在英特尔的手册中,这项技术拥有许多不同的称呼,比如 IA32e、EM64T 以及 Intel 64。

你有时可能会看到微软或某些 Linux 发行版将它称为 amd64 或 x64。
而在本门课程中,我们将统一采用 x86-64 这个称呼。

那么,x86-64 究竟应用在哪些领域呢?你大概已经知道,它主要用于需要高计算能力的场景,例如个人电脑(PC)、服务器,甚至超级计算机。极大概率,你现在用来观看本课程的这台电脑就是一台 x86-64 机器。不过,基于 ARM 架构的系统——比如微软的 Surface,或是苹果搭载 M1 芯片的 Mac(我曾参与过该芯片 SecureBoot 安全启动系统的设计)——正在 PC 领域异军突起,给英特尔带来巨大的竞争压力。

英特尔确实有一些更专注于功耗受限设备(如嵌入式系统)的芯片,但这些只占英特尔芯片出货量极小的一部分。

同一套C语言源代码在所有反编译软件中的总体脉络是差不多了,至于部分汇编代码目前为止还不清楚它们是干嘛的,属于实际情况。

我认为,只要掌握大约 20 到 30 条核心指令(不算变体),就足够让你在大部分时候都极少需要去查阅参考手册了

2.3 可选复习:二进制到十六进制到十进制

十进制:00
二进制:0000b
十六进制(Hex):0x00
其他用工具转换即可

2.4 可选复习:二进制补码负数

C 语言:“有符号”类型可以表示正值或负值,“无符号”类型只能表示正值
例如:unsigned char与signed char(用谷歌的gemini解释一下即可)
负值用其正值的“二进制补码”表示。二进制补码的计算方法是将所有位翻转,然后加 1

2.5 复习:C 数据类型大小

取自 2020 年 11 月 Intel 手册 ,Vol 1 Sec 4.1 - page 4-1(PDF每页下方有该标志):显示了基本 C 数据类型的大小
https://ost2images.s3.amazonaws.com/PDFs/325462-sdm-vol-1-2abcd-3abcd.pdf
图片

“word”(字)这个术语最初指的是当 x86 还是 16 位架构时,英特尔原生的 16 位数据大小。因此,当它扩展到 32 位时,该大小就被称为“double word”(双字)。这种“双字”的称谓随后在 Windows 编程中被采纳为“DWORD”数据类型名称。同样地,对于 64 位,“QWORD”(四字)也经常被用于 Windows 系统中。

2.6 背景知识:字节序

https://youtu.be/tPJgoVxqlnU?si=_ymoQUdaJ6zic5XH

视频对应的幻灯片:https://gitlab.com/opensecuritytraining/arch100x_slides_and_subtitles

书写或显示值:0x1234567887654321
书写或显示值在内存中存放为,内存小端序:现在内存地址最小的在左上角,值为0x21,读取书写或显示出来就是最右侧;而最大的内存地址的值0x12,读取书写或显示出来就是最左侧
书写或显示值在寄存器中存放为,大端序:0x1234567887654321

注意Intel 手册 Vol. 1 4-1:https://ost2images.s3.amazonaws.com/PDFs/325462-sdm-vol-1-2abcd-3abcd.pdf
字节序适用于内存,不适用于寄存器;字节序适用于字节,不是位
图片

图片

如果改变字节的显示大小,这个也很好理解
书写或显示值:0x1234567887654321(小端序放入内存4个字节为一个整体即0x87654321)
如果你改成4个字节为整体来显示,它首先要把值放到内存里面然后再显示出来,0x87654321为一个整体放到最小内存地址的地方,0x12345678继续放
而寄存器为大端序(与书写或显示值保持一致):即0x1234567887654321
图片

改成4个字节为整体来显示,源代码中的变量的值即为书写或显示值
图片

基于以上理解,对于所有的反汇编软件而已,只需要关注书写或显示值是什么,几个字节为整体来显示,即可区分它们不同的大小端风格。

比如GDB,你要求它已2,4,8字节为整体,它就表现出了大端序的风格:你把0x55,0x48从内存取出来,放到书写或显示值中为0x4855(因为从内存读取到显示值为小端序),然后再对比2,4,8字节为整体的显示风格(所谓的大小端风格就出来了)
图片

3.计算机寄存器

3.1 内存层次结构

教学视频:https://youtu.be/Zph6GkevMzo?si=_IHWYgY5urjjTZ7h

幻灯片:https://gitlab.com/opensecuritytraining/arch100x_slides_and_subtitles

3.2 x86-64 通用寄存器

教学视频:https://youtu.be/T9FUYHrnLUM?si=G3Ripj1rufABhRdH

x86-64 寄存器速查表:https://ost2images.s3.amazonaws.com/Arch101_x86-64_Asm/CheatSheet_x86-64_Registers.pdf

3.3 英特尔推荐的寄存器约定

教学视频:https://youtu.be/_HOfsOFhFxw?si=LGN6CyjfPafTG-XR

Intel Arch v1 Section 3.4.1 - General-Purpose Registers, page 3-11

微软编译器寄存器约定: https://docs.microsoft.com/en-us/cpp/build/x64-software-conventions?view=msvc-160

这些是英特尔给编译器开发者(以及汇编手写代码者)的建议。寄存器并不强制要求必须这样使用,但如果你看到它们被这样用了,就会明白其中的缘由。不过我对部分描述做了简化
RAX - 存储函数的返回值
RBX - 指向数据段的基址指针
RCX - 用于字符串和循环操作的计数器
RDX - I/O(输入/输出)指针
RSI - 字符串操作的源索引指针(Source Index)
RDI - 字符串操作的目的索引指针(Destination Index)
RSP - 栈顶指针(Stack Pointer)
RBP - 栈帧基址指针(Base Pointer)
RIP - 指向下一条待执行指令的指针(即“指令指针”,Instruction Pointer)

4.你的第一条指令:空操作 (NOP)

posted @ 2026-07-25 19:09  sec875  阅读(2)  评论(0)    收藏  举报