为什么要写这篇教程呢?
本文章仅提供学习,切勿将其用于不法手段!
因为想要成为一名白帽黑客,汇编语言是必须要掌握的!
无论是二进制漏洞挖掘,还是逆向工程!汇编语言,都是硬性基础之一!当然,你还需要学会C语言!为什么要学会C语言呢?IDA软件 会将 二进制代码 翻译成 汇编语言 和 C语言 !
你不会汇编语言,不会C语言,想要进行逆向工程,以及更深层次的 二进制漏洞挖掘,是非常困难!如果你希望挖掘 二进制漏洞 ,你还要学会 代码审计 !
你必须看得懂,汇编语言代码 和 C语言代码,这是硬性要求!
想要参加CTF竞赛,汇编语言 和 C语言 都是重要的底层基础知识。
今天,我们来简单讲一下,在进行汇编语言编程时,会经常用到的相关汇编指令。
首先,数据传送指令,是我们首先会接触的。
MOV 指令 用于进行数据传送,我们可以在寄存器之间进行数据传送,也可以在寄存器和内存之间进行数据传送!
我们需要知道,在64位环境的保护模式下,入栈出栈,数据传递等操作,通常都是以8字节为单位的!
示例:MOV RAX,[RBX+0100H]
示例:MOV RAX,RBX
MOV RAX,RBX 这条汇编指令
我们简单一些理解,就是将 RBX寄存器中的内容,传送(复制)到 RAX寄存器中去。
这点上,类似于C语言中的变量赋值,如 long number1=100,number2=200; number1=number2;
我们接下来,再来说一下,MOV RAX,[RBX+0100H]
[] 的作用是间接寻址,什么是间接寻址呢?请自行百度。
MOV RAX,[RBX+0100H] 这条指令的作用是,将 RBX中的内存地址 + 0100H 偏移量 而得到的内存地址上的内容(8字节)传递到 RAX 寄存器中去!
MOV 这条汇编指令,作用还是非常大的!、
MOV RBP,RSP 这条指令的作用是,将 RSP 寄存器中的内容,传递到RBP寄存器中去!
RSP寄存器,被称为栈指针寄存器,它永远指向内存中当前栈结构的当前栈顶位置(当前栈顶的内存地址)!栈结构,是会发生变化的,所以,我们明确的说明了,当前栈结构 和 当前栈顶的内存地址!PUSH 指令,会让当前栈顶位置下移8个字节(64位环境下),POP指令,会让当前栈顶位置上移8个字节(64位环境下)!
PUSH 指令的原理是,先将RSP寄存器的内容自减8个字节(64位环境下),然后将数据传递到RSP寄存器内容所指向的内存地址空间上去(8个字节)。
POP指令的原理是,先将RSP寄存器的内容所指向的地址空间上的数据传递到指定的寄存器中,然后将RSP寄存器的内容自增8个字节(64位环境下)。
RBP寄存器,被成为栈基址寄存器,用于存放当前栈结构的基址!
在上面,我们强调了,当前栈结构 和 当前栈顶地址 !我们应该清晰地认知到,栈结构,会发生变化!POP RBP 、MOV RBP,RSP 、 MOV RSP,RAX 等汇编指令,都会改变栈结构 和 栈顶地址!我们把 MOV RBP,RAX 或 MOV RSP,RAX 等指令的操作行为,称为 栈迁移 !
我们需要知道,当我们为了实现栈迁移,而去改变了RSP寄存器的内容,那么对应的,我们也需要正确地去对应改变RBP寄存器中的内容!我们需要维护栈平衡!否则,程序执行可能会遭遇崩溃情况!也就是说,如果我们进行栈溢出测试时,如果我们改变了RSP寄存器的内容,那么我们也同样需要改变RBP寄存器的内容,例如 使用 POP RBP 这条指令!
虽然,我们经常使用 覆盖 当前栈结构 中 函数返回地址 的方式去改变指令的执行走向(这里通常会使用到 ret 这条汇编指令,它的作用是 将当前栈中存放的函数返回地址 传递到 RIP 寄存器中),但是,我们同样不能忽视,RSP 寄存器 和 RBP 寄存器 的重要作用!
为什么我们要重视 RSP 和 RBP 这两个寄存器呢?
因为 RSP 和 RBP 寄存器,直接影响着 当前栈结构 和 当前栈定地址 !
(未完待续)