3 月 25 日汇编语言与逆向工程

主函数

汇编指令

image-20240323212852517

  1. push rbp:将当前函数的栈帧基址寄存器的值压入栈中,用于保存前一个函数的栈帧基址。

  2. mov rbp, rsp:将栈顶指针的值赋给栈帧基址寄存器,这样 rbp 指向了当前函数的栈帧。

  3. sub rsp, 10h:在栈上为局部变量分配 10h(16 字节)的空间,即在栈上分配了 16 字节的空间用于存储局部变量或临时数据。

  4. mov esi, 4:将立即数 4 赋给 esi 寄存器,该寄存器通常用于作为函数参数传递整型参数。

  5. mov edi, 3:将立即数 3 赋给 edi 寄存器,通常用于作为函数参数传递整型参数。

  6. call fun:调用名为 fun 的函数,传递了两个参数,分别是 4 和 3,它们存储在 esi 和 edi 寄存器中。

  7. mov [rbp+m], eax:将 eax 寄存器的值(即函数 fun 的返回值)存储到位于当前栈帧的偏移量 m 处的内存地址中。这里的 m 是一个未知的值,需要根据具体的代码上下文来确定。

  8. mov eax, 0:将 0 赋给 eax 寄存器,通常用于函数返回值。

  9. leave:恢复栈帧,实际上执行的是 mov rsp, rbp 和 pop rbp 的组合指令,将栈帧基址寄存器(rbp)的值恢复为调用者的栈帧基址,并将栈指针(rsp)恢复到调用者函数的栈顶。

  10. retn:函数返回指令,将控制流返回到调用该函数的地址处。

这段代码的主要作用是调用一个函数 fun,将参数 4 和 3 传递给它,然后将其返回值存储到指定的内存位置,并返回到调用者。

栈帧图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
高地址

|
| +------------------+
| | 返回地址 |
| +------------------+
| | |
| | 保存的rbp值 | ← rbp, rsp
| +------------------+
| | |
| | 局部变量 |
| | (10 字节) |
| | |
| +------------------+
| | |
| | 参数空间 | ← rsp (调用fun前)
| | |
| +------------------+
| | |
| | 参数空间 | ← rsp (fun内部)
| | |
| +------------------+

低地址

fun 函数

汇编指令

image-20240323213024282

这段汇编指令表示一个简单的函数,它接受两个整数参数,并返回它们的和。

  1. push rbp:保存调用该函数前的栈帧基址寄存器的值。

  2. mov rbp, rsp:将当前栈顶指针的值赋给栈帧基址寄存器,建立当前函数的栈帧。

  3. mov [rbp+a], edi:将第一个参数(a)存储到位于当前栈帧的偏移量 a 处的内存地址中。通常,函数的参数通过寄存器传递,edi 寄存器用于传递第一个整数参数。

  4. mov [rbp+b], esi:将第二个参数(b)存储到位于当前栈帧的偏移量 b 处的内存地址中。通常,函数的参数通过寄存器传递,esi 寄存器用于传递第二个整数参数。

  5. mov edx, [rbp+a]:将第一个参数(a)的值加载到 edx 寄存器中。

  6. mov eax, [rbp+b]:将第二个参数(b)的值加载到 eax 寄存器中。

  7. add eax, edx:将 edx 寄存器中的值和 eax 寄存器中的值相加,结果保存在 eax 寄存器中。这里计算了两个参数的和。

  8. pop rbp:恢复调用该函数前的栈帧基址寄存器的值。

  9. retn:函数返回指令,将控制流返回到调用该函数的地址处。

这段代码的作用是接受两个整数参数,将它们相加,然后返回结果。

栈帧图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
高地址

|
| +------------------+
| | 返回地址 |
| +------------------+
| | |
| | 保存的rbp值 | ← rbp, rsp
| +------------------+
| | |
| | 参数 b 的值 | ← rbp+8
| +------------------+
| | |
| | 参数 a 的值 | ← rbp+0
| +------------------+

低地址