没有学过逆向,一时兴起,搞了一下这个小软件,名为“逆向分析”,其实过程非常简单,难登大雅之堂,就当段子看吧。
首先介绍一下背景吧。
这是一款国外的Blackjack也就是21点算牌软件,我从来不玩牌的,机缘巧合看到了这个软件搞着玩一下。
21点算牌需要用到Strategy也就是策略,说白了就是算法,从20世纪50年代60年代一直发展到现在,国外的算法大神们研究出了很多厉害的Strategy
这款软件,本身是可以免费使用的,默认免费情况下提供了2个Strategy
在这之外,有两项增值服务,
一是在默认的两个Strategy之外又提供了几十种Strategy
二是可以编辑自定义的Strategy
想要使用这两项增值服务的话,需要向开发商支付$7.99获取License
背景介绍到这里,下面开始演示分析过程。
打开软件,点击“Strategy”可以看到列出了两个免费的Strategy可供选择。
点击“Help”,“Enter License Key”
弹出一个注册框,“Serial Number”标签后有个数字,这里是“61684”
经过测试,当软件在不同的电脑上打开时,这个数字是不同的,在相同的电脑不同的时间打开时是相同的。
因此,我猜测可能是软件读取了某些硬件信息生成了这个数字,并且是与当前时间戳无关的?这个不深究了。
我在“License Key”标签后面随便输入一组数字“12345”试试看,弹出个提示框显示“Invalid Key!”
这个字符串是个典型的标志,等一下会用到。
先用Detect It Easy查一下文件,显示是VB.NET写的。
再用dnSpy载入目标软件。
“编辑”,“搜索程序集”
搜索注册失败时弹出的那个提示字符串“Invalid Key!”,显示它在“btnRegister_Click”里面。
点击“btnRegister_Click”,跳转到目标字符串位置。第457行到480行是这个函数的完整代码,“Invalid Key!”字符串在第478行。
分析一下以上代码,整个函数的执行流程是比较简单的。
第459行对“Me.txtActivationKey.Text”变量的值进行一个判断,如果它是数字形态并且长度大于0就继续向下执行,否则经过一系列跳转最终提示注册失败。
那么这个“Me.txtActivationKey.Text”应该就是由用户输入的License Key了,我们下个断点动态调试来看一下。
没错,结果符合预期。
接下来重点在第462行和第463行
取“Me.txtActivationKey.Text”这个字符串变量的值作为参数,调用Conversions.ToLong()函数将其转换为整型,再将结果作为参数调用Me.CheckKey()函数,
Me.CheckKey()函数会返回一个Boolean值,传递给flag3变量,如果flag3结果为True就提示注册成功,否则就失败。
这样来说,决定成功还是失败的算法,就应该是在Me.CheckKey()函数里面定义的了,点击“CheckKey”跳转到函数定义处。
这个函数更简单了,形式参数“key”是函数调用时传递进来的那个用户输入的值,
紧接着定义了一个变量“num”,应该就是那个“Serial Number”了。
第291行,以“Serial Number”为核心,经过一系列计算得出一个结果值。
第292行,将这个值与用户输入的值“key”进行比对,将Boolean结果返回给调用函数。
总结一下,该函数取随机器而异的一个整数值“Serial Number”经过计算得出另一个整数值“License Key”,如果用户输入的值与函数计算结果相同,即注册成功。
第291行,就是“License Key”的核心算法。
这里,我用Python3以这个小算法写了一个计算函数。
#!/usr/bin/env python3
# -*- coding: utf-8 -*- Serial_Number = float(61684)
License_Key = int(round(Serial_Number * Serial_Number + 134.0 / Serial_Number + 233.0 * Serial_Number / 4.0)) print("Serial Number:\t%s" % int(Serial_Number))
print("License Key:\t%s" % License_Key)
执行
测试一下
注册成功了
增值功能可以正常使用了。