演示版保护技术
序列号保护方式
从网上下载的共享软件一般都有使用功能或者时间上的限制,如果超过了共享软件的试用期,注册过程一般是用户把自己的信息告诉软件公司,软件公司根据用户的信息,利用预先编写的一个用于计算注册码的程序算出一个序列号,并以电子邮件等形式将其发给用户。用户得到序列号之后在软件中输入注册信息和序列号。当注册信息验证通过后,软件就会取消各种限制。
序列号保护机制:
软件验证序列号其实就是验证用户名和序列号之间的数学映射关系。因为这个映射关系是由软件的设计者制定的,所以各个软件生成序列号的算法是不同。显然,映射关系越复杂,序列号越不容易破解。根据映射关系的不同,程序检查序列号有如下4种基本方法。
(1)将用户名等信息作为变量,通过函数F变换之后得到注册码
解密者可以很简单的通过修改比较指令的方法来通过注册码检查
(2)通过注册码验证用户名的正确性
这里要求F是一个可逆的变换,这样显然更加安全
(3)通过对等函数检查注册码
如果输入的用户名和序列号满足式,则认为是正确的注册码。采用这种方法,同样可以是现在内存中不出现注册码的明文,如果F2是一个可逆函数
(4)同时将用户名和注册码作为自变量(即采用二元函数)
当对用户名和序列号进行变换时,如果得出的结论和某个特定的值相等,就合法。
如何攻击序列号保护机制:
若想修改序列号之后的跳转指令,最重要的就是利用各种工具来定位判断序列号的代码段。
一种办法是通过跟踪输入注册码之后的判断找到注册码。软件需要调用一些标准的API将用户输入的注册码复制到自己的缓冲区。
另一种办法是跟踪程序启动时对注册码的判断过程(因为程序每次启动时都需要将注册码读出并加以判断)从而决定是否以注册版的模式工作。根据序列号存放位置不同。
1数据约束的秘诀
在大多数序列号保护程序中,哪个真正正确的注册码会于某个时刻出现再内存中,当然,它出现的位置是不定的,但多数情况下它会在一个范围之内,即存放用户输入序列号的内存地址+-90h的地方。
依据是:加密者在编程的时候需要留意保护功能是否”工作“,必须看到用户输入的数字,以及用户输入的转换结果和真正的密码之间的关系,这种联系必须经常检查以调用这些代码。通常,它们会共同位于一个小的栈区域中。
2.hmemcpy函数
hmemcpy函数(俗称”万能断点“)是windows 9x系统的内部函数,它的作用是将内存中的一块数据复制到另一个地方。由于windows 9x系统频繁使用该函数处理各种字符串,将该函数作为断点是非常实用,该函数也成为windows9x/Me平台最常用的断点。windowsNT /2000以上版本的系统中没有这个断点,因为其内核和windows9x完全不同。
3.利用消息断点:
许多序列号保护软件都有一个按钮,当按下和释放鼠标时,将发送Wm_LBUTTONDOWN(0201h)和WM_LBUTTONUP(0202h)消息。因此用这个消息下断点很容易就能找到按钮的事件代码。
4.利用提示信息
目前大多数软件在设计时采用了人机对话的方式。所谓人机对话,即软件在执行一段程序之后会显示一串提示信息,以反映该段程序运行后的状态。
5.字符串比较形式
(1)寄存器直接比较
mov eax [ ] ;eax或ebx中存放的是直接比较的两个数,一般是十六进制数
mov ebx [ ] ;
cmp eax,ebx ;直接比较两个寄存器
jz(jnz) xxxx
(2)函数比较a
mov eax [ ] ;比较数字直接放在eax中,一般是16进制数,也可能是地址
mov ebx [ ] ;
call xxxxxxxx;用于比较功能的函数,可以是API函数,也可以是程序作者自己编写的比较函数
test eax,eax
jz(jnz)
xxxxxxxx:
cmp xxx,xxx
jz Lable
xor eax,eax ;将eax清零
Lable:
pop edi
pop esi
pop ebp
ret ;函数返回
(3)函数比较b
push xxxxx;参数1可以是寄存器,也可以是地址
push xxxxx;参数2
call xxxxxxxxx
jz(jnz)
(4)串比较
lea edi [ ] ;edi指向字符串a
lea esi [ ] ;esi指向字符串b
repz cmpsd ;比较a 和 b
jz(jnz)
菜单功能限制
·试用版和正式版软件是两个完全不同的版本,没有好的解决办法
·另一种是试用版和正式版为同一个文件,使用一定方法恢复被限制的功能就可以正常使用。
相关函数:
·EnableMenultem函数
BOOL EnableMenuItem(HMENU hMenu,UINT uIDEnableItm,UINT uEnable);
//hMenu:菜单句柄
//uDIEnableItem:欲允许或禁止的一个菜单条目的标识符
//uEnable:控制标志,包括MF_ENABLED(允许,0h)MF_GRAYED(灰化,1h),MF_DISABLED(禁止,2h),MF_BY
//COMMAND 和MF_BUPOSITION
//返回值:返回菜单项以前的状态。如果菜单不想存在,就返回FFFFFFFFh
BOOL EnableWindow(HWND hWnd ,BOOL bEnable);
//hWnd:窗口句柄
//bEnable:TRUE为允许,FALSE为禁止
Key File保护
Keyfile是一种利用文件来注册软件的保护方式。KeyFile一般是一个小文件,可以是纯文本文件,也可以是包含不可显示字符的二进制文件。其内容是一些加密或者未加密的数据,其中可能有用户名,注册码啊等信息,文件格式则由软件作者自己定义。试用版本没有注册文件。当用户向作者付费注册之后,会受到作者提供的注册文件,其中可能包含用户的个人信息。用户只要将该文件放入指定的目录,就可以让软件成为正式版了,该文件一般放在软件的安装目录下或者系统目录下。
相关API函数
几乎所有与windows文件有关的API函数都可以被追踪。
拆解KeyFile保护
拆解keyFile的一般思路:
(1)用Process Monutor等工具监视软件对文件操作,以找到Keyfile的文件名。
(2)伪造一个KeyFile文件。用16进制工具编辑和修改keyFile
(3)在调试器里用CreateFile函数设断,查看其打开的文件名指针,并记下返回的句柄,
(4)用Readfile函数设断,分析传递给ReadFile函数的文件句柄和缓冲区地址。文件句柄一般和第三步返回的相同。
网络验证:拆解网络验证的思路是拦截服务器返回的数据包,分析程序是如何处理数据包的。
破解网路验证的一般思路:如果网络验证的数据内容固定,可以将数据包抓取,写一个本地服务端来模拟服务器。如果验证的数据包内容不固定,则必须分析其结构,找出相应的算法。
光盘检测:
一些采用光盘形式发行的应用软件和游戏,在使用时需要检查光盘是否插在光驱中,如果没有则拒绝允许。
揭密折只需要在相应函数下断点,修改判断指令,就可以跳过光盘检测。
只运行一个实例
windows是一个多任务操作系统,应用程序可以多次运行以形成多个运行实例,要求程序只能运行一个实例。
常用断点设置技巧

浙公网安备 33010602011771号