1、循环语句重要特征提取
循环语句最重要的特点就是执行的过程中会往上跳!!!
箭头往上跳的一般都是循环语句,比如下面的for循环:
2、do..while语句反汇编
#include<iostream>
using namespace std;
#pragma warning (disable:4996)
//1、do..while
void Fun(int x, int y) {
do {
printf("%d\n", x);
x++;
} while (x < y);
}
int main() {
Fun(0, 10);
system("pause");
return 0;
}
00C51790 push ebp
00C51791 mov ebp,esp
00C51793 sub esp,0C0h
00C51799 push ebx
00C5179A push esi
00C5179B push edi
00C5179C mov edi,ebp
00C5179E xor ecx,ecx
00C517A0 mov eax,0CCCCCCCCh
00C517A5 rep stos dword ptr es:[edi]
00C517A7 mov ecx,offset _A8394B5C_循环语句测试@cpp (0C5C029h)
00C517AC call @__CheckForDebuggerJustMyCode@4 (0C51325h)
00C517B1 mov eax,dword ptr [x]
00C517B4 push eax
00C517B5 push offset string "%d\n" (0C57B30h)
00C517BA call _printf (0C510CDh)
00C517BF add esp,8
00C517C2 mov eax,dword ptr [x]
00C517C5 add eax,1
00C517C8 mov dword ptr [x],eax
00C517CB mov eax,dword ptr [x]
00C517CE cmp eax,dword ptr [y]
00C517D1 jl __$EncStackInitStart+15h (0C517B1h)
00C517D3 pop edi
00C517D4 pop esi
00C517D5 pop ebx
00C517D6 add esp,0C0h
00C517DC cmp ebp,esp
00C517DE call __RTC_CheckEsp (0C51249h)
00C517E3 mov esp,ebp
00C517E5 pop ebp
00C517E6 ret
由此可以分析:do..while是先执行{}里的内容,然后再判断是不是需要跳出循环,如果不跳出就跳到do..while开始的地方继续执行。
3、while语句分析
#include<iostream>
using namespace std;
#pragma warning (disable:4996)
//2、while
void Fun(int x, int y) {
while (x < y) {
printf("%d\n", x);
++x;
}
}
int main() {
Fun(0, 10);
system("pause");
return 0;
}
009D1790 push ebp
009D1791 mov ebp,esp
009D1793 sub esp,0C0h
009D1799 push ebx
009D179A push esi
009D179B push edi
009D179C mov edi,ebp
009D179E xor ecx,ecx
009D17A0 mov eax,0CCCCCCCCh
009D17A5 rep stos dword ptr es:[edi]
009D17A7 mov ecx,offset _A8394B5C_循环语句测试@cpp (09DC029h)
009D17AC call @__CheckForDebuggerJustMyCode@4 (09D1325h)
009D17B1 mov eax,dword ptr [x]
009D17B4 cmp eax,dword ptr [y]
009D17B7 jge __$EncStackInitStart+39h (09D17D5h)
009D17B9 mov eax,dword ptr [x]
009D17BC push eax
009D17BD push offset string "%d\n" (09D7B30h)
009D17C2 call _printf (09D10CDh)
009D17C7 add esp,8
009D17CA mov eax,dword ptr [x]
009D17CD add eax,1
009D17D0 mov dword ptr [x],eax
009D17D3 jmp __$EncStackInitStart+15h (09D17B1h)
009D17D5 pop edi
009D17D6 pop esi
009D17D7 pop ebx
009D17D8 add esp,0C0h
009D17DE cmp ebp,esp
009D17E0 call __RTC_CheckEsp (09D1249h)
009D17E5 mov esp,ebp
009D17E7 pop ebp
009D17E8 ret
while语句是先判断,不符合就跳出循环,符合就执行循环体里的内容,最后再跳到开始进行判断
4、while(y--)语句分析
#include<iostream>
using namespace std;
#pragma warning (disable:4996)
void Fun(int x, int y) {
while (y--) {
printf("%d\n", y);
}
}
int main() {
Fun(0, 10);
system("pause");
return 0;
}
00FA1790 push ebp
00FA1791 mov ebp,esp
00FA1793 sub esp,0C4h
00FA1799 push ebx
00FA179A push esi
00FA179B push edi
00FA179C lea edi,[ebp-4]
00FA179F mov ecx,1
00FA17A4 mov eax,0CCCCCCCCh
00FA17A9 rep stos dword ptr es:[edi]
00FA17AB mov ecx,offset _A8394B5C_循环语句测试@cpp (0FAC029h)
00FA17B0 call @__CheckForDebuggerJustMyCode@4 (0FA1325h)
00FA17B5 mov eax,dword ptr [y]
00FA17B8 mov dword ptr [ebp-0C4h],eax
00FA17BE mov ecx,dword ptr [y]
00FA17C1 sub ecx,1
00FA17C4 mov dword ptr [y],ecx
00FA17C7 cmp dword ptr [ebp-0C4h],0
00FA17CE je __$EncStackInitStart+47h (0FA17E3h)
00FA17D0 mov eax,dword ptr [y]
00FA17D3 push eax
00FA17D4 push offset string "%d\n" (0FA7B30h)
00FA17D9 call _printf (0FA10CDh)
00FA17DE add esp,8
00FA17E1 jmp __$EncStackInitStart+19h (0FA17B5h)
00FA17E3 pop edi
00FA17E4 pop esi
00FA17E5 pop ebx
00FA17E6 add esp,0C4h
00FA17EC cmp ebp,esp
00FA17EE call __RTC_CheckEsp (0FA1249h)
00FA17F3 mov esp,ebp
00FA17F5 pop ebp
00FA17F6 ret
先执行while括号()里的内容,然后cmp判断是否需要跳出循环(当且仅当y==0的时候才会跳出循环!!!我竟然现在才发现😂😂😂),不需要就一路往后执行,然后再跳回到一开始的()的语句进行处理。
5、for循环分析
#include<iostream>
using namespace std;
#pragma warning (disable:4996)
void Fun(int x, int y) {
for (int i = x; i < y; i++) {
printf("%d\n", i);
}
}
int main() {
Fun(0, 9);
system("pause");
return 0;
}
00E61790 push ebp
00E61791 mov ebp,esp
00E61793 sub esp,0CCh
00E61799 push ebx
00E6179A push esi
00E6179B push edi
00E6179C lea edi,[ebp-0Ch]
00E6179F mov ecx,3
00E617A4 mov eax,0CCCCCCCCh
00E617A9 rep stos dword ptr es:[edi]
00E617AB mov ecx,offset _A8394B5C_循环语句测试@cpp (0E6C029h)
00E617B0 call @__CheckForDebuggerJustMyCode@4 (0E61325h)
00E617B5 mov eax,dword ptr [x]
00E617B8 mov dword ptr [ebp-8],eax
00E617BB jmp __$EncStackInitStart+2Ah (0E617C6h)
00E617BD mov eax,dword ptr [ebp-8]
00E617C0 add eax,1
00E617C3 mov dword ptr [ebp-8],eax
00E617C6 mov eax,dword ptr [ebp-8]
00E617C9 cmp eax,dword ptr [y]
00E617CC jge __$EncStackInitStart+45h (0E617E1h)
00E617CE mov eax,dword ptr [ebp-8]
00E617D1 push eax
00E617D2 push offset string "%d\n" (0E67B30h)
00E617D7 call _printf (0E610CDh)
00E617DC add esp,8
00E617DF jmp __$EncStackInitStart+21h (0E617BDh)
00E617E1 pop edi
00E617E2 pop esi
00E617E3 pop ebx
00E617E4 add esp,0CCh
00E617EA cmp ebp,esp
00E617EC call __RTC_CheckEsp (0E61249h)
00E617F1 mov esp,ebp
00E617F3 pop ebp
00E617F4 ret
可以总结:for循环是先给i赋值,然后判断(i<y)是否成立,不成立就跳出循环,成立就执行循环体里面的操作,然后再跳转到上面的i++语句,给i进行增加,接着就继续判断(i<y)是否成立,循环往复,直到不满足i<y为止。
6、i++和++i在for循环当中效率一样吗?
i++:
00E617BD mov eax,dword ptr [ebp-8]
00E617C0 add eax,1
00E617C3 mov dword ptr [ebp-8],eax
++i:
008B17BE mov eax,dword ptr [ebp-8]
008B17C1 add eax,1
008B17C4 mov dword ptr [ebp-8],eax
有区别吗?》没区别,所以不要被培训班的老师骗了,编译器才是真理!!!
那么,今天的逆向学习内容到这里就结束了,又是收获满满的一天呢!喜欢的话多多点赞收藏吧!!!🧡🧡🧡🤞