首页
社区
课程
招聘
[原创]对一个求素数的c语言程序的逆向分析
发表于: 2013-11-11 00:14 5449

[原创]对一个求素数的c语言程序的逆向分析

2013-11-11 00:14
5449

(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
    对于这种双重for循环结构,外层循环被优化成do_while循环,最后一个jle为循环条件,根据《C++反汇编与逆向分析技术揭秘》的总结,跳转条件不取反,esi/2为代码外提的语句,首先与2比较,esi/2<ecx则跳,但是根据源码来想就很容易弄迷糊,刚才已经判断为for循环了,所以跳转语句应该是被反向过的,所以esi/2>=ecx时执行循环体内容,也就是不跳,但是ecx才是循环变量,所以应该在取反一次,变成ecx<=esi/2执行循环,这样反向了2次,内层循环的运算结束后为判断跳转语句,同样是do_while结构。
C语言源码:
//1、求出200~1000之间所有的素数,要求:
//调用函数判断某数是不是素数;
//输出结果,每行输出10个素数。
////////////////////////////////////////
#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");
}


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 5
支持
分享
最新回复 (1)
雪    币: 60
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
学习.....................
2013-11-11 07:12
0
游客
登录 | 注册 方可回帖
返回
//