Featured image of post 汇编

汇编

汇编

数据宽度

BYTE WORD DWORD
8bit 16bit 32bit
$$ *寻址范围->32位or64位* $$

68879095-ef38-4d76-9be0-8aa1c7eb90bc

汇编指令

mov lea add sub
取数据 取地址
and or xor not
& | ^ !

进阶

指令格式 功能
ADC R/M,R/M/IMM 带进位加法
SBB R/M,R/M/IMM 带借位减法
XCHG R/M,R/M 交换数据
MOVS B/W/D :[EDI],:[ESI] 移动数据(内存-内存)([EDI]/[ESI]根据方向标志DF决定自增/减)
STOS B/W/D :[EDI] 将AL/AX/EAX的值储存到[EDI]指定的内存单元
REP MOVSD/STOSB/… 按计数寄存器(ECX)中指定的次数重复执行字符串指令
类型转换 功能
MOVSX CX, AL 符号拓展
MOVZX CX, AL 无符号拓展

内存的读写

MOV DWORD ptr ds:[0x0012FFC4], 0x12345678

汇编、寄存器、堆栈窗口大端序;数据窗口小端序

寻址公式
[立即数]
[reg] -> dword ptr ds:[ecx]
[reg+立即数] -> dword ptr ds:[ecx+4]
[reg+reg*{1, 2, 4, 8}] -> dword ptr ds:[eax+ecx*4]
[reg+reg*{1, 2, 4, 8}+立即数] -> dword ptr ds:[eax+ecx*4+4]

标志寄存器

各类标志寄存器 值为1的条件
进位标志CF 运算结果最高位产生一个进位或借位
奇偶标志PF 运算结果中“1”的个数为偶数
辅助进位标志AF 在字/字节操作时,低字节/4位向高字节/4位进位或借位
零标志ZF 运算结果为0
符号标志SF 与运算结果的最高位相同
溢出标志OF 有符号数加减运算是否溢出

image-20250528145359288

常见汇编及JCC

常见汇编
JMP 寄存器/立即数 修改EIP的值
CALL [A]/寄存器
PUSH [B]
MOV EIP,[A]/寄存器
RET -> POP EIP
CMP R/M,R/M/IMM
TEST R/M,R/M/IMM
JCC 条件 标志
JE,JZ 结果为零则跳转 ZF=1
JNE,JNZ 结果不为零则跳转 ZF=0
JS 结果为负则跳转 SF=1
JNS 结果为非负则跳转 SF=0
JP,JPE 结果中1的个数为偶数则跳转 PF=1
JNP,JPO 结果中1的个数为奇数则跳转 PF=0
JO 结果溢出了则跳转 OF=1
JNO 结果没有溢出则跳转 OF=0
JB,JNAE 小于则跳转(无符号数) CF=1
JNB,JAE 大于等于则跳转(无符号数) CF=0
JBE,JNA 小于等于则跳转(无符号数) CF=1 or ZF=1
JNBE,JA 大于则跳转(无符号数) CF=0 and ZF=0
JL,JNGE 小于则跳转(有符号数) SF!=OF
JNL,JGE 大于等于则跳转(有符号数) SF=OF
JLE,JNG 小于等于则跳转(有符号数) ZF=1 or SF!=OF
JNLE,JG 大于则跳转(有符号数) ZF=0 and SF=OF

堆栈

push R/M

pop R/M

esp 栈顶 / ebp 栈底

  • 无参函数
汇编代码 功能
call 00E71316 调用函数(无参)
jmp 00E723D0
00E723D0 push ebp
00E723D1 mov ebp,esp
00E723D3 sub esp,0C0h
提升堆栈
00E723D9 push ebx
00E723DA push esi
00E723DB push edi
保留现场
00E723DC mov edi,ebp
00E723DE xor ecx,ecx
00E723E0 mov eax,0CCCCCCCCh
00E723E5 rep stos dword ptr es:[edi]
00E723E7 mov ecx,0E7E069h
00E723EC call 00E71389
为缓冲区填充数据
00E723F2 pop edi
00E723F3 pop esi
00E723F4 pop ebx
恢复现场
00E723F5 add esp,0C0h
00E723FB cmp ebp,esp
00E723FD call 00E7128F
检查堆栈平衡
00E72402 mov esp,ebp
00E72404 pop ebp
降低堆栈
00E72405 ret 函数返回
  • 有参函数(加法)
汇编代码 功能
000B1D35 push 2
000B1D37 push 1
参数
000B1D39 call 000B143D 调用函数
000B1D3E add esp,8 平衡堆栈
000B143D jmp 000B1CC0 中转
000B1CC0 push ebp
000B1CC1 mov ebp,esp
000B1CC3 sub esp,0C0h
000B1CC9 push ebx
000B1CCA push esi
000B1CCB push edi
000B1CCC mov edi,ebp
000B1CCE xor ecx,ecx
000B1CD0 mov eax,0CCCCCCCCh
000B1CD5 rep stos dword ptr es:[edi]
000B1CD7 mov ecx,0BE069h
000B1CDC call 000B1389
000B1CE1 nop
000B1CE2 mov eax,dword ptr [ebp+8]
000B1CE5 add eax,dword ptr [ebp+0Ch]
eax中存储的就是返回值
000B1CE8 pop edi
000B1CE9 pop esi
000B1CEA pop ebx
000B1CEB add esp,0C0h
000B1CF1 cmp ebp,esp
000B1CF3 call 000B128F
000B1CF8 mov esp,ebp
000B1CFA pop ebp
000B1CFB ret
  • 嵌套函数
