• 欢迎访问C语言网www.dotcpp.com 比赛栏每月有奖月赛!举办比赛联系QQ:2045302297
  • 问题反馈、粉丝交流 QQ群327452739 蓝桥杯训练群:113766799 申请群时请备注排名里的昵称
  • C语言研究中心 为您提供有图、有料、解渴的C语言专题! 欢迎讨论!

C语言逆向之表达式短路分析及应用

C语言研究中心 CTO 11490次浏览 1个评论

大家在学习C语言过程中,可能会见到过一些这样的题,就是表达式短路,表达式短路主要体现在C语言中逻辑运算符&&和||。今天将对表达式短路的做逆向分析,来深入理解它。

 

首先利用表达式短路,我们可以写一个很经典的累加求和的函数,代码如下:

C语言逆向之表达式短路分析及应用

 

功能很简单,就是求1+2+…+99+100的数字和的一个程序,但用递归写了出来,利用逻辑与运算,左边判断是否递归到0,右边累加求和,其中的技巧巧妙的运用逻辑与运算的短路特点,实现累加的效果。请大家自行分析理解~

下面我们断点反汇编,查看重点num && (num += Add(num-1));语句的汇编代码,如下

 

 

C语言逆向之表达式短路分析及应用

 

 

下面详细分析:

 

;比较num是否为0! 这里也就是逻辑与表达式左边的判断!

0040D718       cmp         dword ptr [ebp+8],0

;判断ZF标志位是否为1然后进行跳转,到return处

0040D71C       je          Add+35h (0040d735)

;继续把num变量送入eax寄存器

0040D71E       mov         eax,dword ptr [ebp+8]

;对num减1

0040D721       sub         eax,1

;结果作为参数,压栈准备进入递归调用

0040D724       push        eax

;继续调用Add函数,地址位于0040100a处

0040D725       call        @ILT+5(_Add) (0040100a)

;栈清空

0040D72A       add         esp,4

;将num里的值放入ecx寄存器里

0040D72D       mov         ecx,dword ptr [ebp+8]

;进行累加运算

0040D730       add         ecx,eax

;放回num地址处

0040D732       mov         dword ptr [ebp+8],ecx

;此处为return num 返回Add函数结束

0040D735       mov         eax,dword ptr [ebp+8]

 

 

大家通过阅读汇编代码,上下文联系应该就可以分析出来,递归调用时候的每次参数递减,进行累加求和,正因为逻辑与运算的短路特点会先判断左边num的值是否减到了0来决定是否还算右边的表达式,汇编代码对应num为0时JE比对跳转到return处;而为假时继续计算右边表达式,进行call命令递归调用,栈地址不断变化直至0结束return返回。

大家仔细体会!

 

以上就是逻辑与运算中短路的特点以及运用短路来实现语句中断的例子!逻辑或原理也相同,大家可以自行实验!欢迎讨论!

 

C语言研究中心(www.dotcpp.com)

C语言网提供「C语言、C++、算法竞赛」在线课程,全部由资深研发工程师或ACM金牌大佬亲授课,更科学、全面的课程体系,以在线视频+在线评测的学习模式学习,学练同步,拒绝理论派,真正学会编程!还有奖学金等增值福利等你!

C语言网, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C语言逆向之表达式短路分析及应用
喜欢 (28)
[jinyangH@aliyun.com]
分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
(1)个小伙伴在吐槽
  1. 老师 这个代码是不是一直在重复调用函数,直到上面这个表达式中的左边的num因为调用函数运算的结果为零了,然后这个调用就结束了,也就是不在运算表达式左边的值了。也就是不再调用而是执行加最后一个零了。
    宸宸2017-05-16 08:49 回复