aspower 发表于 2009-6-3 15:16

深入了解VB程序注册破解机制(一)

深入了解VB程序注册破解机制(一)
    说句实在话,我在给文章起上这个名字的时候心里颤颤巍巍的,既怕被人用砖头活活拍死,又怕起了个牛x的名字最后没有给大家介绍什么真正牛x的东西。不过,我为人脸皮极厚,所以就硬着头皮拉起了大旗。如果文章拙劣,还请众位看官多多包涵。如果实在忍受不了要拍砖,请千万不要砸脸。
    前段时间在csdn论坛上的vb区看见了一篇有关反破解的文章,文章介绍了一些代码。这些代码是通过一些api的调用比如isdebuggerpresent,获取父进程等手段,来防止程序被调试器调试和破解的。如果是在几年前,我说不定会惊为天人,然后赶紧把代码copy到vb里试验一下。但是,由于本人对反汇编和程序破解在这几年间有了一定的认识和了解,所以我清楚的知道这些反调试手段对于真正的cracker来说,实在是不值得一提。简单的来说,如果vb是通过调用api来完成反调试的话,那么只要hook住那个api,然后修改这个api的返回值就可以轻易的使得vb上当受骗。而目前常用的这些调试工具都有这样的功能,如olldbg工具有一个hideod的工具就可以hook住isdebuggerpresent,ntgloblflags,hepflags,process32next,……等等十数个api。而对于获得父进程,更加简单了,因为检测父进程是不是explorer的话,只要把调试器或者装载器的文件名改成explorer.exe就可以了。
    其实在早期的软件破解过程中,很多人都害怕调试vb的程序。因为vb的机制和vc或者dehpi不同,他的功能都是在msvbvm60.dll里完成的,通常的软件跟踪办法很容易会在msvbvm60.dll里面打转,而找不出关键点,更不要说人人都害怕的p-code了。虽然如此,但本人在实际的软件跟踪破解过程中,并没有vb比其他语言的程序更难破解的感觉,也许是由于原先一直用vb所以对vb了解更多一点的原因吧。而在另一方面,也说明了现在的vb软件自身防护意识的淡薄和手段的匮乏。
    有看官说了,你别光说不练啊,你不会是在吹牛吧!
    别急,咱这就动手,我就实际剖析两个vb编写的软件,让大家了解一些有关vb注册验证和破解的知识。       
【目标软件】:QQ聊天记录器(qq-msg)V3.0 2009升级版
【作者】: aspower
【作者邮箱】: 不能给,怕垃圾邮件啊!
【编写语言】: VB5.0-6.0
【软件介绍】: QQ聊天记录器能完整的记录下你电脑上的所有的QQ聊天信息,不用密码,不用登录QQ窗口,你即能看到本机上所有QQ号的聊天记录(包括聊后立即删除的记录)。本软件主要功能是提供保存自已的聊天记录,或及时了解你孩子、家人的聊天内容,防止孩子交上不良网友。本软件几乎支持目前所有的QQ版本。特别忠告:本软件不得用于监视别人的计算机,请合法应用本软件。
【使用工具】:peid,regmon,olldbg ,smartcheck
【作者声明】: 只是出于研究,没有其他目的。失误之处敬请大家见谅。
   用peid查看软件,是aspack2.1的壳,普通的压缩壳,直接使用脱壳工具脱掉壳,再查看软件,得知软件是Microsoft Visual Basic 5.0 / 6.0,vb写的。
   打开软件,标题栏显示qqmsg未注册字样,未注册版本有时间限制,而无法查看qq记录。打开注册窗口,输入注册名aspower,随便假注册码9876543210按下现在注册。当的一声,弹出个窗口,说是需要重新启动。很正常的过程,重启验证。
    了解注册机制的人就会知道,大部分重启验证一般是通过检测注册表,或者检测某个key文件来判断注册码的。相信这个也不例外,好,让我们祭起regmon的大旗监视注册表。因为regmon默认的设置会把所有系统的注册表格信息都显示出来,那样的话很小一会就会出现大量的注册表信息。所以我们打开regmon后,先设置过滤条件为qq-msg.exe。这样的话就光显示这个软件对注册表的读写了。现在打开软件,我们就发现regmon里出现了以下键值HKEY_CURRENT_USER\Software\VB and VBA Program Settings\clongxue\clongxue,打开注册表定位到该键值,我们就会发现下面有zcm和zcmm两个dword值,一个是注册名,一个是注册码。
    好现在用olldbg加载软件,如何下断点就成了关键。我们知道,通常在vb下下api断点是无法断下api的调用的,因为vb的api调用是通过msvbvm60.dll里DllFunctionCall函数来完成的,直接在vb程序里下断是无效的。同样,等窗体启动以后再下断也是没有效果的,因为这个时候验证过程已经过去。
    很多人说vb下断点难,就是因为不了解vb。当碰见这个情况的时候,很多人就不知道如何着手了。再有的人就开始一步一步跟,事实上,vb的断点有vb的规律,我们可以自己考虑下,如果自己来些个注册程序,我们会怎么样呢?最可能是就是这样了,先算出一个注册码,然后跟用户输入的注册码比较。vb很可能是这样写的,
