嘿嘿~~~~~~~~将这个软件破解过程传上来!希望此文能够对采用SQL大型数据库后台的软件CRACK有一点了帮助!!!!
兄弟水平有限,希望各位兄弟不要笑我~!!!!!
进入正题!!
首先了解这个软件!!!其实破解这个软件,真的费了好多周折,注册机的制作完全靠Moodsky的提示!!!
软件采用本机生成机器码,提供正确注册用户名+注册号注册
这个一个进销存软件,因为是国产软件,为了保护国内软件版权,这里就不提是什么软件了!!!!!!!和各位老大们的要求一样,我们练习的软件尽量采用国外软件练习!!!
这里在描述破解过程时,首先提醒菜鸟,在破解过程中,要心细,观察软件各种可利用的线索,因我也是菜鸟,在破解这个软件之前,也没有这种习惯,但是经过这一次,真的是受益菲浅!! 这个软件,我用了将近半个月的时间!!~~~~~~~~~~~~~菜鸟啊~~~
闲话少说,开始!!!!拽~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
破解这个程序,我主要做了三种尝试,下面给大家详细唠叨一下!大家如果感觉?嗦,可直接跳到第三部份,观看精彩部份!
第一部份:动静结合部份
首先查壳!!无壳,C++编写!
小提示:
(这里提示一点,软件安装完毕,主执行程序只有几十K,采用SQL数据后的软件,一般整个目录都有几十M,因为这种软件都有好多数据库查询语言和SQL里所谓的存储过程)
非常让人奇怪,这个软件的主程序只有几十K,而且安装目录里有好多以.PBD文件为扩展名的文件,所以,确定软件有一部份由PB ,简称powerbuild编写。
我们一般正常调试程序,以静+动,对于这个软件,
首先以W32ADSW分析,没有可分析资源,因为主程序只有几十K~~~~~,资源都在外部文件里。
之后,以OD载入,查找可利用字符串是行不通的。指定找不到什么,下断点BP MessageBoxA,断在系统领空。返回后到了PBVM90.DLL里了,反正是转来转去,搞的人晕头转向!再加上菜鸟我的这点能耐,这条路是趟不下去了!!!!
因为这次,主要以分析PB程序为主,所以,这里此部份不再详述!!
第二部份,采用物理硬盘序列号加密的软件,是否可以将物理硬盘序列号更改为正式注册硬盘,使软件免注册?
我们一般调试程序,都会查看程序安装目录或安装时,会向硬盘内安装哪些文件,实现这个目的,你用文件监视或注册表监视工具即可!!!
我这里的程序安装目录内,除了一部分C++的DLL外,就是.PBD的文件,这里有一个DLL让我比较怀疑,所以用EXECOPE分析,此DLL里有提取本机硬盘序列号的函数在!知道这些,可以确定程序提取硬盘序列号加密后生成机器码,那我就用我的法宝pc3000将我的硬盘更改物理序列号为注册过软件的电脑硬盘,注册过软件的电脑硬盘是WD---西数的,我的硬盘是ST--西捷的,将物理序列号更改之后,再用更改虚拟序列号的软件将C盘序列号也更改之,这里的前提我将注册过的那台电脑上的硬盘序列号和C盘序列号记下了!!最后安装软件,用正确注册用户号和注册码注册,不成功!!!这里,到最后也没研究明白哪里出了错误?
个人分析:此种方法,个人感觉应该可以成功,原因是软件如果单纯提取硬盘物理序列号加密,如果你知道了其中一个正确的注册码,应该可以,有机会再详细研究之!!!
第三部份:刚才说过了,软件安装目录有好多PBD的PB文件,这里首先对PB做一个简单的概述吧!
PowerBuild 简称pb,是于1984年成立的美国数据库厂商SYBASE公司的一个十分著名的数据库应用开发工具,PB能够快速开发出基于客户/服务器的图形化数据库应用程序,目前SYBASE数据库软件产品是市场上较受欢迎的数据库产品之一。大约在1991年,sybase及pb进入我国市场,目前许多行业和部门都应用了它的产品。
我们CRACK PB类程序时,一般使用PBKILL或PB DE工具,这些工具一般都能很好的将这些PB文件的内容返出来!
对于这个程序,我在用PBKILL分析PBD文件之前,我已经知道程序目录里的一个DLL文件,M.DLL它就是提取本机机器码,所以,我将它删除或剪切到其它地方,再运行程序,发现程序有出错提示,而且原本出现机器码的控件已经是空的了,这就是关键,我们看一下出错的提示,它告诉我们,出错在w_window窗口(就是带有注册按钮的窗口)和M.dll里,现在就清楚多了,我们只要找有w_window窗口的PBD文件就可以了,至少不用漫无目的的乱找了。
终于,PBKILL在pub.pbd里找到了这个窗口。而且找到了关键部份,我把内容都分开列出来 ,供大家参考,免得大家看着乱,心烦就不看了~~
这部分是通过m.dll文件,提取机器码用的,定义函数!!!
type prototypes
function ulong mk_9xhdserial () library "m.dll" alias for "mk_9xhdserial"
function ulong mk_nt2000hdsector () library "m.dll" alias for "mk_nt2000hdsector"
function ulong mk_9xiderw (integer funcx) library "m.dll" alias for "mk_9xIDERW"
end prototypes
forward prototypes
public function string get_serial (integer getfunc_n) //get_serial重要的干活!!!
end prototypes
这部份是get_serial精华部分,制作注册机时,如果不使用下面代码,无法注册成功的1!!!
public function string get_serial (integer getfunc_n);ulong dve_2
ulong my_getdiskv
ulong my_getdiskexv
ulong my_diskv
string my_diskv_st
string st1
string st2
string st3
string st4
string st5
string st6
string vl_1
boolean b2 = false
environment en1 //EN1 环境
getenvironment(en1) //呼叫EN1环境,B2为假,my_getdiskv=0,my)getdiskexv=0
b2 = true
my_getdiskv = 0
my_getdiskexv = 0
if en1.ostype = windows! then
b2 = true
dve_2 = mk_9xiderw(1)
else
b2 = false
dve_2 = mk_nt2000hdsector()
end if
if dve_2 = 255 or dve_2 = 0 then
return "000000"
end if
my_getdiskexv = -1 - dve_2
st1 = string(my_getdiskexv)
st2 = right(st1,8)
st3 = mid(st1,1,7)
my_diskv = long(st2) + long(st3)
if my_diskv < 100000 then
my_diskv_st = "000000"
return "000000"
else
my_diskv_st = string(my_diskv)
end if
choose case getfunc_n //当getfunc_n返回如下两种值时,各参数分别为
case 2
my_diskv_st = left(string(mod(long(left(my_diskv_st,6)) * 367 + long(right(my_diskv_st,6)) * 389,100000000)),6)
case 9
my_diskv_st = reverse(my_diskv_st) //my_diskv_st全部从后向前排列
st1 = mid(my_diskv_st,1,4)
st2 = mid(my_diskv_st,3,4)
st3 = mid(my_diskv_st,6,3)
st4 = mid(my_diskv_st,5,4)
st5 = mid(my_diskv_st,4,3)
my_diskv = (integer(st1) + integer(st2) + 331) * 89
my_diskv = my_diskv + integer(st3) * 13
my_diskv = my_diskv + integer(st4) + integer(st5) * 3
my_diskv_st = string(my_diskv)
end choose
return my_diskv_st
end function //getfunc过程,返回值my_diskv_st
最核心算法就是这部份!!!
最终注册码= dec(left(string(dec(ul1 * 449 + ul2 * 739)),9))
------------------------------------------------------
下面是对核心算法里各变量的类型定义
event clicked;string inputid_str
string my_getid
string st4
string st5
string st6
string s_sle
string s_bbh_hy
string my_getid1
integer zc_bs
decimal ul1
decimal ul2
decimal ul3
decimal ul21
decimal ul3_tmp
decimal ls_tmp
下面是核心算法里各变量的由来!!!!!
s_sle = parent.sle_1.text
s_sle = mid(s_sle,1,2)
inputid_str = right(trim(parent.sle_1.text),6)
ul1 = dec(inputid_str)
inputid_str = trim(parent.sle_3.text)
ul3 = dec(inputid_str)
my_getid = parent.get_serial(2)
ul2 = dec(my_getid)
my_getid = parent.get_serial(9)
ul21 = dec(my_getid)
uo_1 = create user_object
my_getid = uo_1.get_number(2)
my_getid1 = uo_1.get_number(9)
===========================================================
以上都是PB的类型和语句,因为本人不会PB,只好改用VB改做注册机
VB注册机是这么做的,因为对M.DLL文件没有太详细的分析,所以,这里注意,VB注册机一定要把上面我写的get_serial部分带上,调用M.DLL里的函数,所以,最后的注册机要把M.DLL也一起放到注册机所在目录里
Function GetRegcode(machine As String, user As String) As String
Dim s_sle As String
Dim inputid_str As String
Dim ul1, ul2, ul3, ul3_tmp
Dim my_getid As String
Dim my_getid1 As String
s_sle = user '用户名
s_sle = Mid(s_sle, 1, 2)
inputid_str = Right(Trim(user), 6)
ul1 = CLng(inputid_str)
my_getid = get_serial(2)
ul2 = CLng(my_getid)
最终注册码等于 ul3_tmp = CLng(Left(CStr(ul1 * 449 + ul2 * 739), 9))
GetRegcode = ul3_tmp
End Function
好了,整个注册的制作内容基本上就是这些,虽然对PB不太熟悉,但是改用VB做注册机唯一注意的就是在类型转换时,VB和PB的转换函数是不同的。
我们可以看出来,软件一直在进行类型转换,一下不小心,就会转换错误,灾了!!
在这里,再次感谢moodsky大哥提供技术支持!!!茫茫大东北,终于找到一个至友,邻居啊!!~~~~~~~~~~~
我们对比一下,核心算法
PB里最终注册码= dec(left(string(dec(ul1 * 449 + ul2 * 739)),9))
VB里最终注册码= CLng(Left(CStr(ul1 * 449 + ul2 * 739), 9))
对PB类程序的破解总结:
这类程序一旦找到突破口,一般情况下会直接将注册算法直接提取出来,只要推理出一个详细的算法过程,做个注册机就不难了。
把PB里各个转换函数简单解释给大家发上来吧!供大家参考。
dec 函数将字中或blob值转换成decimal类型值
Right 函数从字符串右边返回指定数目的字符
left 函数从字符串左边返回指定数目的字符
mid 函数,以mid(my_diskv_st,3,4)为例,提取my_diskv_st第三到第四位字符!!
reverse函数 将某变量从后向前排列!
string函数将blob类型变量转换成string类型
len函数得到blob类型变量的长度
把PB大部份函数详细给大家贴上来吧,以供收藏!!!
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
上传的附件: