我是新手,以happytown老大这系列东东作为起步点,在此谢谢老大:)以后多多向大家学习。
对于W32Dasm等的反汇编这里就不说了,这里直接从OD开始。
首先运行KeyGenMe_01.exe,尝试输入name:rageliu和serial:12345,点击Check,没有任何反应,看来是要注册码正确才会有提示信息。我们用OD加载KeyGenMe_01.exe,在反汇编的代码区域右键点击,选择“查找“后点“所有参考文本字串”,会在Text string里面发现“Good job,man!”,呵呵,我们猜测这是在注册码正确后给我们的提示,这里注意到上面还有个字串“Congratulations”恭喜的意思啊:)呵呵,双击“Good job,man!”串来到下面代码的地方:
004025BB . C785 7CFFFFFF>MOV DWORD PTR SS:[EBP-84],KeyGenMe.00401>; UNICODE "Good job,man!"
贴出这附近的代码,并加了些猜测的注释,需要我们调试来证实:
00402595 . C785 6CFFFFFF>MOV DWORD PTR SS:[EBP-94],KeyGenMe.00401>; UNICODE "Congratulations"//提示窗体的Caption????
0040259F . BF 08000000 MOV EDI,8
004025A4 . 89BD 64FFFFFF MOV DWORD PTR SS:[EBP-9C],EDI
004025AA . 8D95 64FFFFFF LEA EDX,DWORD PTR SS:[EBP-9C]
004025B0 . 8D4D A4 LEA ECX,DWORD PTR SS:[EBP-5C]
004025B3 . 8B35 98104000 MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaVa>; MSVBVM60.__vbaVarDup
004025B9 . FFD6 CALL ESI ; <&MSVBVM60.__vbaVarDup>
004025BB . C785 7CFFFFFF>MOV DWORD PTR SS:[EBP-84],KeyGenMe.00401>; UNICODE "Good job,man!" //我们猜测是注册码正确后的提示
004025C5 . 89BD 74FFFFFF MOV DWORD PTR SS:[EBP-8C],EDI
004025CB . 8D95 74FFFFFF LEA EDX,DWORD PTR SS:[EBP-8C]
004025D1 . 8D4D B4 LEA ECX,DWORD PTR SS:[EBP-4C]
004025D4 . FFD6 CALL ESI
004025D6 . 8D55 84 LEA EDX,DWORD PTR SS:[EBP-7C]
004025D9 . 52 PUSH EDX
004025DA . 8D45 94 LEA EAX,DWORD PTR SS:[EBP-6C]
004025DD . 50 PUSH EAX
004025DE . 8D4D A4 LEA ECX,DWORD PTR SS:[EBP-5C]
004025E1 . 51 PUSH ECX
004025E2 . 6A 40 PUSH 40
004025E4 . 8D55 B4 LEA EDX,DWORD PTR SS:[EBP-4C] //下面是调用MessageBox,那么上面应该就是设置它的参数了??
004025E7 . 52 PUSH EDX
004025E8 . FF15 34104000 CALL DWORD PTR DS:[<&MSVBVM60.#595>] ; MSVBVM60.rtcMsgBox//这里是不是好熟悉??MessageBox??
由于我们注册码是不正确的,所以上面代码没有被执行到,那就是说前面的某个地方有个判断的东东,将后面的正确提示跳转过了??带着这样的猜测,我们帖出紧接着"Good job,man!"前面的代码:
00402564 . 8B4D DC MOV ECX,DWORD PTR SS:[EBP-24]
00402567 . 51 PUSH ECX
00402568 . FF15 80104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaR8Str>; MSVBVM60.__vbaR8Str//这个应该就是关键call了吧???
0040256E . DC9D 14FFFFFF FCOMP QWORD PTR SS:[EBP-EC] ;
00402574 . DFE0 FSTSW AX
00402576 . F6C4 40 TEST AH,40 //注意这里的TEST
00402579 . 0F84 86000000 JE KeyGenMe.00402605 ; //看到这里了吗???有个跳转,初步估计它应该就是关键跳转了。也就是说它跳过了前面分析的提示窗体部分的代码。执行到了注册码错误的逻辑分支。
0040257F . B9 04000280 MOV ECX,80020004
00402584 . 894D 8C MOV DWORD PTR SS:[EBP-74],ECX
00402587 . B8 0A000000 MOV EAX,0A
0040258C . 8945 84 MOV DWORD PTR SS:[EBP-7C],EAX
0040258F . 894D 9C MOV DWORD PTR SS:[EBP-64],ECX
00402592 . 8945 94 MOV DWORD PTR SS:[EBP-6C],EAX
00402595 . C785 6CFFFFFF>MOV DWORD PTR SS:[EBP-94],KeyGenMe.00401>; UNICODE "Congratulations"//提示窗体的Caption????
0040259F . BF 08000000 MOV EDI,8
004025A4 . 89BD 64FFFFFF MOV DWORD PTR SS:[EBP-9C],EDI
004025AA . 8D95 64FFFFFF LEA EDX,DWORD PTR SS:[EBP-9C]
004025B0 . 8D4D A4 LEA ECX,DWORD PTR SS:[EBP-5C]
004025B3 . 8B35 98104000 MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaVa>; MSVBVM60.__vbaVarDup
004025B9 . FFD6 CALL ESI ; <&MSVBVM60.__vbaVarDup>
004025BB . C785 7CFFFFFF>MOV DWORD PTR SS:[EBP-84],KeyGenMe.00401>; UNICODE "Good job,man!" //我们猜测是注册码正确后的提
分析到这里我们心里应该就有个大概的眉目了,不过前面的猜测正确与否,我们就开始动态调试来证实。
我们在关键call的前面点00402567 . 51 PUSH ECX处下端,F9执行,输入name:rageliu和serial:12345,点击Check,OD断在了00402567我们下的端点处。先不用F7跟进,直接F8一直到00402579 . 0F84 86000000 JE KeyGenMe.00402605,也就是我们猜测的关键跳的地方,果然如我们猜想的一样,跳转被执行,跳到了00402605,也就是跳过了正确的处理代码去到了注册码错误的处理部分,看来我们上面猜测的基本是对的,下面来做进一步的证实,我们先用暴破的方式。
重新用OD加载程序,输入注册码后断在我们的断点处,这时候我们双击00402579 . 0F84 86000000 JE KeyGenMe.00402605后将JE改为JNE,汇编,F8过断点后直接F9执行,呵呵,出来了一个窗体,信息是“Good job,man!”,Caption也正是我们猜想的""Congratulations",到这里已基本证明我们前面的分析是正确的了,如果暴破也就是成功了,不过我们学东西啊,所以目标是要写出注册机:)让我们接着来。
由于我是新手,还是按照破解的一般步骤来吧,我们考虑F7进关键call,追出注册码先,这样注册机就是时间的问题了,嘿嘿。
OD加载KeyGenMe_01.exe后断在00402567我们的断点处,看到右边寄存器里面的ECX了吗?里面是"12345",好象我们刚才填的注册码也是12345哦?先不管它。F8运行到我们猜测的关键call的地方,F7进去,这时候我突然发现已经不在KeyGenMe的空间了,进入了系统功能调用的空间,怎么回事????????????
用Alt+F9返回KeyGenMe的空间后仔细一看,原来那个call不是call的KeyGenMe.XXXX的形式,而是一个系统功能调用,也就不是我们所说的关键call。看来上面关于这里的猜测是不对的。再仔细分析下这段代码:
00402564 . 8B4D DC MOV ECX,DWORD PTR SS:[EBP-24] ; "12345"地址进ECX
00402567 . 51 PUSH ECX ; ECX入栈保存
00402568 . FF15 80104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaR8Str>; MSVBVM60.__vbaR8Str//这里不是什么关键call,应该是调用 //一个系统功能,前面的PUSH ECX //是给这个调用压参吗?????
0040256E . DC9D 14FFFFFF FCOMP QWORD PTR SS:[EBP-EC] ; 没有关键call,比较应该在这里??
00402574 . DFE0 FSTSW AX ; 保存状态字的值到AX
00402576 . F6C4 40 TEST AH,40 ; //AH 值与40("@")比较,不相同就会执行下面的关键跳,也 ; //就失败了
00402579 0F84 86000000 JE KeyGenMe.00402605 ; 关键跳转,跳了就完蛋
这里说下FCOMP/FCOMPP指令:FCOMP将栈顶数据与另一个操作数进行比较,该操作数可以存储在堆栈寄存器中,也可存储在内存中。根据上面的代码,栈顶数据显然就是PUSH ECX所压入的“12345”,也就是我们填写的注册码的明码。。看来注册码没有变化,只是name变换后和注册码比较,那现在的关键就是对name的变换操作了。
目前就研究到这里,其他的我还没搞明白,太菜了,郁闷:)
高手来补上啊,我分析到这个程度也不知道对没对,花我半天时间了,后面还不知如何下手...
我分析了下TEST前面部分的代码,发现有一个循环处理,可能是对name的变换,不过还没弄懂,大家使劲鄙视我吧
这里追到的一组name和注册码:(就是FCOMP QWORD PTR SS:[EBP-EC]的时候看到的就是了)
name:rageliu
serial:287195202
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课