手头拿到一个系统,需要加密狗才能使用,想把加密狗杀掉后使用,于是就搬出几年前的破解工具开始杀狗。
系统中主程序main.exe,还有main.dll,main.pbd文件,用Dasm反汇编main.exe,搜索字符串,没发现有错误提示,表示很怀疑,不会是加密了吧,然后就调试跟踪,发现进入CALL调用后显示错误提示,就想着是不是把加密狗检测放在其他文件中,反编译main.dll文件,也没找到错误信息,折腾了两天,没方向!后来注意到还有个main.pbd文件,不知道是什么文件,网上一查,发现是powerbuilder的动态链接库文件(孤陋寡闻了),用二进制编辑软件一搜,果然找到了错误信息(开心呀!),接下来重点对main.pbd来解密。由于自己对Powerbuilder不熟悉,只能到网上找资料,先想着直接改main.pbd代码,找了半天没找到对应的代码(汗),于是想反编译生成源代码,找到PBkiller真的把它反编译出来了看到源代码了,在源代码中发现有个函数gf_checkkey,里面有检测加密狗的信息,主要代码如下:
ret = findport(0,devicepath)
if ret <> 0 then
messagebox("警告","未找到加密狗!",information!,ok!)
return -1
end if
mystring = space(8)
result = yreadstring(mystring,0,8,"ffffffff","ffffffff",devicepath)
if result <> 0 then
messagebox("警告","读加密狗错误",information!,ok!)
return -1
end if
if trim(mystring) <> "********" then
messagebox("警告","加密狗验证失败!",information!,ok!)
return -1
end if
return 1
以上代码主要用到2个函数,findport()检测加密狗,yreadstring()读狗数据。ret变量检测加密狗,有狗返回0,没狗不返回0。杀狗就是在没狗的情况下通过检测,不出错误提示,或者错误提示后不退出程序继续运行程序。看到代码中return -1应该是函数gf_checkkey的返回值,就想着把代码中的return -1改成其他值或许就能在错误提示后不退出程序而继续运行程序。于是就想把源代码修改后重新用PB编译,由于PBkiller能反编译看到源代码,不能反编译成PB工程文件,下载了PB程序安装了想专研一下,无奈PB也不是很简单(自己水平太低,呵呵)!在网上找到PB DeCompiler想把main.pbd反编译成工程文件直接修改编译,但是PB DeCompiler不是免费软件,要收费的,O,MY GOD!折腾了两天还是没解决,只能放弃。
第5天,对于这段简单的源代码,想放弃又不甘心,忽然想到代码中用到的两个函数findport()和yreadstring(),能不能在它们身上做做文章,于是就先找这两个函数在哪里,在PB动态链接库main.pbd中找了一大圈没找到,心想这两个函数有可能是外部函数,于是就查DLL动态链接库,在一大堆DLL文件中终于用IDA找到了一个DLL文件中包含了这两个函数,信心大增呀!以下是findport()的汇编代码,yreadstring()比较它复杂些,没放出来。
.text:10001520 FindPort proc near
.text:10001520
.text:10001520 arg_0 = dword ptr 4
.text:10001520 arg_4 = dword ptr 8
.text:10001520
.text:10001520 mov eax, hObject
.text:10001525 push esi
.text:10001526 push 0FFFFFFFFh ; dwMilliseconds
.text:10001528 push eax ; hHandle
.text:10001529 call ds:WaitForSingleObject
.text:1000152F mov ecx, [esp+4+arg_4]
.text:10001533 mov edx, [esp+4+arg_0]
.text:10001537 push ecx
.text:10001538 push edx
.text:10001539 call sub_10006540
.text:1000153E mov esi, eax
.text:10001540 mov eax, hObject
.text:10001545 push 0 ; lpPreviousCount
.text:10001547 push 1 ; lReleaseCount
.text:10001549 push eax ; hSemaphore
.text:1000154A call ds:ReleaseSemaphore
.text:10001550 mov eax, esi
.text:10001552 pop esi
.text:10001553 retn 8
.text:10001553 FindPort endp
对这两段汇编代码分析后发现只有修改这两函数的返回值就可以了,汇编函数返回值一般在EAX中,我们只要把EAX改成0,不管这段代码做了什么,于是用二进制编辑软件直接修改1550处MOV EAX,ESI二进制B8 C6修成为XOR EAX,EAX的二进制31 C0,如下:
findport
00001550h:B8 C6 5E C2 08 00 90 90-90 90 90 90 90 90 90 90; MOV EAX,ESI
修改为
00001550h:31 C0 5E C2 08 00 90 90-90 90 90 90 90 90 90 90; XOR EAX,EAX
修改二进制保存后再运行程序,果然“未找到加密狗!”的错误提示没有了,终于找到突破口了,真是“山穷水尽疑无路,柳暗花明又一村”。于是对yreadstring()函数代码返回值也做了同样处理,“读加密狗错误”也没有了,但“加密狗验证失败!”的错误还是有。对源代码仔细分析后发现时读狗数据后比较,现在狗都没有哪来数据比较呢?想在DLL中给函数yreadstring()的参数mystring赋值,发现比较麻烦,既然这里比较麻烦,那main.pbd中比较的字符串能不能改呢?于是把main.pbd中“********”用二进制编辑软件全部改成20空格,保存后运行,果然错误提示都没有了,正常进入了系统。好开心呀!
通过5天的奋战终于把狗杀掉,晚上可以不用熬夜了!在此分享这5天来我的杀狗经历,希望高手不要见笑,新手能有所启发!
心得体会:只要执着去做,总能成功!碰到障碍可以绕过去找到出路!代码是公共的,没有解不开的锁!有兴趣的可以交流QQ:6894701
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课