本题的难点在于输入的内容会被分散的存放在作者构造的表中,影响判断的跟进。不过只要弄清楚对表特定位置内容的操作等同于对输入数据的操作就可以解决这样一个问题。
首先是判断输入的内容和长度,要求输入数字并且在8到16位。

之后的sub_4012c0和sub_4014e0是初始化表和将输入内容存到表中的操作。存放的方式是将输入内容的每一位分散的存放在表的不同位置中。完成一次操作后会修改一次存放的位置。不过深入跟进就可以发现虽然位置一直在变,但处理的还是那些数。

接下来的sub_401730函数是将输入内容乘9的操作。由于作者把每一位存放到不同位置中,因此这个乘法也比较特殊。先把每一位乘9,然后如果某一位乘9之后大于10的话,就保留个位数,将十位数进位到下一位。这样其实就是把输入的数乘9。值得一提的是,输入的首位是作为个位,输入的末位是最高位。也就是计算时是对输入的倒序进行计算的。

接下去到while循环里的计算过程,关键函数是sub_401840函数。sub_401840函数里面主要还是执行sub_401730。只不过两个乘数发生了变化。在这里是上一步算得的值左移后再乘以输入的每一位后累加。例如,上一步算的的值为11111,输入的值为54321.那么这一步就是11111*5+111110*4+1111100*3+11111000*2+111110000*1。其实不难发现,这就等于11111*12345。所以这一步其实就是将上一步算的的值再乘以输入的倒序对应的数字。因为计算流程就是sub_401730函数,在这就不贴图了。
接下去还是一个sub_401730,这回传参固定是9,所以就还是对上一步算的的值乘9。
至此对输入的计算流程已经结束。假设输入为n,则计算过程为(n*9)*n*9,其实就是(n*9)^2。
[培训]科锐逆向工程师培训第53期2025年7月8日开班!