题外话:以前每逢寒暑假,都能有时间找来几个软件练练手,但这个假期不行,参编的一本书的几万字还没动笔,也就没时间破解了。还有,现在我只是对注册的计算过程感兴趣,而对暴破兴趣不大,但这需要更多的时间去分析,无疑增加了难度,而且现在很多软件越来越破了,也没有那么大的精力去做,只好将放假前做的这个破解整理一下发表在这。
下载地址:http://media2.533.net/source/directmediaxtra201_fulldownload.exe
软件简介:一个authorware多媒体xtra插件,安装后可以很方便地插入midi、视频、flash等多媒体文件,并能很方便地对它们进行控制。
破解工具:ida pro 4.15,softice 4.05 for win9x
破解过程:首先,将directmediaxtra安装到authorware的xtras文件夹下,这是安装程序会在xtras下面directmediaxtra.x32,这个就是外部多媒体插件。安装好后,运行authorware 5.2,选择insert->tabuleiro xtras->directmediaxtra,出现directmediaxtra properties后,会显示unregisted,单击register后,随便输入用户名和序列号,激活softice,下bpx hmemcpy(当然,还有更好的断点可下,好像是getwindowtexta,时间长了,记不清了),按f12、f10直到来到下面
.text:100086a0 arg_0 = dword ptr 4 ====> 注册码
.text:100086a0 arg_4 = dword ptr 8 ====> 用户名
.text:100086a0
.text:100086a0 sub esp, 18h
.text:100086a3 mov eax, dword_1003aa90
.text:100086a8 push ebx
.text:100086a9 push ebp
.text:100086aa mov ebp, [esp+20h+arg_0]
.text:100086ae push esi
.text:100086af push edi
.text:100086b0 mov [esp+28h+var_c], eax
.text:100086b4 mov edi, ebp
.text:100086b6 or ecx, 0ffffffffh
.text:100086b9 xor eax, eax
.text:100086bb repne scasb
.text:100086bd not ecx
.text:100086bf dec ecx
.text:100086c0 cmp ecx, 14h ====> 注册码是否20位
.text:100086c3 jnz loc_100088d6 ====> 不是则错
.text:100086c9 mov cl, [ebp+3] ====> 第4位注册码
.text:100086cc mov dl, [ebp+4] ====> 第5位注册码
.text:100086cf mov [esp+28h+var_16], al
.text:100086d3 lea eax, [esp+28h+var_18]
.text:100086d7 push eax
.text:100086d8 mov [esp+2ch+var_18], cl
.text:100086dc mov [esp+2ch+var_17], dl
.text:100086e0 call _atoi ====> 将第4、5位注册码转为数字
.text:100086e5 add esp, 4
.text:100086e8 cmp eax, 14h ====> 是否是"20"
.text:100086eb jnz loc_100088d6 ====> 不是则错
.text:100086f1 mov al, [ebp+2] /
.text:100086f4 mov cl, [ebp+0] > ====> 取注册码的前3位
.text:100086f7 mov dl, [ebp+1] /
.text:100086fa mov byte ptr [esp+28h+arg_0+2], al
.text:100086fe mov byte ptr [esp+28h+arg_0], cl
.text:10008702 mov byte ptr [esp+28h+arg_0+1], dl
.text:10008706 mov byte ptr [esp+28h+arg_0+3], 0
.text:1000870b lea esi, [esp+28h+var_c] ====> esi指向"dmx"
.text:1000870f lea eax, [esp+28h+arg_0] ====> 指向注册码的前3位
.text:10008713 mov dl, [eax] /
.text:10008715 mov bl, [esi] |
.text:10008717 mov cl, dl |
.text:10008719 cmp dl, bl |
.text:1000871b jnz short loc_1000873b |
.text:1000871d test cl, cl |
.text:1000871f jz short loc_10008737 |
.text:10008721 mov dl, [eax+1] |
.text:10008724 mov bl, [esi+1] |
.text:10008727 mov cl, dl /
.text:10008729 cmp dl, bl /====> 比较注册码的前3位是否是"dmx"
.text:1000872b jnz short loc_1000873b |
.text:1000872d add eax, 2 |
.text:10008730 add esi, 2 |
.text:10008733 test cl, cl |
.text:10008735 jnz short loc_10008713 |
.text:10008737 xor eax, eax |
.text:10008739 jmp short loc_10008740 |
.text:1000873b sbb eax, eax |
.text:1000873d sbb eax, 0ffffffffh |
.text:10008740 test eax, eax |
.text:10008742 jnz loc_100088d6 /
.text:10008748 mov al, [ebp+7] ====> regcode(8)
.text:1000874b lea ecx, [esp+28h+arg_0]
.text:1000874f push ecx
.text:10008750 mov byte ptr [esp+2ch+arg_0], al
.text:10008754 call _atoi ====> 转为数字
.text:10008759 mov dl, [ebp+0bh] ====> regcode(12)
.text:1000875c mov edi, eax ====> edi=regcode(8)
.text:1000875e lea eax, [esp+2ch+arg_0]
.text:10008762 mov byte ptr [esp+2ch+arg_0], dl
.text:10008766 push eax
.text:10008767 call _atoi ====> 转为数字
.text:1000876c mov cl, [ebp+11h] ====> regcode(18)
.text:1000876f lea edx, [esp+30h+arg_0]
.text:10008773 push edx
.text:10008774 mov ebx, eax ====> ebx=regcode(12)
.text:10008776 mov byte ptr [esp+34h+arg_0], cl
.text:1000877a call _atoi
.text:1000877f mov [esp+34h+var_8], eax ====> regcode(18)放到这里
.text:10008783 mov al, [ebp+0ch] ====> regcode(13)
.text:10008786 lea ecx, [esp+34h+arg_0]
.text:1000878a mov byte ptr [esp+34h+arg_0], al
.text:1000878e push ecx
.text:1000878f call _atoi
.text:10008794 mov dl, [ebp+10h] ====> regcode(17)
.text:10008797 mov esi, eax ====> esi=regcode(13)
.text:10008799 lea eax, [esp+38h+arg_0]
.text:1000879d mov byte ptr [esp+38h+arg_0], dl
.text:100087a1 push eax
.text:100087a2 call _atoi
.text:100087a7 mov cl, [ebp+8] ====> regcode(9)
.text:100087aa lea edx, [esp+3ch+arg_0]
.text:100087ae push edx
.text:100087af mov [esp+40h+var_4], eax ====> regcode(17)放到这里
.text:100087b3 mov byte ptr [esp+40h+arg_0], cl
.text:100087b7 call _atoi
.text:100087bc mov ecx, [esp+40h+var_8] ====> regcode(18)
.text:100087c0 mov edx, [esp+40h+var_4] ====> regcode(17)
.text:100087c4 add eax, ecx ====> regcode(9)+regcode(18)
.text:100087c6 lea ecx, [esi+esi*2] ====> regcode(13)*3
.text:100087c9 mov [esp+40h+var_11], 0
.text:100087ce mov [esp+40h+var_d], 0
.text:100087d3 lea eax, [eax+edx*4] ====> regcode(17)*4+regcode(9)+regcode(18)
.text:100087d6 add ecx, eax ====> regcode(13)*3+regcode(17)*4+regcode(9)+regcode(18)
.text:100087d8 movsx eax, byte ptr [esp+40h+var_c+2] ====> eax="x"
.text:100087dd add ecx, ebx ====> regcode(13)*3+regcode(17)*4+regcode(9)+regcode(18)+regcode(12)
.text:100087df lea esi, [ecx+edi+0eh] ====> regcode(8)+regcode(13)*3+regcode(17)*4+regcode(9)+regcode(18)+regcode(12)+0eh
.text:100087e3 mov ecx, [esp+40h+var_c] ====> ecx="dm"
.text:100087e7 movsx edx, ch ====> edx="m"
.text:100087ea movsx ecx, cl ====> ecx="d"
.text:100087ed add eax, edx
.text:100087ef add eax, ecx ====> eax="d"+"m"+"x"=e9h
.text:100087f1 mov ecx, 3e8h ====> ecx=3e8h=1000
.text:100087f6 lea eax, [eax+eax*4] ====> eax*5=48dh
.text:100087f9 shl eax, 2 ====> eax*4=1234h
.text:100087fc cdq
.text:100087fd idiv esi ====> 整除
.text:100087ff add eax, 73h ====> 商+73h
.text:10008802 cdq
.text:10008803 idiv ecx ====> 除以1000,取余数
.text:10008805 mov al, [ebp+0dh] ====> regcode(14)
.text:10008808 mov cl, [ebp+12h] ====> regcode(19)
.text:1000880b mov [esp+40h+var_13], al
.text:1000880f mov al, [ebp+9] ====> regcode(10)
.text:10008812 mov [esp+40h+var_12], cl
.text:10008816 mov cl, [ebp+0eh] ====> regcode(15)
.text:10008819 mov [esp+40h+var_f], al
.text:1000881d mov [esp+40h+var_e], cl
.text:10008821 mov esi, edx ====> esi=余数
.text:10008823 mov dl, [ebp+6] ====> regcode(7)
.text:10008826 mov [esp+40h+var_14], dl
.text:1000882a mov dl, [ebp+13h] ====> regcode(20)
.text:1000882d mov [esp+40h+var_10], dl
.text:10008831 lea edx, [esp+40h+var_14] ====> 位置顺序:r(7)r(14)r(19)
.text:10008835 push edx
.text:10008836 call _atoi ====> 转为整数
.text:1000883b mov edi, eax ====> 放到edi中
.text:1000883d lea eax, [esp+44h+var_10] ====> 位置顺序:r(20)r(10)r(15)
.text:10008841 push eax
.text:10008842 call _atoi ====> 转为整数
.text:10008847 add esp, 20h
.text:1000884a mov ecx, eax ====> 放到ecx中
.text:1000884c cmp edi, esi ====> 与余数比较
.text:1000884e jnz loc_100088d6 ====> 不等则错误
.text:10008854 mov eax, 55555556h
.text:10008859 imul esi ====> 乘以余数
.text:1000885b mov eax, edx ====> 取高位数放到eax中
.text:1000885d mov esi, 3e8h
.text:10008862 shr eax, 1fh ====> 右移1f位,即除以2^31
.text:10008865 lea eax, [edx+eax+159h] ====> +345(159h)
.text:1000886c cdq
.text:1000886d idiv esi ====> 除以1000
.text:1000886f cmp ecx, edx ====> 进行比较
.text:10008871 jnz short loc_100088d6 ====> 不等则错误
.text:10008873 mov edx, [esp+28h+arg_4] ====> 用户名
.text:10008877 or ecx, 0ffffffffh
.text:1000887a mov edi, edx
.text:1000887c xor eax, eax
.text:1000887e repne scasb
.text:10008880 not ecx
.text:10008882 dec ecx
.text:10008883 test ecx, ecx ====> 用户名是否为空
.text:10008885 jle short loc_100088d6 ====> 为空则错误
:
:
:
.text:100088c2 mov eax, 1 ====> 成功的旗标eax=1
.text:100088c7 and ecx, 3
.text:100088ca repe movsb
.text:100088cc pop edi
.text:100088cd pop esi
.text:100088ce pop ebp
.text:100088cf pop ebx
.text:100088d0 add esp, 18h
.text:100088d3 retn 8
.text:100088d6 pop edi
.text:100088d7 pop esi
.text:100088d8 pop ebp
.text:100088d9 xor eax, eax ====> 失败的旗标eax=0
.text:100088db pop ebx
.text:100088dc add esp, 18h
.text:100088df retn 8
.text:100088df sub_100086a0 endp
注册码的计算过程:前5个字符必须为"dmx20"
设x=regcode(8)+regcode(13)*3+regcode(17)*4+regcode(9)+regcode(18)+regcode(12)+14
y=(hex("d")+hex("m")+hex("x"))*20
z=((y / x)+115) mod 1000
z=regcode(7,14,19)
(z*55555556h的高位+345) mod 1000=regcode(20,10,15)
根据上面的计算过程,随机生成第8、9、12、13、17、18和6、11、16位的注册码后,再推算出第7、10、14、15、19、20位的注册码即可,注册机已做成。
注册成功后,会在directmediaxtra.x32所在的文件夹下生成一个名为dmx2.lic的隐藏注册文件,里面就是注册名和注册码,可以用文本编辑器打开,以后只要把这个注册文件复制到相应文件夹即可。