逆向分析练习二(回文数判断)

逆向分析练习二(回文数判断)

今天依旧是debug版本的反汇编代码逆向分析,等能够熟练的分析debug版本的汇编代码后再看o1和o2优化下的代码会更简单。

这次分析的代码包含了大量的除法和取余数运算,如果没有对这方面指令使用经验的话也算是比较难了

能够帮助大家快速了解到除法运算这方面的逆向实现

题目描述

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

  • 例如,121 是回文,而 123 不是。

debug版汇编代码

00763580  push        ebp  														//依旧是保存并提升栈
00763581  mov         ebp,esp 
00763583  sub         esp,0D8h 
00763589  push        ebx  
0076358A  push        esi  
0076358B  push        edi  
0076358C  lea         edi,[ebp-0D8h] 
00763592  mov         ecx,36h 
00763597  mov         eax,0CCCCCCCCh 
0076359C  rep stos    dword ptr es:[edi] 			//从这里开始下面则是业务代码
0076359E  cmp         dword ptr [x],0 				//这里应该是判断x>=0
007635A2  jl          isPalindrome+39h (7635B9h) //这里如果<0就跳到7635B9h
007635A4  mov         eax,dword ptr [x] //这里eax=x
007635A7  cdq              							//执行cdq根据eax是否大于 8000 0000来设置edx
007635A8  mov         ecx,0Ah 					//ecx = 10
007635AD  idiv        eax,ecx 					//eax = eax/10
007635AF  test        edx,edx 					//判断edx是否为0
007635B1  jne         isPalindrome+3Dh (7635BDh) //这么看来这里应该是对x除法后的余数判空
007635B3  cmp         dword ptr [x],0 						//如果小于10了就结束
007635B7  je          isPalindrome+3Dh (7635BDh) 
007635B9  xor         al,al 										//所以说这里应该是一个块的结束
007635BB  jmp         isPalindrome+95h (763615h) //这里似乎直接跳转到结束了
007635BD  mov         dword ptr [flag],0 			//又一个块的开始,flag=0
007635C4  mov         eax,dword ptr [x] 		//eax = x
007635C7  mov         dword ptr [t],eax 		//t=x
007635CA  cmp         dword ptr [x],0 			//x>0  //从下面看回来会发现这是一个循环的开始
007635CE  jle         isPalindrome+76h (7635F6h) //一个块的开始
007635D0  mov         ecx,dword ptr [flag] 	//ecx = flag
007635D3  imul        ecx,ecx,0Ah 			//flag*10
007635D6  mov         eax,dword ptr [x] //eax = x
007635D9  cdq              							//这是又要做除法了
007635DA  mov         esi,0Ah 
007635DF  idiv        eax,esi 
007635E1  add         ecx,edx     //这上面应该是一个除10之后对余数做加法到ecx
007635E3  mov         dword ptr [flag],ecx 	//flag = ecx
007635E6  mov         eax,dword ptr [x] 	//eax = x
007635E9  cdq              
007635EA  mov         ecx,0Ah 
007635EF  idiv        eax,ecx 
007635F1  mov         dword ptr [x],eax //这次只做除法然后写回x
007635F4  jmp         isPalindrome+4Ah (7635CAh) //跳回循环的头部
007635F6  mov         eax,dword ptr [t] 	//跳出
007635F9  cmp         eax,dword ptr [flag] 
007635FC  je          isPalindrome+8Dh (76360Dh) 
007635FE  mov         eax,dword ptr [t] 
00763601  cdq              
00763602  mov         ecx,0Ah 
00763607  idiv        eax,ecx 
00763609  test        eax,eax 
0076360B  jne         isPalindrome+93h (763613h) 
0076360D  mov         al,1 		//这里是返回1
0076360F  jmp         isPalindrome+95h (763615h) 
00763611  jmp         isPalindrome+95h (763615h) 
00763613  xor         al,al 		//这里是返回0
00763615  pop         edi  
00763616  pop         esi  
00763617  pop         ebx  
00763618  mov         esp,ebp 
0076361A  pop         ebp  
0076361B  ret          

分析

这里只做简略的描述,具体的分析在汇编代码的注释中

  1. 首先按流程看下来看到0076359C这里发现这是个比较跳转可以初步判定7635B9h这里应该是一个块的结束
  2. 在这块代码中间有一个新接触到的指令cdq下面简单介绍一下这个指令
    1. 这个指令把 EAX 的第 31 bit 复制到 EDX 的每一个 bit 上。 它大多出现在除法运算之前。它实际的作用只是把EDX的所有位都设成EAX最高位的值。也就是说,当EAX <80000000, EDX 为00000000;当EAX >= 80000000, EDX 则为FFFFFFFF。
  3. 看到cdq就应该知道下面应该是一个除法操作,继续往下看,会发现确实如此,在对x除10
  4. test指令:对两个操作数做and运算,并改变标记位
int func (x){
  if(x < 0 || (x%10==0 && x != 0)) return 0;
  int flag = 0,t=x;
  while(x>=0){
    flag = flag*10 + x%10;
    x=x/10;
  }
  if(t != flag){
    if(x/10==0)
      return 1;
  }
  return 0;
  
}

源代码


bool isPalindrome(long int x){
  if(x<0||(x%10==0&&x!=0)){
  return false;}
  long int flag=0;long int t=x;
  while(x>0){
      flag=flag*10+x%10;
      x/=10;
  }  
  if(t==flag||t/10==0){
  return true;}
  else {
  return false;
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值