漏洞狩猎与利用 计算器体系结构 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.环境准备
- 实验室环境 x86-64 Windows :
https://p.ost2.fyi/courses/course-v1:OpenSecurityTraining2+Lab_Setup_x86-64_Windows+2021_v1/about
创建 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
-
在 Windows 虚拟机中安装 Visual Studio:也就是 Dbg 1001的课程
https://p.ost2.fyi/courses/course-v1:OpenSecurityTraining2+Dbg1001_VS_IDE+2021_v1/about -
从以下地址下载课程源代码
https://gitlab.com/opensecuritytraining/arch1001_x86-64_asm_code_for_class
解压缩文件,将其移动到桌面,然后打开 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
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)

浙公网安备 33010602011771号