序列号保护方式

一些程序和软件可能会有时间或功能上的限制,需要注册方能继续使用,注册过程一般是通过输入的用户信息通过一系列计算得出一个序列号,当注册信息验证通过后就会取消各种限制,从而成为完全正式版本。
每次启动时,程序或软件会从磁盘文件或者系统注册表中读取注册信息并进行检查,如果注册信息正确,则以正式版的模式运行,否则将作为有功能限制的版本来运行。

程序验证序列号其实就是验证用户名和序列号之间的数学映射关系,因为这个映射关系是由程序的设计者指定的,所以各个程序生成序列号的算法是不同的。显然,映射关系越复杂,序列号就越不容易被破解。

根据映射关系不同,程序检查序列号有如下四种方法:

  • 按用户输入的用户名来生成注册码,再同用户输入的注册码比较。
    映射关系:序列号=F(用户名)
    将正确的注册码和输入的注册码进行比较。我们就可以通过分析程序验证注册码的过程,很容易获得注册码。

    这种方法在检查注册码正确性的同时,也再现了生成注册码的过程,就可以编制一个通用的注册码程序即注册机。

    由此可见,这种生成检查注册码的方法是非常不安全的,我们也可以通过修改指令的方法来爆破通过注册码的检查。

  • 通过序列号验证用户名的正确性
    生成注册码仍是 序列号=F(用户名) 这种变换,但程序在检查注册码正确与否的时候,是利用F的逆变换即对用户输入的注册码进行变换的。如果变换的结果和用户名相同,则说明是正确的注册码。即用户名=F -1(序列号)
    解决方法: 通过F -1 找出其逆变换,从而得到正确的注册码或写出注册机。
    给定一个注册码,利用用户名=F (序列号)变换出一个用户名,从而得到一个正确的组合

  • 通过对等函数检查注册码
    如果输入的用户名和注册码满足F1(用户名)=F2(序列号),F1、F2是两种完全不同的的算法,但用户名通过F1算法的计算出的特征字等于序列号通过F2算法计算出的特征字,则认为是正确的注册码,如果F2是一个可逆函数,则为第二种方法的推广,解密方法也类似。

  • 同时将用户名和注册码作为自变量(即采用二元函数)
    当对用户名和序列号进行变换时,如果得出的结果和某个特定值相等,则认为是正确的用户名-序列号对
    特定值=F3(用户名,序列号)
    这种算法使用户名和注册码之间的关系不再那么清晰,同时可能失去了用户名与序列号之间的一一对应关系,导致无法写出注册机。

以上都是序列号与用户名相关的情况,序列号也可以和用户名没有关系。即使序列号算法再复杂,如果程序可以被任意修改,还是可以通过修改指令使程序成为正常使用。

若要找到序列号,或者修改关键跳转指令,最重要的是利用各种工具来定位判断序列号的代码段

  • 常见API
    通过追踪输入注册码后的判断找到注册码,通常用户会在一个编辑框中输入注册码,程序需要调用一些API将用户输入的注册码字符串复制到自己的缓冲区中,利用OD对API的断点设置功能,就可以找到判断注册码的地方。
    常见的API:
GetWindowTextA(W)//该函数将指定窗口的标题条文本(如果存在)拷贝到一个缓存区内
GetDlgItemTextA(W)//,调用这个函数以获得与对话框中的控件相关的标题或文本。

等程序完成对注册码的判断流程后,一般会显示一个对话框,告诉用户注册码是否正确。
常见的用于显示对话框的API包括MessageBoxA(W)、MessageBoxExA(W)、ShowWindow等

  • 数据约束性
    在大多数序列号保护的程序中,那个正确的序列号会于某个时刻出现在内存中,当然它出现的位置是不定的,但多数情况下它会在一个范围之内,真正的序列号会在离保存用户输入的序列号不远的地方出现。
    只在用明文比较序列号的保护方式中使用。
    在这里插入图片描述在这里插入图片描述

  • 利用消息断点
    许多程序都有按钮,当按下和释放鼠标时,将发送WM_LBUTTONDOWN、WM_LBUTTONUP消息,因此用这个消息下断点很容易找到按钮事件代码。

  • 利用提示消息
    程序在执行一段程序之后会显示提示信息,可以用OD的智能搜索工具查找出现的提示信息,直接定位到所需代码处。

注册机编写器keymake

注册机编写器是一个很特殊的软件,它可以快速地生成一个注册机,而不需要再过多的了解程序的指令算法。
在这里插入图片描述
在这里插入图片描述

参数 解释
中断次数 即指在该位置连续中断多少次
第一字节 当前设置的中断位置处反汇编后的第一个字节。
指令长度 当前中断位置反汇编后的长度。
寄存器方式 注册码可能是会放在寄存器中比较,并且可能经过十进制或十六进制的转换,所以就提供了一个寄存器方式及十进制或十六进制的选项。
内存方式 如设置为EAX,即指注册码保存在EAX所指向的内存地址中(而不是寄存器里)。
偏移地址 如注册码在eax+64的位置,则以在偏移地址处填入64,eax-64,就填入-64.
宽字符串 一般在VB程序中出现
地址指针 如果eax处值是123456,而123456里的值又是654321,654321所指向的地址才是注册码所在呢,所以加入了一个“地址指针”,比如说要从654321里取注册码,就不要选择地址指针;如果要从123456里取注册码就选择地址指针,并将其值设置为1;如果要从eax里取注册码就选择地址指针,并将其值设置为2。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第一字节:中断位置处反汇编后的第一个字节E8、50
指令长度:当前中断位置反汇编后的长度5、1
内存方式:注册码保存在EBP所指向的内存地址中
在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43916678/article/details/103548980