if (string1=string2) then
注册成功       
else
注册失败
end if
那么string1=string2在汇编环境下是怎么样的呢?
可能是这样的,
0041BA42   .50            push    eax               压入第一个字符串
0041BA43   .68 20804000   push    00408020                压入第二个字符串
0041BA48   .FF15 C4104000 call    dword ptr [<&MSVBVM60.__vbaStrCm>;MSVBVM60.__vbaStrCmp比较函数
                            MOV EDi,EAX                  ;结果同时在eax中返回
    那么我们就可以在od里用MSVBVM60.__vbaStrCmp下断,这样的话,我们就可以在所有的字符串比较函数位置使程序停下来了。我们命令行里输入bpx MSVBVM60.__vbaStrCmp,然后按下f9让程序继续运行。再断下n次以后,发现已经进入程序,依然显示未注册,而根本没有看见注册字符入栈,就是说vbaStrCmp前的push    eax和 push    00408020都没有出现注册码的身影。那么这个程序是怎么进行注册验证的呢?
    没关系,调试vb软件还有很多强大的软件,现在让我们启动令vb程序心惊胆颤的smartcheck来看下这个vb程序究竟在哪里搞了鬼.smartcheck
是一个非常强大的vb调试工具,在smartcheck下,你会看到非常详细的vb程序信息,甚至会被反汇编到可读的代码级别.
    用smartcheck启动这个软件,你会看见软件启动的整个过程,你会看见,一开始软件启动了一个form1,就是输入密码的窗口,然后开始接受keypress,之后form2.load,form2.load后面有一个加号,那么让我们来看看form2.load里有什么猫腻.果然在form2.caption显示未注册的标题前面有两个可疑的InStr过程,instr大家都知道,在一个字符串里查找另一个字符串的函数,难道这个软件是用instr来从注册码里找字符串的?我们把里面的内容复制出来到文本里详细看看.

InStr(long:1, String:"98765432...", String:"leiw3-mb...", Integer:0) returns LONG:0

Arguments
--------------------
Longstart = 1 0x00000001
Stringstring1 = 00150ED4
      = "987654321"
Stringstring2 = 00408088
      = "leiw3-mbodr-9ewto-nmbio"
Integercompare = 0 0x0000

Instr(long:1, VARIANT:String:"aspower", VARIANT:String:"xue", Integer:0)

Arguments
--------------------
Longstart = 1 0x00000001
string1 (variant)
    String.bstrVal = 001638B4
          = "aspower"
string2 (variant)
    String.bstrVal = 0040807C
          = "xue"
Integercompare = 0 0x0000

Form2.Caption <-- "qq-msg 3.0 2009(未注册)" (String)
String "qq-msg 3.0 2009(未注册)"

当然我们不知道是不是这样,因为注册码和用户名都进入了查找,我们再用ollydbg跟一下.现在有smartcheck里的分析,我们可以很容易的下一个有用的断点MSVBVM60.__vbaInStr,果然,很快我们就到了一个可疑的地方.
前面正好有明白的注册码入栈的行为,
00415EE5   .68 107B4000   push    00407B10                         ; /szKey = "zcmm"<--注册表里注册码的位置
00415EEA   .68 D47F4000   push    00407FD4                         ; |Section = "clongxue"
00415EEF   .68 D47F4000   push    00407FD4                         ; |AppName = "clongxue"
00415EF4   .FF15 BC114000 call    dword ptr [<&MSVBVM60.#689>]   ; \rtcGetSetting
显然这里就应该是正式的关键位了。
我们看
00415EFC   .8D4D 90       lea   ecx, dword ptr
00415EFF   .FF15 EC114000 call    dword ptr [<&MSVBVM60.__vbaStrMo>;MSVBVM60.__vbaStrMove 字符串移动
00415F05   .C745 FC 19000>mov   dword ptr , 19
00415F0C   .C785 30FEFFFF>mov   dword ptr , 0040807C    ;UNICODE "xue"压入用户名比较字符
00415F16   .C785 28FEFFFF>mov   dword ptr , 8
00415F20   .6A 01         push    1
00415F22   .8B55 90       mov   edx, dword ptr
00415F25   .52            push    edx                                        <----这里是我们输入的注册码"123456789"
00415F26   .68 88804000   push    00408088                         ;UNICODE "leiw3-mbodr-9ewto-nmbio"压入注册码比较字符
00415F2B   .6A 00         push    0
00415F2D   .FF15 84114000 call    dword ptr [<&MSVBVM60.__vbaInStr>;MSVBVM60.__vbaInStr
00415F33   .8985 20FEFFFF mov   dword ptr , eax
00415F39   .C785 18FEFFFF>mov   dword ptr , 3
00415F43   .6A 01         push    1
00415F45   .8D45 98       lea   eax, dword ptr
00415F48   .50            push    eax
00415F49   .8D8D 28FEFFFF lea   ecx, dword ptr
00415F4F   .51            push    ecx                                 <----这里是我们输入的用户名"aspower"
00415F50   .6A 00         push    0
00415F52   .8D95 FCFEFFFF lea   edx, dword ptr
00415F58   .52            push    edx
00415F59   .FF15 5C114000 call    dword ptr [<&MSVBVM60.__vbaInStr>;MSVBVM60.__vbaInStrVar
00415F5F   .50            push    eax
00415F60   .8D85 18FEFFFF lea   eax, dword ptr
00415F66   .50            push    eax
00415F67   .8D8D ECFEFFFF lea   ecx, dword ptr
00415F6D   .51            push    ecx
00415F6E   .FF15 1C114000 call    dword ptr [<&MSVBVM60.__vbaVarAn>;MSVBVM60.__vbaVarAnd
00415F74   .50            push    eax
00415F75   .FF15 A8104000 call    dword ptr [<&MSVBVM60.__vbaBoolV>;MSVBVM60.__vbaBoolVarNull
00415F7B   .66:8985 C4FDF>mov   word ptr , ax
00415F82   .8D8D FCFEFFFF lea   ecx, dword ptr
00415F88   .FF15 1C104000 call    dword ptr [<&MSVBVM60.__vbaFreeV>;MSVBVM60.__vbaFreeVar
00415F8E   .0FBF95 C4FDFF>movsx   edx, word ptr
00415F95   .85D2          test    edx, edx
00415F97      0F84 9E000000 je      0041603B   <----------------关键一跳,跳了鸭子就飞了!
到这里,真相大白了,原来这个软件就是用instr来查找一下用户名和注册码,而他查找的字符完全是固定值.这样的话,事实上所有的用户名和注册码都必须包含"xue"和"leiw3-mbodr-9ewto-nmbio"字符串,而且必须是连起来的.那么让我们来试一下,输入"xueaspower"和"leiw3-mbodr-9ewto-nmbio"重新启动,果然,caption后已经没有了未注册的内容,功能也完全没有限制了。
    在这里,大家如果有兴趣的话,可以跟进00415F2D   .FF15 84114000 call    dword ptr [<&MSVBVM60.__vbaInStr>,详细看一下vb是如何进行字符串比较的,相信看了以后对你一定会有很大的帮助的.
    看完我的破解过程,你也许觉得这个软件的注册码也太简单了吧,这不等于是白送的么? 我可以告诉你,如今世面上的vb软件10个最少有7个是明码比较的,当然,也许不是完全固定的字符串,但是只要一用到if (string1=string2) then 这样的检验格式,那不出5分钟,你这个软件就可以被破解。而令人惊讶的是,这个软件的版本3.0了,而且在skycn上它的下载量更是超过了10万,如果加上其他软件站的下载,这个软件很可能有超过几十万的用户,即使是这样的一个软件,对于自己的注册码保护措施还是这样的低能,其他的软件可想而知了。
    好,在这里讲两句题外的话,在上次的帖子里,有位朋友说了句这样的话。他说我的软件被高手破解的那个功夫也许他自己都能写一个了。说实话,这样想就不太对了,就拿我才分析的这个软件来说,事实上技术含量并不高。你不要被他那广告词所吓倒。你如果认真的分析了整个软件的内容,你就会发现,其实他所谓的监视太简单不过了。他在启动的过程中,会在系统的目录里释放然后启动一个sevesys.exe文件,而且修改启动注册表,让自己自动启动。更加可笑的是,这个文件连自我隐藏都没有做,你只要启动任务管理器,你就可以在里面看见这个文件。详细跟踪这个sevesys.exe文件,你就发现,其实他只是调用了findwindow定时查找窗体,然后利用getwidowtext复制出qq对话框里的内容。
在他的说明里,有个地方这样说,本软件登录时需要密码,您的原始密码是:888,您可以点击“设置”按钮修改密码。没有密码就不能登录本软件,并且本软件对记录下的数据做了很好的加密处理。你可以打开注册表中HKEY_CURRENT_USER\Software\VB and VBA Program Settings\clongxue\clongxue下有个setupmm键值,下面的值就是密码,而且是明码。另外一个地方这样说明6、当去掉“启动QQ实时监控”前的打钩时,本软件即停止监视QQ聊天窗口功能,此时手工删除本软件所在文件夹,即可彻底删除本软件。事实上,在删除掉这个文件夹后,sevesys.exe文件并没有在系统中删除,难道是为了防止这个机密被人发现不删除,还是为了留个后门?非常值得怀疑啊!其实一个软件的技术不是最关键的,倒不一定是最火的软件就是最有技术含量的。同样,你自己觉得别人高手可能不屑破解你的软件,可是你自己的软件连个菜鸟都能对付的话,那又怎么能保证这个菜鸟不给你破解出来呢?
【目标软件】:XX网络电视 8.29
【作者】: aspower
【作者邮箱】: 不能给,怕垃圾邮件啊!
【编写语言】: VB5.0-6.0
【软件介绍】:一个在线收看网络电视的软件,内置100多个电视台,还有大量广播频道。
【使用工具】:peid,olldbg ,smartcheck,filemoniter
【作者声明】: 只是出于研究,没有其他目的。失误之处敬请大家见谅。

    这个软件我隐去了软件名,如果需要实例,可以下载我提供的文件包。毕竟大家本是同根生,相煎何太急啊。前面那个软件要不是因为他窥探隐私和类似窃听的功能,我也不能明着来,主要一想到刚上网那会,我注册的n个qq就被这样的所谓o(∩_∩)o技术给弄跑了,想起来就眼泪哗哗的啊。
    不多废话,分析软件。该软件什么壳都没有加,不知道是对自己的注册技术很自信呢,还是别的原因。咱们不管了,撸起袖子上吧!
照样操起smartcheck,准备将软件大卸八块。加载软件后,软件显示只能使用45次。好我们进入注册画面,可以看见有三个输入栏,一个是机器码,一个是用户名,一个是输入的注册码。我们随便输入用户名为aspower,注册码是987123456,按下注册,ok弹出一个注册码错误的窗口。有门,这说明是直接验证不重启的。看看smartcheck里面,cmdok_click的行为里出了一长串的字符。我们来仔细看看,里面有没有什么可疑的信息,很快一个string值引起了关注,复制到文本里看看。
Val(String:"5933") returns double:5933 (displayed as single-precision floating point)

Arguments
--------------------
Stringstring1 = 001CA00C
      = "5933"
Double (5933) --> Long (5933)
Double 5933
Long 5933
    难道又是一个明码的?输入5933到注册码拦里,当,还是一个错误框。看来这个软件用smartcheck是对付不了了。想想也是,要是smartcheck可以随便对付那个vb软件的话,那vb软件早绝种了。好,我们用一个新的工具来对这个软件进行监视吧,filemoniter是用来监视软件读写文件的工具。你问我为什么不用regmon了?嘿嘿,你用用试试,这个软件在启动的时候对注册表有将近5000次的读写,而且全部和注册码无关。所以,我判断这个软件应该是读某个key文件来验证的。
    果然,跟踪发现,超级电视启动的时候读取了d盘的Iotmrd.sys文件,看来这个文件里有猫腻。我们随便用个文本工具打开这个文件就会发现,其实里面就是普通文档。

pt1=5933
pt2=V
Form1Top= 1065
Form1Left= 2625
Form1Height= 8520
Form1Width= 11520   请注意,由于机器的差异上面的内容可能不同,但是意思都是一样的。pt1就是我们刚才看见的5933,而pt2则是个英文字母,是什么意思呢?你可以再打开软件一次,退出再看这个文件。你就会发现,其他都没有变,就这个pt2变了,变成了w,你明白了么?想想看,w不是在v的前面么?这个pt2就记录了你使用的次数,当pt2变为)的时候,你就不能继续使用了。那么你就可以先用到45次,然后来修改这个值,你就又可以使用这个软件了,这里你最多可以用ue或者winhex把这里的acii码值改为ff,那样的话你就可以连续使用212次才过期。
   但是我们craker可不会止步于此!下面就带你进入周瑜的思考领域!哦,不好意思说串了,火凤燎原看多了啊!下面就带你进入破解者的思考领域,我们注意到,其实这个文件在最开始的时候并没有安装这个文件,那么肯定是后来生成的,那么我们是不是可以先删除它,然后让他再生成一次呢?说干就干,先删除掉Iotmrd.sys,然后启动ollydbg,用超级字符串查找unicode值,Iotmrd.sys,找到一处,再哪里下段。然后f9开始运行程序,果然,不一会儿,程序在Iotmrd.sys的地方断了下来。我们f8单步行进,并且随时注意d盘下生成没有生成Iotmrd.sys文件,走了大概两百多里地后走到了这里(当然没有那么夸张拉:),
00428EAE   .FF15 34424800          CALL DWORD PTR DS:[<&MSVBVM50.#594>]                   MSVBVM50.rtcRandomize
省略部分代码
00428F5A   .FF15 28424800          CALL DWORD PTR DS:[<&MSVBVM50.#593>]                   MSVBVM50.rtcRandomNext
00428F60   .D99D 04FFFFFF          FSTP DWORD PTR SS:
00428F66   .D985 04FFFFFF          FLD DWORD PTR SS:
00428F6C   .D80D 28104000          FMUL DWORD PTR DS:
00428F72   .DFE0                   FSTSW AX
00428F74   .A8 0D                  TEST AL,0D
00428F76   .0F85 1D4E0000          JNZ supernet.0042DD99
00428F7C   .FF15 58434800          CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8IntI4>]            MSVBVM50.__vbaR8IntI4
00428F82   .8D8D 6CFFFFFF          LEA ECX,DWORD PTR SS:
00428F88   .8BD8                   MOV EBX,EAX
00428F8A   .FF15 E4414800          CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeVar>]            MSVBVM50.__vbaFreeVar
00428F90   .8BCB                   MOV ECX,EBX
00428F92   .8B16                   MOV EDX,DWORD PTR DS:
00428F94   .0FAFCB               IMUL ECX,EBX
00428F97   .0F80 014E0000          JO supernet.0042DD9E
00428F9D   .81C1 40420F00          ADD ECX,0F4240
   很显然了,MSVBVM50.rtcRandomize和 MSVBVM50.rtcRandomNext就是用vb生成了两个随机数,而当代码跑到IMUL ECX,EBX,你会发现ecx和ebx的值是一样的,我这里都是1D54,十进制就是7508。那么IMUL ECX,EBX就是将ecx乘方,然后ADD ECX,0F4240 也就是1D54^2+0f4240。最后结果转换为十进制就是57370064。果然,进入软件后,注册拦的序列号变成了这里算出的57370064,而Iotmrd.sys中的pt1也变成了7508。但是我们这里虽然知道了序列号是怎么算出的,但是离算出注册码还是有很远的距离。
    那么怎么办呢?现在我们对msgbox下手,如果这个程序不是调用messagebox这个api来弹出错误的话,那么vb的msg函数通常是MSVBVM50.rtcMsgBox,我们对所有的MSVBVM50.rtcMsgBox下段,然后再次点下注册,ok果然在下面这行断了下来。
004802C0   .FF15 3C424800          CALL DWORD PTR DS:[<&MSVBVM50.#595>]                     ;MSVBVM50.rtcMsgBox
好现在就来看看要怎么样才能避开这个错误窗口。果然,不远的地方有这样一个跳转能够躲开这个错误提示走到下面去,
0048021D   . /0F8D FD030000          JGE supernet.00480620
ok,我们用jmp替换了jge(jge是条件跳转也就是说根据条件跳到某个位置,而jmp则是强迫跳。)再看看可以不可以通过,结果再次输入用户名和注册码,还是弹出了错误窗口。这说明什么?这说明程序根本没有走到这里,只能继续向上找了,向上找了很远很远,(真的很远,翻了六七页代码)终于找到了罪魁祸首,
0047FE3B   .8B06                   MOV EAX,DWORD PTR DS:
0047FE3D   .FF90 A0000000          CALL DWORD PTR DS:
0047FE43   .85C0                   TEST EAX,EAX
0047FE45   .7D 12                  JGE SHORT supernet.0047FE59
0047FE47   .68 A0000000            PUSH 0A0
0047FE4C   .68 C08D4000            PUSH supernet.00408DC0
0047FE51   .56                     PUSH ESI
0047FE52   .50                     PUSH EAX
0047FE53   .FF15 1C424800          CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheckObj>]               ;MSVBVM50.__vbaHresultCheckObj
0047FE59   >8B55 E0                MOV EDX,DWORD PTR SS:
0047FE5C   .52                     PUSH EDX
0047FE5D   .FF15 80434800          CALL DWORD PTR DS:[<&MSVBVM50.#581>]                               ;MSVBVM50.rtcR8ValFromBstr
0047FE63   .FF15 70424800          CALL DWORD PTR DS:[<&MSVBVM50.__vbaFpR8>]                        ;MSVBVM50.__vbaFpR8
0047FE69   .DB85 40FFFFFF          FILD DWORD PTR SS:
0047FE6F   .DD9D 04FFFFFF          FSTP QWORD PTR SS:
0047FE75   .DC9D 04FFFFFF          FCOMP QWORD PTR SS:                                        ;(初始 cpu 选择)
0047FE7B   .DFE0                   FSTSW AX
0047FE7D   .F6C4 40                TEST AH,40
0047FE80      74 07                  JE SHORT supernet.0047FE89
0047FE82   .BE 01000000            MOV ESI,1
0047FE87   .EB 02                  JMP SHORT supernet.0047FE8B
0047FE89   >33F6                   XOR ESI,ESI
0047FE8B   >8D4D E0                LEA ECX,DWORD PTR SS:
0047FE8E   .FF15 7C434800          CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeStr>]                     ;MSVBVM50.__vbaFreeStr
0047FE94   .8D4D C8                LEA ECX,DWORD PTR SS:
0047FE97   .FF15 78434800          CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeObj>]                     ;MSVBVM50.__vbaFreeObj
0047FE9D   .F7DE                   NEG ESI
0047FE9F   .66:85F6                TEST SI,SI
0047FEA2   .0F84 92030000          JE supernet.0048023A      <------------------这里一跳,老母鸡就变鸭了!
只要改为      0f85 92030000             jnz                                          
    好,错误框没有弹出了,但是标题拦依然显示为未注册。难道这个只是跳过了错误窗口,而没有使破解成功么?当然有的软件是有多处检测点叫做暗桩,这个软件呢?
   我们还是看下d盘的那个Iotmrd.sys文件吧,结果发现里面已经添加了以上内容
pt3=258358
pt4=aaa
    这里的pt4正是我输入的注册用户名,而pt3不是我输入的注册码,经过验证发现这个正是正确的注册码。
    事实上这个点只是判断是否写入的,结果他写入的时候直接写的程序自身算出来的正确注册码,于是…………庐山瀑布汗啊!
    好了,我们现在就可以有好几种完全破解这个软件的方法了,一是用ue或者winhex之类的16进制编辑工具,打开exe文件修改0047FEA2位置的0f84为0f85,然后随意输入用户名和注册码,软件就会自己给你注册了。二就是用内存补丁方式,动态修改0047FE80位置的值。既然是vb程序版,我们当然最好使用程序的方法了。
下面是vb的源码,调试的时候注意,因为系统的不同,可能不一定是每个系统里这个软件的exe名字都是supernettv.exe小写的!大家自行修改!
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "Kernel32" (ByVal dwDesiredAccess As Long, ByValbInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "Kernel32" (ByVal hProcess As Long, ByVallpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
'定义访问权限常量
Private Const PROCESS_ALL_ACCESS = &H1F0FFF

Private Declare Function WriteProcessMemory Lib "Kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long

      Const TH32CS_SNAPHEAPLIST = &H1
Const TH32CS_SNAPPROCESS = &H2
Const TH32CS_SNAPTHREAD = &H4
Const TH32CS_SNAPMODULE = &H8
Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE)
Const TH32CS_INHERIT = &H80000000
Const MAX_PATH As Integer = 260
Private Type PROCESSENTRY32
    dwSize As Long
    cntUsage As Long
    th32ProcessID As Long
    th32DefaultHeapID As Long
    th32ModuleID As Long
    cntThreads As Long
    th32ParentProcessID As Long
    pcPriClassBase As Long
    dwFlags As Long
    szExeFile As String * MAX_PATH
End Type
Private Declare Function CreateToolhelp32Snapshot Lib "Kernel32" (ByVal lFlags As Long, ByVal lProcessID As Long) As Long
Private Declare Function Process32First Lib "Kernel32" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "Kernel32" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Sub CloseHandle Lib "Kernel32" (ByVal hPass As Long)

Dim tvexe As Long


Private Sub Command1_Click()
   Dim hWnd As Long, hProcess As Long, pid As Long, address As Long, readBuf As Long
   Dim i As Integer
   
   findtv               '查找程序是否运行
   If tvexe = 0 Then
      MsgBox "请先运行超级电视再运行本程序", vbCritical, "失败 "
   Else
       hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, tvexe)          '打开进程
       If hProcess = 0 Then
       MsgBox "打开进程失败"
       Exit Sub
       End If
       res = "u"   '修改数据.把&H47FE80处修改成75H
       WriteProcessMemory hProcess, &H47FE80, res, 1, ByVal 0&
      End If
End Sub

    Private Sub findtv()
    Dim hSnapShot As Long, uProcess As PROCESSENTRY32
    'Takes a snapshot of the processes and the heaps, modules, and threads used by the processes
    hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0&)
    'set the length of our ProcessEntry-type
    uProcess.dwSize = Len(uProcess)
    'Retrieve information about the first process encountered in our system snapshot
    r = Process32First(hSnapShot, uProcess)
    'set graphics mode to persistent
    Do While r
      t = InStr(1, uProcess.szExeFile, "supernettv.exe")
      If t > 0 Then
      tvexe = uProcess.th32ProcessID
      Exit Sub
      End If
      'Retrieve information about the next process recorded in our system snapshot
      r = Process32Next(hSnapShot, uProcess)
    Loop
    tvexe = 0
    'close our snapshot handle
    CloseHandle hSnapShot
End Sub



最后由于这个程序的开始老是弹出网页,跟一下开始就可以发现弹出窗口是使用一个call来完成的 nop掉
                                8b8504ffffff
                                50
nop掉弹出网页的call
                   0042A384      e85fe3fdff
                        改为nop 9090909090

    后记,可能有的朋友已经看的晕头转向了,其实如果要实际讲注册码的计算流程,我还可以继续讲下去,但是我觉得,我要说明的内容已经说到了。如果对算法有更进一步兴趣的朋友可以下载我上传的包来获得更详细的注册吗算法过程。提醒一下,这个程序是用浮点算法来计算的。
    从我分析这两个软件的注册算法后,我希望大家了解到以下两点,
第一,破解其实并不象你想象的那么难,因此,如果你用明码比较这样的算法来制作共享软件的注册的话,那肯定是等于完全白送给别人。
第二,一个软件的流行于否,和技术含量的关系并不大。有很多技术含量并不高的软件都有很大的用户量,所以你也一样可能用vb软件开发出来一个流行的软件,重要的是找准目标。
    那么,如果你要制作一个共享软件,怎么样能防止别人对你软件的破解呢?
首先,你可以给自己的软件加一个稍微强大一点的壳,像upx或者 aspack这样的壳基本上就跟(***)没什么两样,当然如果有钱购买一些商用的壳,肯定是要比免费能弄到的壳好上很多。
其次,即使是有了一个好壳,也很难抵挡真正高手的破解。我这里可以提供给大家一个简单实用的办法,现在很多软件也在采用,那就是把部分注册用户才可以使用的功能完全屏蔽掉,也就是说在汇编领域把这些代码全部nop掉。这样的话,事实上试用版本完全没有收费版本的功能代码,这样的话,即使被破解这个程序也无法正常试用注册功能。除非破解者能把这些代码自己给补上,但是一般情况是不会有人这样做的。
再次,如果你的程序需要提供全功能试用,或者你代码量和功能本身就不多,那么就应该用其他的办法来保护你的程序,比如利用一些程序smc技术或者利用网络验证等办法,这就是我下两篇文章将给大家介绍和讲解的。
    最后,祝各位vb程序员的作品大卖,做员工的人人加工资,做老板的人人发大财。
    程序包说明,两个程序的原文件下载地址,第2个软件的详细算法,以及一个vc版本的注册机以及源代码,有需要的可以下载。

stpzhj 发表于 2009-6-3 16:03

菜鸟学习中……谢谢LZ了……

期待(2)

q68174644 发表于 2009-6-3 15:38

又得上一课了!!

有为55 发表于 2009-6-3 15:34

原来是沙发 呵呵 学习了这个文章对我很有帮助

aspower 发表于 2009-6-3 15:16

http://download.csdn.net/source/1377883

程序和详细算法下载

附件传不上来

毛毛虫老板 发表于 2009-6-3 17:27

:lol谢谢,看贴学习了!

Alar30 发表于 2009-6-3 20:14

不服不行。。。
可惜对VB不了解

findkill 发表于 2009-6-4 08:56

分析得很详细和很有道理。拜读了。

fuma255 发表于 2009-6-9 15:13

又得上一课了!!

fengshangren 发表于 2009-6-16 22:43

VB搞不懂怎么破
页: [1] 2 3
查看完整版本: 深入了解VB程序注册破解机制(一)