Skip to main content

x64汇编

掌握汇编语言对于恶意软件开发有着很大的作用,例如可以编写自定义 Shellcode、在木马加载器中插入汇编代码以实现混淆以及底层的指令操作等。


基本概念

汇编语言是我们可以用来为给定 CPU 编写程序的最底层的编程语言,汇编可以被翻译为 CPU 操作码,即 CPU 可以直接执行的机器码。 通常,汇编指令与操作码具有 1:1 的关系,但在 C 等高级语言中情况并非如此,它们有多种方法将书面代码编译或转换为机器代码。接下来,我们分别来讨论汇编中设计的名词与概念。


字节顺序

字节顺序指的是数据在计算机内存中的存储方式。大端是指数据的最高有效字节 (最左端) 存储在低的内存地址中,最低有效位存储在高的内存地址中。字节顺序只适用于字节,而非

image.png

如上图所示,0x11223344 的 4 个字节 0x11,0x22,0x33,0x44 分别存储在由低往高的内存地址中。

小端则正好相反,如下图所示,0x11223344 的 4 个字节 0x11,0x22,0x33,0x44 分别存储在由高往低的内存地址中。

image.png

因为小段运用更多,请尝试理解下图:

image.png


有符号与无符号数字

如果存储一个无符号的数,那么我们不需要指定其正负符号,那么该数的范围为 0 到 2^64 -1 。但如果要存储一个有符号的数,因为要额外留出一位存储正负符号,那么该数的范围为 -2^63 2^63-1

计算一个数的负数形式,有 2 个步骤:翻转所有位,再加上 1。以 42 为例,过程如下:

42:    0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 1010
翻转:  1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 0101
加1:    1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 0110



CPU 寄存器

由于访问内存 (RAM) 对于 CPU 来说通常是一个缓慢的过程,因此处理器内总是包含许多寄存器,这些寄存器是处理器内部的小型存储位置,可以非常快速地访问数据。在 64 位 x64 处理器上,寄存器可以保存 64 位8 字节。 让我们分别查看一下程序中最如下的常用寄存器:

寄存器名称
作用
备注
RIP
指令寄存器,指向要被执行的下一条指令的地址
RAX
算数寄存器,用于算术运算和 I/O 操作

通用寄存器
RBX
基址寄存器,用作数据指针

通用寄存器
RCX
计数寄存器,常用于循环中的计数器

通用寄存器
RDX
数据寄存器,用于算数运算和 I/O 操作,以及扩展精度结果

通用寄存器
RSI
源索引,通常用作输入字符串的指针

通用寄存器
RDI
目标索引,通常用作输出字符串的指针

通用寄存器
RBP
基址指针,指向栈帧的基址,配合偏移定位变量

通用寄存器
RSP
栈指针,指向栈的顶部

RIP


RFLAGS


通用寄存器
R8-R15
额外的通用寄存器
通用寄存器
RFLAGS
FLAG 寄存器,存储着一系列布尔类型的 Flag,揭示之前操作的结果,例如数值比较。








在 x64 处理器中,每个寄存器是 8 字节,但可以被分为更小的部分以及被直接饮用。例如,RAX 的后 4 字节为 EAX,EAX 的后 2 字节为 AX 等,如下图所示。AH 与 AL 中的 A 与 H 分别表示 High 和 Low。

image.png

寄存器 R8 也可以被类似的方式细分:

image.png

对于通用寄存器,各个部分的名称如下表所示:

64-bit registerLower 32 bitsLower 16 bitsLower 8 bits
raxeaxaxal
rbxebxbxbl
rcxecxcxcl
rdxedxdxdl
rsiesisisil
rdiedididil
rbpebpbpbpl
rspespspspl
r8r8dr8wr8b
r9r9dr9wr9b
r10r10dr10wr10b
r11r11dr11wr11b
r12r12dr12wr12b
r13r13dr13wr13b
r14r14dr14wr14b
r15r15dr15wr15b



标签
描述




















数据尺寸
名称
字节数
byte
1
word
2
dword
4
qword
8


常见汇编指令

值操作

mov

lodsb:从 RSI 中取下一个字节传递给 AL

cdq:清空 RDX 为 NULL

 

比较

test

cmp

jxx

栈操作

push:保存所有寄存器

pushad

pop

popad:恢复寄存器

取址

lea

基本运算

inc

dec

add

sub

mul

div

neg

位操作

and

or

xor

not

sal

sar

shi

sjr

rol

ror

跳转

jmp

jxx

jexcz: 如果 RAX 为 0,那么跳转到最后。

函数调用与返回

call

ret

其他

stosx

int3

nop

repe scasd:重复对比 RAX 与 RDI


函数调用

参数类型
参数 1
参数 2
参数 3
参数 4
参数 5 +
浮点型
RCX
RDX
R8
R9

其他
XMM0
XMM1
XMM2
XMM3