汇编代码 功能
00761D45 push 3
00761D47 push 2
00761D49 push 1
参数
00761D4B call plus2 (0761442h) 调用函数
00761D50 add esp,0Ch 平衡堆栈
00761442 jmp plus2 (0762490h) 中转
00762490 push ebp
00762491 mov ebp,esp
00762493 sub esp,0CCh
00762499 push ebx
0076249A push esi
0076249B push edi
0076249C lea edi,[ebp-0Ch]
0076249F mov ecx,3
007624A4 mov eax,0CCCCCCCCh
007624A9 rep stos dword ptr es:[edi]
007624AB mov ecx,76E069h
007624B0 call 00761389
007624B5 nop
12: int t = plus1(a, b);
007624B6 mov eax,dword ptr [ebp+0Ch]
eax=2
007624B9 push eax 2入栈(参数)
007624BA mov ecx,dword ptr [ebp+8] ecx=1
007624BD push ecx 1入栈(参数)
007624BE call plus1 (076143Dh) 函数调用
007624C3 add esp,8 平衡堆栈
007624C6 mov dword ptr [ebp-8],eax eax是plus1返回结果,ebp-8是局部变量t
13: return plus1(t, c);
007624C9 mov eax,dword ptr [ebp+10h]
007624CC push eax
007624CD mov ecx,dword ptr [ebp-8]
007624D0 push ecx
007624D1 call 0076143D
007624D6 add esp,8
同上
0076143D jmp plus1 (00761CC0h)
00761CC0 push ebp
00761CC1 mov ebp,esp
00761CC3 sub esp,0C0h
00761CC9 push ebx
00761CCA push esi
00761CCB push edi
00761CCC mov edi,ebp
00761CCE xor ecx,ecx
00761CD0 mov eax,0CCCCCCCCh
00761CD5 rep stos dword ptr es:[edi]
00761CD7 mov ecx,76E069h
00761CDC call 00761389
00761CE1 nop
9: return a + b;
00761CE2 mov eax,dword ptr [ebp+8]
00761CE5 add eax,dword ptr [ebp+0Ch]
00761CE8 pop edi
00761CE9 pop esi
00761CEA pop ebx
00761CEB add esp,0C0h
00761CF1 cmp ebp,esp
00761CF3 call 0076128F
00761CF8 mov esp,ebp
00761CFA pop ebp
00761CFB ret
plus1(t, c)
007624D9 pop edi
007624DA pop esi
007624DB pop ebx
007624DC add esp,0CCh
007624E2 cmp ebp,esp
007624E4 call 0076128F
007624E9 mov esp,ebp
007624EB pop ebp
007624EC ret

裸函数及其调用约定

 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
28
void __declspec(naked) plus(/*int x, int y, int z*/) { //裸函数
    __asm {
        /*
        push ebp;   //提升堆栈
		mov ebp, esp;
		sub esp, 0x40;
		push ebx;   //保留现场
		push esi;
		push edi;
		mov eax, 0xCCCCCCCC;  //填充缓冲区
		mov ecx, 0x10;
		lea edi, dword ptr ds : [ebp - 0x40] ;
		rep stosd;

		mov eax, dword ptr ds : [ebp + 8] ;  //函数功能	x
		add eax, dword ptr ds : [ebp + 0xC] ;	//y
		add eax, dword ptr ds : [ebp + 0x10] ;	//z
		//__emit 0xe8;

		pop edi;   //恢复现场
		pop esi;
		pop edx;
		mov esp, ebp;    //降低堆栈
		pop ebp;
		*/
        ret;
    }
}
调用约定 参数压栈顺序 平衡堆栈
__cdecl 从右至左入栈 调用者清理栈
__stdcall 从右至左入栈 自身清理堆栈->ret 8
__fastcall ecx/edx传送前两个
剩下:从右至左入栈
自身清理堆栈

内存图

if,else,while 代码区
参数,局部变量,临时数据 堆栈
动态申请的,大小可变的
可读,可写
可读,可写 全局变量区
只读 常量区

位运算

算数移位 指令格式 逻辑移位 指令格式
溢出位进CF SAL/SAR R/M,CL/I 溢出位进CF SHL/SHR R/M,CL/I
算数左移 SAL(补0) 逻辑左移 SHL(补0)
算数右移 SAR(补符号位) 逻辑右移 SHR(补0)
循环移位 指令格式 带进位循环 指令格式
溢出位进CF ROL R/M, I
ROR R/M, CL
溢出位进CF RCL R/M, I
RCR R/M, CL
循环左移 ROL(补溢出位) 左移 RCL(补CF位)
循环右移 ROR(补溢出位) 右移 RCR(补CF位)
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
人生若只如初见
使用 Hugo 构建
主题 StackJimmy 设计