Day4:Linux汇编框架、操作系统与汇编器、主函数跳转流程
Linux汇编框架、操作系统与汇编器、主函数跳转流程
Linux(NASM)汇编框架
Linux和Windows的不同主要有:
系统调用方式不同:
Windows提供API,可以直接利用系统函数
Linux需要用系统调用号触发系统调用。系统调用号存入特定寄存器后使用触发指令,触发系统调用
触发指令:
32位(x86):int 0x80
64位(x64):syscall
参数传递:
32位:eax(系统调用号),ebx、ecx、edx、esi、edi、ebp(参数)。
64位:rax(系统调用号),rdi、rsi、rdx、r10、r8、r9(参数)。
32位下exit示例:
1
2mov eax,1 ;32位下,exit的系统调用号为1
int 0x80 ;系统调用号存入寄存器后,触发系统调用
可执行文件格式不同:
- Windows使用PE文件格式
- Linux使用ELF文件格式
其他细节:
- Linux在段名前必须添加section,只有.text段没有.code段(实际上由汇编器决定,详见下一部分)
- Linux使用0xA作为字符串结束符
32位汇编框架
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16section .data
msg db "HelloWorld",0xA
len equ $ - msg ;用变量len记录msg的长度($表示当前变量的地址,减去msg的地址就是msg的长度)
section .text
global _start
_start:
mov eax,4 ;eax存放系统调用号4:sys_write
mov ebx,1 ;参数1:文件描述符,1表示标准输出stdout
mov ecx,msg ;参数2:要打印的数据地址
mov edx,len ;参数3:打印的字节数
int 0x80
mov eax,1 ;eax存放系统调用号1:sys_exit
mov ebx,0 ;参数1:退出状态码(0表示成功)
int 0x8064位汇编框架
1 | |
操作系统与汇编器
- Windows:主要有MASM和NASM两种汇编器
- MASM(Microsoft Macro Assembler),主要集成在visual studio中
- 段名前不要求加section,可以直接用 .段名 声明
- 指令存放在.code段
- .code段,函数以 func_name proc 开始,以 func_name endp 结束
- 使用Intel风格,即 指令 目标操作数,源操作数
- NASM(Netwide Assembler),跨平台汇编器,支持Windows、Linux、macOS
- 段名前要求加section,用 sectino .段名 声明
- 指令存放在.text段
- .text段,函数用 global func_name 声明后再定义
- 使用Intel风格
- MASM(Microsoft Macro Assembler),主要集成在visual studio中
- Linux:主要有NASM和GAS两种汇编器
- NASM同上
- GAS(GNU Assembler),Linux默认汇编器
- 段名前要求加.section,用 .section .段名 声明
- 指令存放在.text段
- .text段,函数用 .global func_name 声明后再定义
- 使用AT&T风格,即 指令 源操作数,目标操作数
主函数跳转流程
环境:vs2022,Debug x86/x64,Release x86/x64
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
26
27;x86 debug 跳转特征
;step1
jmp ;直接jmp
;step2
call ;第一个call
;step3
call
call <-- ;连续两个call,进第二个
;step4
2*jz-->call
mov
call ;两个jz指向的同一个call且此call后紧跟mov和call
;step5
mov
push
mov
push
mov
push
call ;连续push3个参数入栈后的call
;step6
jmp1
2
3
4
5
6
7
8
9
10;x86 Release 跳转特征
;step1
call
jmp ;call后的jmp
;step2
push
push
push
call ;连续push3个参数入栈后的call1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26;x64 Debug 跳转特征
;step1
jmp ;直接jmp
;step2
call ;第一个call
;step3
call
call <-- ;连续两个call进第二个
;step4
2*jz-->call
mov
call ;两个jz指向的同一个call且此call后紧跟mov和call
;step5
mov
mov
mov
mov
mov
call ;连续5个mov后的call(传参)
;step6
jmp ;直接jmp1
2
3
4
5
6
7
8
9
10
11
12;x64 Release 跳转特征
;step1
call
jmp ;call后的jmp
;step2
mov
mov
mov
call
mov
call ;三个mov后的call(传参)且此call后紧跟mov和call
Day4:Linux汇编框架、操作系统与汇编器、主函数跳转流程