AlarmMaster V4.13 算法分析(疲劳指数:★★★^_^,想消磨时间的朋友进)
【破文标题】AlarmMaster V4.13 算法分析(疲劳指数:★★★^_^,想消磨时间的朋友进)【破文作者】飘云
【作者邮箱】[email protected]
【作者主页】WwW.ChiNaPYG.CoM
【破解工具】Peid0.94,OllyDbg,VC++
【破解平台】Win9x/NT/2000/XP
【软件名称】AlarmMaster V4.13
【软件大小】644kb
【原版下载】http://www.brigsoft.com/alarm-clock/download/AlarmMasterInst.exe
【保护方式】Nag+Name+Code
【软件简介】 这是一个简单的闹钟、时程表、计时器、PC 对时器程序。只需按一下鼠标就可以设定闹铃的时间,同时也可以在日程表上设定闹铃,你可以设在任一个时间,并可以对每一个闹铃设定文字讯息。闹铃几乎没有限制,而且每组都可以设定个自的声音。这程序还附有对时功能,再你每次上线时它就会自动连接原子钟帮你对时。
【破解声明】我是一只菜菜鸟,偶得一点心得,愿与大家分享 !^_^
------------------------------------------------------------------------
【破解过程】先运行程序,打开注册窗口,发现有4组注册码框~~
OD载入程序后,搜索字符串,没有找到~~~
欲下断 bp GetDlgItem
Nag窗口出来之后,选择 “Enter Registration Code” 马上断住了~~~
0012F8D0 1000210C/CALL 到 GetDlgItem 来自 BSSuppor.1000210A
0012F8D4 002603DE|hWnd = 002603DE ('Alarm Master',class='#32770')
0012F8D8 000003E9\ControlID = 3E9 (1001.)
我晕,原来在DLL文件中效验注册码,难怪刚刚找不到有用信息咯~~
ALT+F9返回
1000210C push 3EA//返回到这里~~
10002111 push ebx
10002112 mov , eax
10002115 call edi
10002117 push 3EB
用插件搜索字符串吧:
找到个有用的~~
%d%d%d%d(c++的格式字符串)这不正式我们四个输入框的格式字符串吗?
双击后来到:
1000285E push ebp //代码开始处,F2下断
1000285F mov ebp, esp
10002861 sub esp, 118
10002867 push ebx
.
.
.
1000292F dword ptr
10002932 dword ptr
10002935 dword ptr
10002938 1000D2D8 ; %d%d%d%d//★来到这里,向上看!★
将以前的断点取消,在 1000285E 下断,输入注册信息:
piaoyun
1111-2222-3333-4444
立刻中断~:
1000285E push ebp
1000285F mov ebp, esp
10002861 sub esp, 118
10002867 push ebx
10002868 mov ebx,
1000286B push esi
1000286C push edi
1000286D xor edi, edi
1000286F mov , ecx
10002872 xor esi, esi
10002874 cmp edi, ; 变量和用户名长度比较(意即用户名算法部分的循环开关)
10002877 jge short 100028A8
10002879 mov dword ptr , 1
10002880 push edi
10002881 mov ecx, ebx
10002883 call 10002847
10002888 cmp byte ptr , 20 ; 逐个字符与空格比较
1000288B jnz short 10002897
1000288D inc edi
1000288E inc dword ptr
10002891 cmp dword ptr , 64
10002895 jl short 10002880
10002897 push edi
10002898 mov ecx, ebx
1000289A call 10002847
1000289F mov al, ; 逐位当前指针处字符ASCII到al
100028A1 mov , al ; 转存
100028A5 inc edi ; 指向用户名下一位
100028A6 jmp short 100028AD
100028A8 mov byte ptr , 40 ; 追加“@”字符 40=“@” 追加的个数为 16-用户名长度
100028AD inc esi ; 指向注册码下一位
100028AE cmp esi, 10 ; 是否取完16(10进制)位?
100028B1 jl short 10002874 ; 循环 变换后的用户名("piaoyun@@@@@@@@@")
100028B3 mov byte ptr , 0
100028B8 xor esi, esi
100028BA xor ebx, ebx
100028BC lea edi,
100028C0 mov dword ptr , 4
100028C7 mov ecx,
100028CA call 10002827 ; 算法CALL 跟进! EAX中返回的是关键值
100028CF movsx ecx, byte ptr ; 取变换后的用户名ASCII送ecx(共4轮循环 第一轮:1、5、9、13位,第二轮:2、6、
10、14位,第三轮:3、7、11、15位,第四轮:4、8、12、16位)
100028D2 xor edx, edx ; edx 清零
100028D4 lea eax, ; eax=eax+ecx-0xa
100028D8 push 0A ; 0x0A(10)
100028DA pop ecx
100028DB div ecx ; eax%0xA (余数放edx)
100028DD add edi, 4 ; 指向变换后用户名的随后第4位
100028E0 add dl, 30 ; 余数+0x30
100028E3 mov , dl ; 保存结果
100028EA inc esi
100028EB dec dword ptr
100028EE jnz short 100028C7 ; 小循环
100028F0 mov byte ptr , 20 ; 每4位(即每1轮大循环)用空格隔开
100028F8 inc esi
100028F9 inc ebx
100028FA cmp ebx, 4 ; 大循环共4轮
100028FD jl short 100028BC
100028FF mov byte ptr , 0
10002907 xor esi, esi
10002909 lea eax,
1000290F mov bl,
10002911 lea ecx,
10002918 movsx edx, byte ptr
1000291B mov , bl
1000291D inc esi
1000291E mov , dl
10002920 dec eax
10002921 cmp esi, 9
10002924 jl short 1000290F ; 此循环为:倒置字符串
10002926 push dword ptr
10002929 lea eax,
1000292F push dword ptr
10002932 push dword ptr
10002935 push dword ptr
10002938 push 1000D2D8 ; %d%d%d%d
1000293D push eax
1000293E call 10004CC7
10002943 add esp, 18
10002946 pop edi
10002947 pop esi
10002948 pop ebx
10002949 leave
1000294A retn 14 ; 返回到 1000297D
*****************************call 10002827*****************************
10002827 mov eax, ; 初始值为0
10002829 imul eax, eax, 343FD ; eax=eax×0x343FD
1000282F add eax, 269EC3 ; eax=eax+0x269EC3
10002834 mov , eax ; 结果保存到
10002836 sar eax, 10 ; EAX右移0x10位
10002839 and eax, 7FFF ; EAX and 0x7FFF
1000283E cdq ; edx符号扩展
1000283F push 0A ; 0xA入栈
10002841 pop ecx
10002842 idiv ecx ; eax%ecx 余数放edx
10002844 mov eax, edx
10002846 retn
***********************************************************************
下面开始验证注册码:
1000297D mov eax, ; 假码第1部分送eax
10002980 cmp eax, ; 和真码第1部分比较
10002983 mov ebx, ; 假码第4部分送ebx
10002986 mov edi, ; 假码第3部分送edi
10002989 mov edx, ; 假码第2部分送edx
1000298C jnz short 1000299D ; 不相等就跳
1000298E cmp edx, ; 和真码第2部分比较
10002991 jnz short 1000299D
10002993 cmp edi, ; 和真码第3部分比较
10002996 jnz short 1000299D
10002998 cmp ebx, ; 和真码第4部分比较
1000299B je short 100029B7 ; 上面都通过就跳到 成功~~
1000299D mov ecx, 4D2 ; ecx=0x4D2(1234)
100029A2 cmp eax, ecx ; 假码第1部分=1234?
100029A4 jnz short 100029BC
100029A6 mov eax, 162E ; eax=0x162E(5678)
100029AB cmp edx, eax ; 假码第2部分=5678?
100029AD jnz short 100029BC
100029AF cmp edi, ecx ; 假码第3部分=1234?
100029B1 jnz short 100029BC
100029B3 cmp ebx, eax ; 假码第4部分=5678?
100029B5 jnz short 100029BC ; 满足上面条件就不跳,也就注册成功了~~ 因此,通用注册码为 1234-5678-1234-5678
100029B7 xor eax, eax
100029B9 inc eax
100029BA jmp short 100029BE
100029BC xor eax, eax
100029BE pop edi
100029BF pop ebx
100029C0 leave
100029C1 retn 14
------------------------------------------------------------------------
【破解总结】
1.对用户名进行变换,规则如下:
变换后的用户名=用户名+(16-用户名长度)个字符"@" piaoyun==>>piaoyun@@@@@@@@@
2.call 10002827中的内容,请自行查看,返回值到eax
3.分4轮大循环取变换后的用户名待下一步运算(第一轮:1、5、9、13位,第二轮:2、6、10、14位,第三轮:3、7、11、15位,第四轮:4、8、12、16位),取得的ASCII均放到ecx中
4.eax=eax+ecx-0xA (eax的初始值由第2步决定)
5.第4步的结果除以0xA的余数+0x30保存起来
6.每4位(即每1轮大循环)用空格隔开 (用空格隔开在还原注册码时不是必须的!只是代表4组而以)
7.倒置第6步的结果即为注册码
通用注册码:1234-5678-1234-5678 ~~ 哈哈,作者在玩你!
注册信息保存在:HKEY_LOCAL_MACHINE\SOFTWARE\BrigSoft\AlarmMaster\Options 删除即可重玩~~------------------------------------------------------------------------
【算法注册机】
//说明:
//注册机是按照算法流程写下来的,没做任何优化处理,仅仅为了方便初学者对照反汇编代码参考
#include "iostream.h"
#include "string.h"
#include "windows.h"
#include "stdio.h"
void main()
{
char Name={0},Code={0},Sn={0};
long Sum0=0,Sum=0;
cout<<"\t\t------------------------------------\n";
cout<<"\t\t|------------------------------|\n";
cout<<"\t\t||KeyGen For AlarmMaster V4.13||\n";
cout<<"\t\t|| Code By PiaoYun ||\n";
cout<<"\t\t|| WwW.ChiNaPYG.CoM ||\n";
cout<<"\t\t||E-mail:[email protected]||\n";
cout<<"\t\t|| WinXP SP2&VC++ 6.0 ||\n";
cout<<"\t\t|------------------------------|\n";
cout<<"\t\t------------------------------------\n";
cout<<"Please Input Your RegName:\n";
cin>>Name;
int i,j,k=0;
int LenName;
byte n;//支持中文
LenName=strlen(Name);
//对用户名进行变换
if(LenName<16)
for(;LenName<16;LenName++)
Name='@';
for(i=0;i<4;i++) //大循环
{
for(j=i;j<16;j+=4,k++)//小循环
//call 10002827里面的算法
{
Sum0*=0x343FD;
Sum0+=0x269EC3;
Sum=Sum0;
__asm
{
mov eax,Sum
sar eax,010H
and eax,07FFFH
cdq
mov ecx,0AH
idiv ecx
mov Sum,edx
}
n=Name;
Sum=Sum+n-0xA;
Sum=Sum%0xA+0x30;
Code=Sum;
}
}
for(i=0;i<16;i++)//倒置字符串作为注册码
{
Sn=Code;
}
cout<<"Your RegCode:\n"<<Sn<<endl;
system("pause");
}
------------------------------------------------------------------------
【版权声明】本文纯属技术交流,转载请注明作者信息并保持文章的完整,谢谢! 坐在沙发上好好学习! 老大强呀。学习! 学习了
论坛再次开通
好像以前没见过的人好多多哦。都是成员啊,版主之类了。:L一个! 坐下听讲。。。。。。。 看不懂~~呵呵,支持老大! 咱来慢慢研究啊~~/:D 学习了~~
页:
[1]
2