2014反汇编特训第一集:IDA逆向分析双重循环寻找素数,随后会发布语音教程
反汇编代码如下:
(release版本)
sub_401020 proc near
mov edi, 65h ; 初值
loc_40102A:
mov eax, edi ; eax = edi = 65h
mov ecx, 2 ; ecx = 2
cdq
sub eax, edx
mov esi, eax ; esi = eax
sar esi, 1 ; esi = esi / 2
cmp esi, ecx
jl short loc_40104A ; esi < ecx ->
; esi >= ecx ->
; ecx <= esi
; 不满足条件则跳出内层循环
loc_40103C:
mov eax, edi
cdq
idiv ecx
test edx, edx ;内层循环的内容,如果eax % ecx == 0则跳
jz short loc_40104A ; esi在上面/2了,再+1,可以想到,这一段语句用到了被外提的代码
inc ecx
cmp ecx, esi
jle short loc_40103C ; 满足条件则跳回,被优化的for结构,do_while,如果不满足,向下执行就跳出循环
loc_40104A:
inc esi ; esi在上面/2了,再+1,可以想到,这一段语句用到了被外提的代码
cmp ecx, esi ; ecx在程序里都为递增变量
jl short loc_40105E ; 小于则跳->大于等于则执行
push edi
push offset aD ; "%d "
call printf
add esp, 8
inc ebx ; ebx++
loc_40105E:
mov eax, ebx ; eax = ebx
mov ecx, 0Ah ; ecx = 10
cdq
idiv ecx
test edx, edx ; eax % ecx ==0 则执行语句,否则跳转
jnz short loc_401079 ; 如果输出了10个,则换行
push offset asc_408038 ; "\n"
call printf
add esp, 4
loc_401027: ;
add edi, 2 ;edi+=2(while)
cmp edi, 0C8h ;临界值0C8h
jle short loc_401007 ;edi<=0C8h则跳(向上)
push offset asc_408038 ; "\n"
call printf
add esp, 4
pop edi
pop esi
pop ebx
retn
(release版本)
sub_401020 proc near
mov edi, 65h ; 初值
loc_40102A:
mov eax, edi ; eax = edi = 65h
mov ecx, 2 ; ecx = 2
cdq
sub eax, edx
mov esi, eax ; esi = eax
sar esi, 1 ; esi = esi / 2
cmp esi, ecx
jl short loc_40104A ; esi < ecx ->
; esi >= ecx ->
; ecx <= esi
; 不满足条件则跳出内层循环
loc_40103C:
mov eax, edi
cdq
idiv ecx
test edx, edx ;内层循环的内容,如果eax % ecx == 0则跳
jz short loc_40104A ; esi在上面/2了,再+1,可以想到,这一段语句用到了被外提的代码
inc ecx
cmp ecx, esi
jle short loc_40103C ; 满足条件则跳回,被优化的for结构,do_while,如果不满足,向下执行就跳出循环
loc_40104A:
inc esi ; esi在上面/2了,再+1,可以想到,这一段语句用到了被外提的代码
cmp ecx, esi ; ecx在程序里都为递增变量
jl short loc_40105E ; 小于则跳->大于等于则执行
push edi
push offset aD ; "%d "
call printf
add esp, 8
inc ebx ; ebx++
loc_40105E:
mov eax, ebx ; eax = ebx
mov ecx, 0Ah ; ecx = 10
cdq
idiv ecx
test edx, edx ; eax % ecx ==0 则执行语句,否则跳转
jnz short loc_401079 ; 如果输出了10个,则换行
push offset asc_408038 ; "\n"
call printf
add esp, 4
loc_401027: ;
add edi, 2 ;edi+=2(while)
cmp edi, 0C8h ;临界值0C8h
jle short loc_401007 ;edi<=0C8h则跳(向上)
push offset asc_408038 ; "\n"
call printf
add esp, 4
pop edi
pop esi
pop ebx
retn
sub_401020 endp
源代码:
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
void PrimeFind();//声明求素数的函数
int main()
{
PrimeFind();//调用
system("pause");
return 0;
}
void PrimeFind()//定义
{
int min=101,max=200;//定义求素数的范围
int x,temp,count=0;//101-200内的遍历和2-x内的遍历
for(x=min;x<=max;x+=2)//x在101-200内的奇数递增
{
for(temp=2;temp<=x/2;temp++)//temp在x范围内递增
{
if(x%temp==0)
{
break;//x能被temp整除则跳出(此时证明x不是素数,temp<=x/2+1)
}
}
if(temp>=x/2+1)//for正常跳出,则x是素数【注意】是x/2,不是x
{
printf("%d ",x);
count++;
}
if(count%10==0)
{
printf("\n");
}
}
printf("\n");
}