加密与解密——序列号保护方式

序列号保护的本质就是验证用户名和序列号之间的映射关系,越复杂的映射关系越难破解,根据映射关系的不同,程序检测序列号有以下几种方式:

  • 序列号 = F (用户名)

    • 如果把这个过程看作加密解密并进行密文对比的过程,那么用户名就是明文,而序列号则是密文,F函数就是加密算法了。这种保护方法虽然简单,但极为不安全,因为在程序运行的某一时刻,内存中一定会出现正确的序列号,也就是加密函数结束后。只要找到正确的时间点,甚至完全不用关心算法就可以完成验证。

  • 用户名 = F (序列号)

    • 这里是把序列号作为明文,用户名作为密文了,这种方式通常需要F函数是一种对称加密算法的解密函数,而官方生成序列号时则使用加密函数对用户名进行加密得到的,这样就不会出现内存中有正确序列号的情况。这种保护方式的关键就是解密算法了,一旦得到解密算法就有机会逆向出加密算法,这样也就完成了验证。

  • F1 (用户名) = F2 (序列号)

    • 这种方式是上一种的扩展,它相当于多套了几层加密而已。验证方式是:用户名 = F( F2(序列号) )

  • 特殊值 = F (用户名, 序列号)

    • 这种保护方式的数学原理就比较复杂了,但保护效果相比前几种有了很大提升。不过在设计上有难度,并且可能出现用户名与序列号映射不唯一的情况。

攻击方式

所谓攻击方式,就是要找到关键的验证算法处,再进行对算法的逆向和分析,通常由以下几种方式找到关键点

1.数据约束

若序列号以明文的方式出现在内存中,它的位置很可能在我们输入的序列号附近。因为许多软件制作者都会以局部变量的形式来存储输入的序列号和临时计算出的序列号

2.消息断点

要验证序列号时,往往会点击一个check按钮,通过追踪WM_LBUTTONDOWN和WM_LBUTTONUP两个鼠标按下和释放的消息,很容易找到按钮的事件代码,而验证算法很可能就在其中

3.利用提示信息

人机交互中一系列提示信息,可以直接通过搜索关键字符串定位关点

关键API断点

最常用的方式,如MessageBoxA,GetWindowTextA,GetDlgItemInt,GetDlgItemTextA等等

 

字符串比较方式

要进行序列号验证,势必会进行字符串比较,字符串比较之后很大可能跟上的就是条件跳转指令,如果程序只是简单的将所有比较放在同一个循环体中,那只需要简单的修改关键跳转指令即可,所以保护方通常会迂回的对字符串进行比较,在多个地方进行离散的比较和判断,并插入花指令和SMC等技术来干扰破解者。

比较方式通常只有三种,当遇到这些东西时,要格外留意

  1. 直接寄存器的比较
  2. 作为参数传入比较函数
  3. repz cmpsd指令进行串比较

猜你喜欢

转载自blog.csdn.net/qq_35713009/article/details/86603647