六、for循环的逆向
1 #include "stdafx.h" 2 3 4 5 int fun(int a,int b) 6 { 7 int c=a+b; 8 int i; 9 for(i=0;i<50;i++) 10 { 11 c=c+i; 12 } 13 return c; 14 } 15 16 17 int _tmain(int argc, _TCHAR* argv[]) 18 { 19 20 int m=fun(11,22); 21 return 0; 22 }
下面是汇编代码:
1 int fun(int a,int b) 2 { 3 00412CE0 push ebp ;ebp入栈 4 00412CE1 mov ebp,esp ;用ebp保存esp的值 5 00412CE3 sub esp,0D8h ;为局部变量申请空间 6 00412CE9 push ebx ; 7 00412CEA push esi ; 8 00412CEB push edi ;寄存器入栈,保存它们的值 9 00412CEC lea edi,[ebp-0D8h] ;获得局部变量空间的首地址 10 00412CF2 mov ecx,36h ;确定stos的终止条件 11 00412CF7 mov eax,0CCCCCCCCh ;将eax的值初始化为CCCCCCCC,也就是int3断点的机器码 12 00412CFC rep stos dword ptr es:[edi] ;讲CC放入申请的局部变量空间 13 int c=a+b; 14 00412CFE mov eax,dword ptr [a] ;eax=a 15 00412D01 add eax,dword ptr [b] ;eax=a+b 16 00412D04 mov dword ptr [c],eax ;c=eax 17 int i; 18 for(i=0;i<50;i++) 19 00412D07 mov dword ptr [i],0 ;int i=0 20 00412D0E jmp fun+39h (412D19h) ;跳转到B 21 00412D10 mov eax,dword ptr [i] ;这里是A的开始 22 00412D13 add eax,1 ; 23 00412D16 mov dword ptr [i],eax ;i++ 24 00412D19 cmp dword ptr [i],32h ;这里是B的开始 i<50? 25 00412D1D jge fun+4Ah (412D2Ah) ;如果i大于或等于50,则此条语句实现,跳出循环 26 { 27 c=c+i; 28 00412D1F mov eax,dword ptr [c] ;eax=c 29 00412D22 add eax,dword ptr [i] ;eax++ 30 00412D25 mov dword ptr [c],eax ;c=eax 31 } 32 00412D28 jmp fun+30h (412D10h) ;跳转到A 33 return c; 34 00412D2A mov eax,dword ptr [c] ;将结果保存到eax中,作为返回的结果 35 } 36 00412D2D pop edi ;弹出保存的寄存器值,实现堆栈的平衡 37 00412D2E pop esi ; 38 00412D2F pop ebx ; 39 00412D30 mov esp,ebp ; 40 00412D32 pop ebp ; 41 00412D33 ret
我们主要看循环部分的代码。
循环主要用这么几条指令来实现:
mov 进行初始化
jmp跳过修改循环变量的代码
cmp实现条件判断
jge根据条件跳转
1 mov <循环变量>,<初始值> ;给循环变量赋初值 2 jmp B ;跳到第一次循环处 3 A : (改动循环变量) ;修改循环变量 4 ... 5 6 B : cmp <循环变量>,<限制变量> ;检查循环条件 7 jge 跳出循环 8 (循环体) 9 ... 10 jmp A ;跳回去修改循环变量
。。。。。。。。。。。。。。。。