逆向-取模运算

除法终于整理结束了,这篇开始整理取模运算,对于取模运算来说,个别的情况还是需要使用除法的,所以除法运算的基础还是得牢靠。

取模也叫取余,表达为 a % b。下面需要对b的情况进行区分来分析

1. 变量
2. 常量
    2.1 无符号
        2.1.1 2的幂
        2.1.2 非2的幂
    2.2 有符号
        2.1.1 2的幂
            2.1.1.1 正数
            2.1.1.2 负数
        2.1.2 非2的幂

首先,这里和除法一样,对于为变量时候,都是没有优化的,所以直接会使用div/idiv指令,可以据此判断出有无符号,取模的结果在edx中。

下面主要探讨常量的情况,先来补充一点基础知识,先看如下代码

	printf("%d\r\n",8%3);
	printf("%d\r\n",8%-3); 
	printf("%d\r\n",-8%3); 
	printf("%d\r\n",-8%-3);

上面的运算结果

2
2
-2
-2

如果对于结果有误的可以看下面的公式

设被除数为a,除数为b,商为q,余数为r
a / b = q ..余.. r
=> a = q*b + r
=> r = a - q*b;  //求余公式

也就是说余数等于被除数减去商乘以除数,这里应该比较好理解。这里对于某些情况中,取模也会使用该公式进行优化。

我们挑最后第三个来套一下公式看是否正确,剩余几个同理可求得

-8%3
已知除法向零取整,-8/-3可得商q=-2
r = a - q*b
  = -8 - -2*3
  = -8 + 6
  = -2

OK,其实对于上面的结果来说,其实我们还可以得出一个规律,就是余数的符号跟着被除数走,这里的应用具体后面会提。

 

好了,下面来看2.1.1情况,也就是无符号中2的幂情况,对于无符号的情况,debug都不优化,主要来看release中的情况

int main(unsigned int argc, char* argv[])
{
    printf("%d",argc%8);
    return 0;
}

对应汇编代码

.text:00401043                 mov     eax, [ebp+argc]
.text:00401046                 and     eax, 7
.text:00401049                 push    eax

可以发现,其取模的结果就用了一个and 7,下面我们来分析一下<

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值