HappyEO 2.40.2 算法分析
作者:bbbsl
使用工具:trw v1.23
分析平台:盗版Win98se
软件介绍:HappyEO是一款用声卡模拟电子琴的软件。有了它,您可以用计算机的键盘奏出美妙的乐曲。还有录音、自动伴奏和效果等功能。假如您没有声卡,您仍然可以用计算机内部的扬声器来发音。
(不是我说的,是作者说的,不过确实挺好玩的,只可惜我不识谱,唉,只能瞎弹!^_*)
分析过程:
先运行trw及该软件,然后选注册后,会出现注册窗口,依次填入姓名,公司名及注册码,作者很细心,如果填错位数他会提醒你的,然后下断点
bpx hmemcpy,填getwindowtexta及getdlgitemtexta均不行,那样就过了关键地方了!:-P,不过在Win2000下怎么设断点呢?有那位大虾能告诉我吗?谢谢!
废话不多说了,回到注册界面点击确定按钮,然后程序会断下,然后F10,经过N个ret后,我们来到这里:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 第一个程序段
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0167:51098C40 LEA EDX,[EBP-04]
0167:51098C43 MOV EAX,[EBX+02D0]
0167:51098C49 CALL 510312E0 ==>我们从这里出来停在下一行!
0167:51098C4E MOV EAX,[EBP-04] ==>Name
0167:51098C51 CALL 51003F28 ==>这里计算长度
0167:51098C56 CMP EAX,BYTE +04 ==>Name<4?报错:继续
0167:51098C59 JL NEAR 51098DB0
0167:51098C5F LEA EDX,[EBP-08]
0167:51098C62 MOV EAX,[EBX+02EC]
0167:51098C68 CALL 510312E0 ==>经过这个call取公司名
0167:51098C6D MOV EAX,[EBP-08] ==>Corporation
0167:51098C70 CALL 51003F28 ==>计算长度
0167:51098C75 CMP EAX,BYTE +0C ==>Corporation<12?报错:继续
0167:51098C78 JL NEAR 51098DB0
0167:51098C7E LEA EDX,[EBP-0C]
0167:51098C81 MOV EAX,[EBX+02D4]
0167:51098C87 CALL 510312E0 ==>在这里取注册码
0167:51098C8C MOV EAX,[EBP-0C] ==>我们输入的注册码
0167:51098C8F CALL 51003F28 ==>计算长度
0167:51098C94 CMP EAX,BYTE +06 ==>长度<6?报错:继续
0167:51098C97 JNZ NEAR 51098DB0
0167:51098C9D LEA EDX,[EBP-10]
0167:51098CA0 MOV EAX,[EBX+02D4]
0167:51098CA6 CALL 510312E0
0167:51098CAB MOV EAX,[EBP-10] ==>再取一遍?
0167:51098CAE PUSH EAX ==>注册码进栈
0167:51098CAF LEA EDX,[EBP-18]
0167:51098CB2 MOV EAX,[EBX+02EC]
0167:51098CB8 CALL 510312E0
0167:51098CBD MOV EAX,[EBP-18]
0167:51098CC0 PUSH EAX ==>Corp进栈
0167:51098CC1 LEA EDX,[EBP-1C]
0167:51098CC4 MOV EAX,[EBX+02D0]
0167:51098CCA CALL 510312E0
0167:51098CCF MOV EAX,[EBP-1C] ==>eax<--Name
0167:51098CD2 LEA ECX,[EBP-14] ==>用来存放地址的一个指针
0167:51098CD5 POP EDX ==>edx<--Corp
0167:51098CD6 CALL 510980B4 ==>关键,跟进!
0167:51098CDB MOV EDX,[EBP-14] ==>这里D edx可得注册码
0167:51098CDE POP EAX ==>假注册码
0167:51098CDF CALL 51004038 ==>比较是否正确,就不看怎么比较的了吧!
0167:51098CE4 JNZ NEAR 51098D9A
0167:51098CEA MOV EAX,51098E00
0167:51098CEF CALL 51056968
0167:51098CF4 CALL 51009688
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 这里是刚才我说的关键call
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0167:510980B4 PUSH EBP
0167:510980B5 MOV EBP,ESP
0167:510980B7 ADD ESP,BYTE -10
0167:510980BA PUSH EBX
0167:510980BB XOR EBX,EBX
0167:510980BD MOV [EBP-10],EBX ==>相当于四个变量
0167:510980C0 MOV [EBP-0C],ECX
0167:510980C3 MOV [EBP-08],EDX
0167:510980C6 MOV [EBP-04],EAX
0167:510980C9 MOV EAX,[EBP-04]
0167:510980CC CALL 510040DC
0167:510980D1 MOV EAX,[EBP-08]
0167:510980D4 CALL 510040DC
0167:510980D9 XOR EAX,EAX
0167:510980DB PUSH EBP
0167:510980DC PUSH DWORD 5109814A
0167:510980E1 PUSH DWORD [FS:EAX]
0167:510980E4 MOV [FS:EAX],ESP
0167:510980E7 MOV EAX,[EBP-0C]
0167:510980EA CALL 51003CA8
0167:510980EF MOV EAX,[EBP-04] ==>又来了,判断名字长度
0167:510980F2 CALL 51003F28
0167:510980F7 CMP EAX,BYTE +04
0167:510980FA JL 51098127
0167:510980FC MOV EAX,[EBP-08] ==>判断公司名长度
0167:510980FF CALL 51003F28
0167:51098104 CMP EAX,BYTE +0C
0167:51098107 JL 51098127
0167:51098109 LEA EAX,[EBP-10]
0167:5109810C MOV ECX,[EBP-08] ==>公司名
0167:5109810F MOV EDX,[EBP-04] ==>Name
0167:51098112 CALL 51003F74 ==>这里用来合并姓名和公司名
0167:51098117 MOV EAX,[EBP-10] ==>eax<--合并后的字符串
0167:5109811A CALL 51097F9C ==>用这个字符串来算一个重要数!跟进!
0167:5109811F MOV EDX,[EBP-0C] ==>通过运算得到一个数
0167:51098122 CALL 51098024 ==>用这个数求最后的六位注册码
0167:51098127 XOR EAX,EAX
0167:51098129 POP EDX
0167:5109812A POP ECX
0167:5109812B POP ECX
0167:5109812C MOV [FS:EAX],EDX
0167:5109812F PUSH DWORD 51098151
0167:51098134 LEA EAX,[EBP-10]
0167:51098137 CALL 51003CA8
0167:5109813C LEA EAX,[EBP-08]
0167:5109813F MOV EDX,02
0167:51098144 CALL 51003CCC
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 算注册码的CALL一
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0167:51097F9C PUSH EBP
0167:51097F9D MOV EBP,ESP
0167:51097F9F ADD ESP,BYTE -10
0167:51097FA2 MOV [EBP-04],EAX
0167:51097FA5 MOV EAX,[EBP-04]
0167:51097FA8 CALL 510040DC
0167:51097FAD XOR EAX,EAX
0167:51097FAF PUSH EBP
0167:51097FB0 PUSH DWORD 51098016
0167:51097FB5 PUSH DWORD [FS:EAX]
0167:51097FB8 MOV [FS:EAX],ESP
0167:51097FBB MOV DWORD [EBP-08],FFFFFFFF ==>设[ebp-8]为tempvar
0167:51097FC2 MOV EAX,[EBP-04] ==>那串字符串设为str[]
0167:51097FC5 CALL 51003F28
0167:51097FCA TEST EAX,EAX
0167:51097FCC JNG 51097FF5
0167:51097FCE MOV [EBP-10],EAX ==>设[ebp-10]为lenofnc
0167:51097FD1 MOV DWORD [EBP-0C],01 ==>设[ebp-c]为i
0167:51097FD8 MOV EAX,[EBP-04] ==>字符串地址addrofstr<--[ebp-4]
0167:51097FDB MOV EDX,[EBP-0C] ==>用edx来从字符串定位字符
0167:51097FDE MOV AL,[EAX+EDX-01] ==>一次取一个字符
0167:51097FE2 MOV EDX,[EBP-08] ==>edx<--tempvar,初值为-1
0167:51097FE5 CALL 51097F48 ==>中间为查表过程,过会详细看看
0167:51097FEA MOV [EBP-08],EAX ==>得到的结果放入tempvar
0167:51097FED INC DWORD [EBP-0C] ==>i++
0167:51097FF0 DEC DWORD [EBP-10] ==>lenofnc--
0167:51097FF3 JNZ 51097FD8 ==>lenofnc==0?往下走:循环
0167:51097FF5 MOV EAX,[EBP-08]
0167:51097FF8 CALL 51097F80 ==>得到的最终结果取反
0167:51097FFD MOV [EBP-08],EAX
0167:51098000 XOR EAX,EAX
0167:51098002 POP EDX
0167:51098003 POP ECX
0167:51098004 POP ECX
0167:51098005 MOV [FS:EAX],EDX
0167:51098008 PUSH DWORD 5109801D
0167:5109800D LEA EAX,[EBP-04]
0167:51098010 CALL 51003CA8
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 注册码从call
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0167:51097F48 PUSH EBP
0167:51097F49 MOV EBP,ESP
0167:51097F4B ADD ESP,BYTE -0C
0167:51097F4E MOV [EBP-08],EDX ==>tempvar
0167:51097F51 MOV [EBP-01],AL ==>所取字符
0167:51097F54 MOV AL,[EBP-08]
0167:51097F57 XOR AL,[EBP-01] ==>tempvar^str[i]
0167:51097F5A AND EAX,FF ==>temp<--tempvar^str[i]&0xff
0167:51097F5F MOV EAX,[EAX*4+510DFEB4] ==>用temp查表送往eax
0167:51097F66 MOV EDX,[EBP-08]
0167:51097F69 SHR EDX,08 ==>tempvar>>=8
0167:51097F6C AND EDX,00FFFFFF ==>tempvar&=0xffffff
0167:51097F72 XOR EAX,EDX ==>eax<--tempvar^[temp*4+510dfeb4]
0167:51097F74 MOV [EBP-0C],EAX
0167:51097F77 MOV EAX,[EBP-0C]
0167:51097F7A MOV ESP,EBP
0167:51097F7C POP EBP
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 在这里面,刚才的最终数被取反
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0167:51097F80 PUSH EBP
0167:51097F81 MOV EBP,ESP
0167:51097F83 ADD ESP,BYTE -08
0167:51097F86 MOV [EBP-04],EAX
0167:51097F89 MOV EAX,[EBP-04]
0167:51097F8C XOR EAX,BYTE -01 ==>It's here!!!
0167:51097F8F MOV [EBP-08],EAX
0167:51097F92 MOV EAX,[EBP-08]
0167:51097F95 POP ECX
0167:51097F96 POP ECX
0167:51097F97 POP EBP
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 最后一个call,用来算六位注册码
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0167:51098024 PUSH EBP
0167:51098025 MOV EBP,ESP
0167:51098027 ADD ESP,BYTE -14
0167:5109802A XOR ECX,ECX
0167:5109802C MOV [EBP-14],ECX
0167:5109802F MOV [EBP-08],EDX
0167:51098032 MOV [EBP-04],EAX
0167:51098035 XOR EAX,EAX
0167:51098037 PUSH EBP
0167:51098038 PUSH DWORD 510980A6
0167:5109803D PUSH DWORD [FS:EAX]
0167:51098040 MOV [FS:EAX],ESP
0167:51098043 MOV EAX,[EBP-08]
0167:51098046 CALL 51003CA8
0167:5109804B XOR EAX,EAX
0167:5109804D MOV [EBP-0C],EAX
0167:51098050 MOV EAX,[EBP-04] ==>刚才求得的那个数字
0167:51098053 MOV ECX,24 ==>除数为0x24
0167:51098058 XOR EDX,EDX
0167:5109805A DIV ECX ==>edx=eax%0x24
0167:5109805C MOV DL,[EDX+510E02B5] ==>用余数来查表
0167:51098062 LEA EAX,[EBP-14] ==>这里的地址用来存放注册码
0167:51098065 CALL 51003E50 ==>存注册码
0167:5109806A MOV EDX,[EBP-14]
0167:5109806D MOV EAX,[EBP-08]
0167:51098070 CALL 51003F30
0167:51098075 MOV EAX,[EBP-08]
0167:51098078 MOV EAX,[EBP-04]
0167:5109807B MOV ECX,24
0167:51098080 XOR EDX,EDX
0167:51098082 DIV ECX
0167:51098084 MOV [EBP-04],EAX ==>将除完了的数放回ebp-4
0167:51098087 INC DWORD [EBP-0C] ==>循环计数器
0167:5109808A CMP DWORD [EBP-0C],BYTE +06 ==>是否已经六位了?
0167:5109808E JNZ 51098050
0167:51098090 XOR EAX,EAX
0167:51098092 POP EDX
0167:51098093 POP ECX
0167:51098094 POP ECX
0167:51098095 MOV [FS:EAX],EDX
0167:51098098 PUSH DWORD 510980AD
0167:5109809D LEA EAX,[EBP-14]
0167:510980A0 CALL 51003CA8
##############################################################
我认为我分析的挺详细了,有什么地方不对谢谢指教!其实就是这么简单,不过我的注册机放2000下了,没法帖出来,见谅,不过到这里,大家也能自己写出来了吧!
相关视频
相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么
热门文章 去除winrar注册框方法
最新文章
比特币病毒怎么破解 比去除winrar注册框方法
华为无线路由器HG522-C破解教程(附超级密码JEB格式文件京东电子书下载和阅读限制破解教UltraISO注册码全集(最新)通过Access破解MSSQL获得数据
人气排行 华为无线路由器HG522-C破解教程(附超级密码JEB格式文件京东电子书下载和阅读限制破解教UltraISO注册码全集(最新)qq相册密码破解方法去除winrar注册框方法(适应任何版本)怎么用手机破解收费游戏华为无线猫HG522破解如何给软件脱壳基础教程
查看所有0条评论>>