ThatManK Mobile Article
汇编基础
1. 32 位寄存器
1. 通用寄存器
EAX ESP // 栈指针寄存器
EBX EBP
ECX ESI
EDX EDI
EIP
2. 32 位汇编常用指令
1. MOV
MOV EAX,1
MOV EBX,EAX
MOV DWORD PTR DS:[19FF74],0x12345678
MOV DWORD PTR DS:[19FF78],EAX
MOV EAX,DWORD PTR DS:[19FF78]
MOV DWORD PTR DS:[EAX],0x12345678
MOV EAX,DWORD PTR DS:[ECX+4]
MOV EDX,DWORD PTR DS:[EAX+ECX*2] // 只能× 1/2/4/8
2. ADD
3. SUB
4. AND
5. OR
6. XOR
7. NOT // 只有一个操作数
8. MOVS // 从内存到内存, DF 会自增或者自减
MOVS BYTE PTR ES:[EDI], BYTE PTR DS:[ESI] 简写:MOVSB
MOVS WORD PTR ES:[EDI], WORD PTR DS:[ESI] 简写:MOVSW
MOVS DWORD PTR ES:[EDI], DWORD PTR DS:[ESI] 简写:MOVSD
9. STOS // 将 AL/AX/EAX 的值存储到 ES:[EDI], DF 会自增或者自减
STOS BYTE PTR ES:[EDI] 简写:STOSB
STOS WORD PTR ES:[EDI] 简写:STOSW
STOS DWORD PTR ES:[EDI] 简写:STOSD
10. 重复执行 REP
MOV ECX,10 // ECX: 计数器
REP MOVSD
REP STOSD
11. PUSH/POP
PUSH 寄存器/立即数
PUSH DWORD PTR DS:[19FF64]
12. JMP
JMP SHORT 00444212
JMP NEAR EAX
JMP NEAR DWORD PTR DS:[19FF60]
13. CALL(F7, push 下一行地址) // F7 相当于 -t(TF位), F8 相当于 -p, F2 添加断点(init 3、CC)
14. RET(返回, pop ip)
3. 存储模式
- 大端/尾模式:数据高位在低位,数据低位在高位(arm 应用)
- 小端/尾模式:数据高位在高位,数据低位在低位(默认)
4. 标志寄存器
- EFLAGS
- EFL 00000246
11 10 9 8 7 6 5 4 3 2 1 0
0000 0 0 0 0 0 0 0 0 0 0 0 0
0000 0 0 1 0 0 1 0 0 0 1 1 0
第 0 位(CF,进位标志/Carry Flag):用于算术运算的进位和借位。
第 2 位(PF,奇偶校验标志/Parity Flag):若累加器中的低八位中1的数量为奇数(最后一个字节),则PF清0;为偶数,则置1。
第 4 位(AF,辅助进位标志/Auxiliary Carry Flag):用于BCD(二进制编码的十进制数)运算产生的进位或借位标志。
第 6 位(ZF,零标志/Zero Flag):若运算结果为0,则置1。
第 7 位(SF,符号标志/Sign Flag):根据结果的最高位设置(如果是负数,则置1)。
第 8 位(TF,陷阱标志/Trap Flag):用于单步调试功能。
第 9 位(IF,中断允许标志/Interrupt Flag):控制处理器对可屏蔽中断的响应。
第 10 位(DF,方向标志/Direction Flag):用于字符串操作指令,控制是自增还是自减。(DF=0,自增)
第 11 位(OF,溢出标志/Overflow Flag):指出有符号运算结果是否溢出。
JCC(Jump if Condition Code) 判断:
- JE/JZ (Jump if Equal/Jump if Zero): a = b / a - b = 0
跳转条件:ZF(零标志)被设置。
跳转当且仅当前一个操作的结果为零(或者两个比较操作数相等)。
004441EC > B8 01000000 MOV EAX,1
004441F1 BB 01000000 MOV EBX,1
004441F6 3BC3 CMP EAX,EBX
004441F8 74 26 JE SHORT abc.00444220
004441FA EB 2B JMP SHORT abc.00444227
- JNE/JNZ (Jump if Not Equal/Jump if Not Zero): a != b / a - b != 0
跳转条件:ZF清零。
跳转当且仅当前一个操作的结果不为零(或两个比较操作数不相等)。
004441EC > B8 01000000 MOV EAX,1
004441F1 BB 02000000 MOV EBX,2
004441F6 3BC3 CMP EAX,EBX
004441F8 74 26 JE SHORT abc.00444220
004441FA 75 2B JNZ SHORT abc.00444227
- JC/JB (Jump if Carry/Jump if Below): a < b
跳转条件:CF(进位标志)被设置。
跳转如果无符号数比较中,第一个数小于第二个数。
004441EC > B8 01000000 MOV EAX,1
004441F1 BB 02000000 MOV EBX,2
004441F6 3BC3 CMP EAX,EBX
004441F8 72 26 JB SHORT abc.00444220
004441FA 73 2B JNB SHORT abc.00444227
- JNC/JNB (Jump if Not Carry/Jump if Not Below): a >= b
跳转条件:CF清零。
跳转如果无符号数比较中,第一个数大于或等于第二个数。
004441EC > B8 01000000 MOV EAX,1
004441F1 BB 02000000 MOV EBX,2
004441F6 3BC3 CMP EAX,EBX
004441F8 72 26 JB SHORT abc.00444220
004441FA 73 2B JNB SHORT abc.00444227
- JO (Jump if Overflow):
跳转条件:OF(溢出标志)被设置。
跳转当且仅当前一个操作产生溢出。
004441EC > B0 7F MOV AL,7F
004441EE 04 01 ADD AL,1
004441F0 70 2E JO SHORT abc.00444220
004441F2 71 33 JNO SHORT abc.00444227
- JNO (Jump if Not Overflow):
跳转条件:OF清零。
不跳转如果前一个操作没有产生溢出。
004441EC > B0 7F MOV AL,7F
004441EE 04 01 ADD AL,1
004441F0 70 2E JO SHORT abc.00444220
004441F2 71 33 JNO SHORT abc.00444227
- JS (Jump if Sign): (有符号) res 为负数
跳转条件:SF(符号标志)被设置。
跳转如果前一个操作的结果为负数。
004441EC > B0 02 MOV AL,2
004441EE 2C 03 SUB AL,3
004441F0 78 2E JS SHORT abc.00444220
004441F2 79 33 JNS SHORT abc.00444227
- JNS (Jump if Not Sign): res == 0 | res 为正数
跳转条件:SF清零。
跳转如果前一个操作的结果为正数或零。
004441EC > B0 02 MOV AL,3
004441EE 2C 03 SUB AL,2
004441F0 78 2E JS SHORT abc.00444220
004441F2 79 33 JNS SHORT abc.00444227
- JP/JPE (Jump if Parity/Jump if Parity Even): res 中 1 的个数为偶数
跳转条件:PF(奇偶校验标志)被设置。
跳转如果前一个操作的最低有效字节的位数为偶数。
004441EC > B0 03 MOV AL,3
004441EE 20C0 AND AL,AL // 011
004441F0 7A 2E JPE SHORT abc.00444220
004441F2 71 33 JNO SHORT abc.00444227
- JNP/JPO (Jump if No Parity/Jump if Parity Odd): res 中 1 的个数为奇数
跳转条件:PF清零。
跳转如果前一个操作的最低有效字节的位数为奇数。
004441EC > B0 03 MOV AL,4 // 100
004441EE 20C0 AND AL,AL
004441F0 7A 2E JPE SHORT abc.00444220
004441F2 71 33 JNO SHORT abc.00444227
- JL/JNGE (Jump if Less/Jump if Not Greater or Equal): a < b
跳转条件:SF ≠ OF。
跳转当有符号数比较中,第一个数小于第二个数。
004441EC > B0 04 MOV AL,4
004441EE B3 05 MOV BL,5
004441F0 3AC3 CMP AL,BL
004441F2 7C 2C JL SHORT abc.00444220
004441F4 7D 31 JGE SHORT abc.00444227
- JGE/JNL (Jump if Greater or Equal/Jump if Not Less): a >= b
跳转条件:SF = OF。
跳转当有符号数比较中,第一个数大于或等于第二个数。
004441EC > B0 04 MOV AL,5
004441EE B3 05 MOV BL,5
004441F0 3AC3 CMP AL,BL
004441F2 7C 2C JL SHORT abc.00444220
004441F4 7D 31 JGE SHORT abc.00444227
- JG/JNLE (Jump if Greater/Jump if Not Less or Equal): a > b
跳转条件:ZF清零,且SF = OF。
跳转如果有符号数比较中,第一个数大于第二个数。
004441EC > B0 05 MOV AL,6
004441EE B3 05 MOV BL,5
004441F0 3AC3 CMP AL,BL
004441F2 7F 2C JG SHORT abc.00444220
004441F4 7E 31 JLE SHORT abc.00444227
- JLE/JNG (Jump if Less or Equal/Jump if Not Greater): a <= b
跳转条件:ZF被设置或者SF ≠ OF。
跳转如果有符号数比较中,第一个数小于或等于第二个数。
004441EC > B0 05 MOV AL,5
004441EE B3 05 MOV BL,5
004441F0 3AC3 CMP AL,BL
004441F2 7F 2C JG SHORT abc.00444220
004441F4 7E 31 JLE SHORT abc.00444227
- JA/JNBE (Jump if Above/Jump if Not Below or Equal): a > b
跳转条件:CF清零且ZF清零。
跳转如果无符号数比较中,第一个数大于第二个数。
- JBE/JNA (Jump if Below or Equal/Jump if Not Above): a <= b
跳转条件:CF被设置或者ZF被设置。
跳转如果无符号数第一个操作数小于或等于第二个操作数
5. 函数
- 寄存器传参
004441EC > B8 01000000 MOV EAX,1
004441F1 BB 02000000 MOV EBX,2
004441F6 E8 0E000000 CALL abc.00444209
004441FB B8 78563412 MOV EAX,12345678
00444200 BB 78563412 MOV EBX,12345678
... // 这里是函数,带了两个参数
00444209 03C3 ADD EAX,EBX
0044420B C3 RETN
- 堆栈传参 1
004441EC > 6A 01 PUSH 1
004441EE 6A 02 PUSH 2
004441F0 E8 07000000 CALL abc.004441FC
004441F5 83C4 08 ADD ESP,8 // sp 又回到原位
004441F8 90 NOP
004441F9 90 NOP
004441FA 90 NOP
004441FB 90 NOP
004441FC 3E:8B4424 08 MOV EAX,DWORD PTR DS:[ESP+8]
00444201 3E:034424 04 ADD EAX,DWORD PTR DS:[ESP+4]
00444206 C3 RETN
- 堆栈传参 2
004441EC > 6A 01 PUSH 1
004441EE 6A 02 PUSH 2
004441F0 E8 07000000 CALL abc.004441FC
004441F5 90 NOP
004441F6 90 NOP
004441F7 90 NOP
004441F8 90 NOP
004441F9 90 NOP
004441FA 90 NOP
004441FB 90 NOP
004441FC 3E:8B4424 08 MOV EAX,DWORD PTR DS:[ESP+8]
00444201 3E:034424 04 ADD EAX,DWORD PTR DS:[ESP+4]
00444206 C2 0800 RETN 8
6. ESP 寻址
004441EC > 6A 01 PUSH 1
004441EE 6A 02 PUSH 2
004441F0 B8 03000000 MOV EAX,3 // 因为 push 了
004441F5 50 PUSH EAX
004441F6 E8 02000000 CALL abc.004441FD
004441FB 90 NOP
004441FC 90 NOP
004441FD 3E:8B4424 0C MOV EAX,DWORD PTR DS:[ESP+C] // 所以这里+C
00444202 3E:034424 08 ADD EAX,DWORD PTR DS:[ESP+8]
00444207 C2 1200 RETN 12
$ ==> > 004441FB abc.004441FB
$+4 > 00000003
$+8 > 00000002
$+C > 00000001
7. EBP 寻址(堆栈平衡)
004441EC > 6A 01 PUSH 1
004441EE 6A 02 PUSH 2
004441F0 E8 05000000 CALL abc.004441FA
004441F5 83C4 08 ADD ESP,8
004441F8 90 NOP
004441F9 90 NOP
004441FA 55 PUSH EBP
004441FB 8BEC MOV EBP,ESP
004441FD 83EC 10 SUB ESP,10 // 在大栈里面,分出来一个小栈,通过 ss:bp 寻址
00444200 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C]
00444203 0345 08 ADD EAX,DWORD PTR SS:[EBP+8]
00444206 8BE5 MOV ESP,EBP
00444208 5D POP EBP
00444209 C3 RETN
$ ==> > 0019FF80
$+4 > 004441F5 abc.004441F5
$+8 > 00000002
$+C > 00000001