【ChinaBeta.Cn 网络安全】
【软件名称】Alarm Master 【下载地址】天空 【应用平台】Win9x/NT/2000/XP 【软件大小】未知 【软件限制】nag+时间限制 【破解声明】破解只是感兴趣,无其它目的。失误之处敬请诸位大侠赐教! ======================================================================================== 【分析过程】 试验码: Regname:ligyuan Regcode:1234 5678 abcd efgh 运行软件,有nag和剩余时间提示,点注册弹出注册对话框,输入试验码,下断点bp getDlgItem,bp GetDlg ItemTextA,bp GetWindowTextA,点OK,没有被断下,弹出错误对话框,点try again,程序被截下,Ctrl+F9 返回 F9几次后,弹出了注册对话框,再次输入试验码,点OK程序运行返回到这里 100020C1 51 push ecx 100020C2 68 2D1F0010 push BSSuppor.10001F2D 100020C7 FF71 0C push dword ptr ds:[ecx+C] 100020CA FF71 10 push dword ptr ds:[ecx+10] 100020CD FF71 04 push dword ptr ds:[ecx+4] 100020D0 FF15 54D10010 call dword ptr ds:[<&USER32.DialogBoxParamA>] ; 100020D6 8BF0 mov esi,eax 100020D8 83FE FF cmp esi,-1 100020DB 75 05 jnz short BSSuppor.100020E2 100020DD E8 1EEFFFFF call BSSuppor.10001000 100020E2 8BC6 mov eax,esi ;F8单步运行 100020E4 5E pop esi 100020E5 C3 retn ;运行到这后返回 ///////////////////////////////////////////////////////////////////////// 10002DC6 8B06 mov eax,dword ptr ds:[esi] ;来到这里 10002DC8 FFB0 CC010000 push dword ptr ds:[eax+1CC] 10002DCE 8D4D E8 lea ecx,dword ptr ss:[ebp-18] 10002DD1 E8 46FAFFFF call BSSuppor.1000281C ;这里是把每一组注册码转为16进制 10002DD6 8B06 mov eax,dword ptr ds:[esi] 10002DD8 8B4D AC mov ecx,dword ptr ss:[ebp-54] ;第一组的16进制送ecx 10002DDB 8988 F0010000 mov dword ptr ds:[eax+1F0],ecx ;转存到ds:[eax+1F0] 10002DE1 8B06 mov eax,dword ptr ds:[esi] 10002DE3 8B4D B0 mov ecx,dword ptr ss:[ebp-50] ;第二组的16进制送ecx 10002DE6 8988 F4010000 mov dword ptr ds:[eax+1F4],ecx ;转存到ds:[eax+1F4] 10002DEC 8B06 mov eax,dword ptr ds:[esi] 10002DEE 8B4D B4 mov ecx,dword ptr ss:[ebp-4C] ;第三组的16进制送ecx 10002DF1 8988 F8010000 mov dword ptr ds:[eax+1F8],ecx ;转存到ds:[eax+1F8] 10002DF7 8B06 mov eax,dword ptr ds:[esi] 10002DF9 8B4D B8 mov ecx,dword ptr ss:[ebp-48] ;第四组的16进制送ecx 10002DFC 8988 FC010000 mov dword ptr ds:[eax+1FC],ecx ;转存到ds:[eax+1FC] 10002E02 8B0E mov ecx,dword ptr ds:[esi] 10002E04 8D45 90 lea eax,dword ptr ss:[ebp-70] 10002E07 50 push eax 10002E08 E8 8EFEFFFF call BSSuppor.10002C9B 10002E0D 8B1E mov ebx,dword ptr ds:[esi] 10002E0F 8BCB mov ecx,ebx 10002E11 E8 AEFBFFFF call BSSuppor.100029C4 10002E16 85C0 test eax,eax 10002E18 /74 08 je short BSSuppor.10002E22 10002E1A |6A 02 push 2 10002E1C |5F pop edi 10002E1D |E9 02010000 jmp BSSuppor.10002F24 10002E22 8D45 BC lea eax,dword ptr ss:[ebp-44] 10002E25 50 push eax 10002E26 8BCB mov ecx,ebx 10002E28 E8 24FFFFFF call BSSuppor.10002D51 10002E2D 8945 F0 mov dword ptr ss:[ebp-10],eax 10002E30 8B0E mov ecx,dword ptr ds:[esi] 10002E32 8B81 F8010000 mov eax,dword ptr ds:[ecx+1F8] 10002E38 8B91 FC010000 mov edx,dword ptr ds:[ecx+1FC] 10002E3E 52 push edx 10002E3F 8945 EC mov dword ptr ss:[ebp-14],eax 10002E42 FF75 EC push dword ptr ss:[ebp-14] 10002E45 8B81 F4010000 mov eax,dword ptr ds:[ecx+1F4] 10002E4B 8B89 F0010000 mov ecx,dword ptr ds:[ecx+1F0] 10002E51 50 push eax 10002E52 51 push ecx 10002E53 FF75 F0 push dword ptr ss:[ebp-10] 10002E56 33DB xor ebx,ebx 10002E58 43 inc ebx 10002E59 8D4D E8 lea ecx,dword ptr ss:[ebp-18] 10002E5C 885D FC mov byte ptr ss:[ebp-4],bl 10002E5F E8 E9FAFFFF call BSSuppor.1000294D ;关键call,F7跟进 10002E64 57 push edi 10002E65 53 push ebx 10002E66 8D4D BC lea ecx,dword ptr ss:[ebp-44] 10002E69 8945 F0 mov dword ptr ss:[ebp-10],eax 10002E6C C645 FC 00 mov byte ptr ss:[ebp-4],0 10002E70 E8 9DE4FFFF call BSSuppor.10001312 10002E75 397D F0 cmp dword ptr ss:[ebp-10],edi 10002E78 0F85 A6000000 jnz BSSuppor.10002F24 下面是跟进后,里面的关键部分,中间省略了一些过程 //////////////////////////////////////////////////////////////对输入的用户名进行处理 10002874 3B7B 14 cmp edi,dword ptr ds:[ebx+14] ;edi是否大于或等于用户名的长度 10002877 7D 2F jge short BSSuppor.100028A8 ;大就跳 10002879 C745 08 01000>mov dword ptr ss:[ebp+8],1 10002880 57 push edi 10002881 8BCB mov ecx,ebx 10002883 E8 BFFFFFFF call BSSuppor.10002847 ;读取用户名的一个字符 10002888 8038 20 cmp byte ptr ds:[eax],20 ;字符的ASCII值是否为0X20 1000288B 75 0A jnz short BSSuppor.10002897 ;不是就跳 1000288D 47 inc edi 1000288E FF45 08 inc dword ptr ss:[ebp+8] 10002891 837D 08 64 cmp dword ptr ss:[ebp+8],64 ;是否大于0X64 10002895 ^ 7C E9 jl short BSSuppor.10002880 ;不是往上跳取下一个字符 10002897 57 push edi 10002898 8BCB mov ecx,ebx 1000289A E8 A8FFFFFF call BSSuppor.10002847 1000289F 8A00 mov al,byte ptr ds:[eax] ;用户名字符的ASCII值送al 100028A1 884435 E8 mov byte ptr ss:[ebp+esi-18],al ;al转送到堆栈中 100028A5 47 inc edi 100028A6 EB 05 jmp short BSSuppor.100028AD 100028A8 C64435 E8 40 mov byte ptr ss:[ebp+esi-18],40 ;用户名长度小于0X10时,用40填充 100028AD 46 inc esi 100028AE 83FE 10 cmp esi,10 ;比较是否进行了0X10 次操作 100028B1 ^ 7C C1 jl short BSSuppor.10002874 ;不是往上跳继续
///////////////////////////////////////////////////////下面是由上面处理后的用户名得出注册码的过程 100028BC 8D7C1D E8 lea edi,dword ptr ss:[ebp+ebx-18] ;用户名的基址送edi 100028C0 C745 08 04000>mov dword ptr ss:[ebp+8],4 ;ss:[ebp+8]=4,用来得出4位注册码 100028C7 8B4D FC mov ecx,dword ptr ss:[ebp-4] ;为ecx赋值一个内存地址 100028CA E8 58FFFFFF call BSSuppor.10002827 ;算法call 100028CF 0FBE0F movsx ecx,byte ptr ds:[edi] ;取用户名的一个字符值送ecx 100028D2 33D2 xor edx,edx 100028D4 8D4408 F6 lea eax,dword ptr ds:[eax+ecx-A] ;eax=eax+ecx-0xa 100028D8 6A 0A push 0A 100028DA 59 pop ecx ;ecx=0xa 100028DB F7F1 div ecx ;eax=eax/ecx,edx=eax%ecx 100028DD 83C7 04 add edi,4 ;edi+=4,相当于隔3个字符取下一字符 100028E0 80C2 30 add dl,30 ;dl+=30 100028E3 889435 E8FEFF>mov byte ptr ss:[ebp+esi-118],dl ;得到值的对应字符送到存储空间保存 100028EA 46 inc esi ;esi++ 100028EB FF4D 08 dec dword ptr ss:[ebp+8] ;从4减到0 100028EE ^ 75 D7 jnz short BSSuppor.100028C7 ;不为0就往上跳继续下一个字符 100028F0 C68435 E8FEFF>mov byte ptr ss:[ebp+esi-118],20 ;每4个字符用空格隔开 100028F8 46 inc esi 100028F9 43 inc ebx ;ebx++(ebx初始为0) 100028FA 83FB 04 cmp ebx,4 ;比较ebx是否小于4 100028FD ^ 7C BD jl short BSSuppor.100028BC ;小就往上跳,获得另一4位注册码 100028FF C68435 E7FEFF>mov byte ptr ss:[ebp+esi-119],0 10002907 33F6 xor esi,esi 10002909 8D85 FAFEFFFF lea eax,dword ptr ss:[ebp-106] 1000290F 8A18 mov bl,byte ptr ds:[eax] ;下面这段代码是把上面4组注册码反向 10002911 8D8C35 E8FEFF>lea ecx,dword ptr ss:[ebp+esi-118] 10002918 0FBE11 movsx edx,byte ptr ds:[ecx] 1000291B 8819 mov byte ptr ds:[ecx],bl 1000291D 46 inc esi 1000291E 8810 mov byte ptr ds:[eax],dl 10002920 48 dec eax 10002921 83FE 09 cmp esi,9 10002924 ^ 7C E9 jl short BSSuppor.1000290F ;这个变换后得到的就是正确的注册码
///////////////////////////////////////////////////////////////跟进算法call 10002827 8B01 mov eax,dword ptr ds:[ecx] 10002829 69C0 FD430300 imul eax,eax,343FD ;eax*=0X343FD 1000282F 05 C39E2600 add eax,269EC3 ;eax+=0x269ec3 10002834 8901 mov dword ptr ds:[ecx],eax ;eax的值保存在ds:[ecx]地址中 10002836 C1F8 10 sar eax,10 ;eax>>=10 10002839 25 FF7F0000 and eax,7FFF ;eax^=0x7fff 1000283E 99 cdq ;edx符号扩展 1000283F 6A 0A push 0A 10002841 59 pop ecx ;ecx=0xa 10002842 F7F9 idiv ecx ;eax=eax/ecx,edx=eax%0xa 10002844 8BC2 mov eax,edx ;eax=edx 10002846 C3 retn ////////////////////////////////////////////////////////下面这里是输入的家假码与真码比较的部分 1000297D 8B45 0C mov eax,dword ptr ss:[ebp+C] ;假码第1部分送eax 10002980 3B45 FC cmp eax,dword ptr ss:[ebp-4] ;与真码第1部分比较 10002983 8B5D 18 mov ebx,dword ptr ss:[ebp+18] ;假码第2部分送ebx 10002986 8B7D 14 mov edi,dword ptr ss:[ebp+14] ;假码第3部分送edi 10002989 8B55 10 mov edx,dword ptr ss:[ebp+10] ;假码第4部分送edx 1000298C 75 0F jnz short BSSuppor.1000299D ;不等就跳 1000298E 3B55 F8 cmp edx,dword ptr ss:[ebp-8] ;与真码第2部分比较 10002991 75 0A jnz short BSSuppor.1000299D 10002993 3B7D F4 cmp edi,dword ptr ss:[ebp-C] ;与真码第3部分比较 10002996 75 05 jnz short BSSuppor.1000299D 10002998 3B5D F0 cmp ebx,dword ptr ss:[ebp-10] ;与真码第4部分比较 1000299B 74 1A je short BSSuppor.100029B7 ;都相等就跳到结束(成功) 1000299D B9 D2040000 mov ecx,4D2 ;上面任一部分不同都会来到这里4d2=1234 100029A2 3BC1 cmp eax,ecx ;第一部分是不是为1234 100029A4 75 16 jnz short BSSuppor.100029BC 100029A6 B8 2E160000 mov eax,162E ;162e=5678 100029AB 3BD0 cmp edx,eax ;第4部分是否为5678 100029AD 75 0D jnz short BSSuppor.100029BC 100029AF 3BF9 cmp edi,ecx ;第3部分是不是为1234 100029B1 75 09 jnz short BSSuppor.100029BC 100029B3 3BD8 cmp ebx,eax ;第2部分是否为5678 100029B5 75 05 jnz short BSSuppor.100029BC;满足上面的4个比较也能成功注册 100029B7 33C0 xor eax,eax ;因此有一个万能码1234-5678-1234-5678 100029B9 40 inc eax 100029BA EB 02 jmp short BSSuppor.100029BE 100029BC 33C0 xor eax,eax 一个简单的注册机: void main(){ char regname[50],regcode[20]; long temp1=0,temp2=0; printf("请输入Regname:"); gets(regname); int stlen=strlen(regname); if(stlen<16) for(;stlen<16;stlen++) regname[stlen]=0x40; for(int i=0, t=0;i<4;i++, t=0){ if(i)regcode[19-5*i]=0x2d; for(int j=0;j<16;j+=4,t++){ temp1*=0x343FD; temp1+=0x269ec3; temp2=temp1; __asm{ mov eax,temp2 sar eax,010h and eax,07FFFh cdq mov ecx,0ah idiv ecx mov temp2,edx } temp2=temp2+regname[j+i]-0xa; temp2=temp2%0xa+0x30; regcode[18-5*i-t]=temp2; } } regcode[19]=''; printf("你的Regcode:%sn",regcode); } 请输入Regname:ligyuan 你的Regcode:5153-4723-9940-1266 也可以用万能码1234-5678-1234-5678
软件的注册保护没有过多的考虑,找到关键点后能够轻松的实现算法注册机,还留了万能码,差 一点我就中了头奖,这样,我这个菜鸟也才有了练手的机会,由于代码中没有考虑到输入空格时 的处理,因此有很多不足之处,还望不要笑话鄙人。。。。。。
(责任编辑:hahack)
注:本站所有资料均为个人爱好与广大网友分享!如用于非法!造成一切后果自负·与本站无关! |