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 字节。 让我们分别查看一下程序中最常用的寄存器:

寄存器名称
作用
备注
RAX


RBX


RCX


RDX


RSI


RDI


RBP


RSP


RIP

 
RFLAGS


R8-R15
通用寄存器






 

image.png

image.png


标签
描述














 

 

 

 

 


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


常见汇编指令

移动值操作

mov

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

cdq:清空 RDX 为 NULL

 

比较

test

cmp

jxx

栈操作

pushpush:保存所有寄存器

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