老文章档案 · 2003 年

HappyEO算法分析

破解教程 · 算法分析 · 2003-06-25 · 作者:bbbsl 人气: · 出处:嬴政天下整理收藏)

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下了,没法帖出来,见谅,不过到这里,大家也能自己写出来了吧! (出处:嬴政天下整理收藏)

相关文章:

·语音界面2.0算法分析及注册机源码!

·侠客系统修改器1.21破解手记--算法分析

·中文拨号上网计时计费器 V4.12注册算法分析

·ClockWise 3.22e注册码算法分析

·CoolClock V1.02注册算法分析

·Directory Scanner v1.5 注册算法分析

·Disk Chief 1.2 简单注册算法分析

·EffeTech HTTP Sniffer 3.2注册算法分析

·eLib2.01算法分析

·EZ MP3 Recorder 1.15 注册算法分析

相关软件:

→ 特别推荐

→ 热点TOP10

我为人人《《==》》人人为我

关于我们 |

帮助(?)

| 广告服务 |

版权声明 |

商业合作 |

发展历程 |

加盟我们 |

联系我们

Copyright © 1999-2003

winzheng.com All Rights Reserved.

繁体版:由华琦数码技术提供

Powered

by:MeSky.Net

2003-2004 年,宽带刚刚普及,下载站的文章区是许多人学电脑的第一课堂。
🕰 → 🤖 从那时到现在

当年一篇教程能让一台电脑焕然一新;今天的效率工具换成了 AI。 想知道当下最可靠的 AI 模型怎么选?看 赢政指数——我们用了 28 年的选软件严谨,现在用来评测大模型。

档案性质声明:本页为赢政天下(1998-2011)老文章的历史档案复原, 内容反映当年发表时的原貌——包括当年的技术表述、软件版本与观点,部分方法在今天已不适用或不合规,仅作互联网历史记录与研究用途, 不提供任何形式的下载。原始数据经由公共网络存档(Internet Archive)复原。发现问题请联系我们
← 返回老文章档案 · 软件史档案馆 · 赢政天下站史