- UID
- 61793
注册时间2009-5-2
阅读权限10
最后登录1970-1-1
周游历练
该用户从未签到
|
一:去掉烦人的音乐
这个kegenme比较吵,
Ctrl+N,看看调用了那些与音乐相关的函数
winmm.waveOutClose
winmm.waveOutGetPosition
winmm.waveOutOpen
winmm.waveOutPrepareHeader
winmm.waveOutReset
winmm.waveOutUnprepareHeader
winmm.waveOutWrite
显示,从函数的名称可以看出waveOutOpen是音乐的开启函数
在它上面右键->在每个参考上设置断点,F9运行
来到:
- 00403FAA $- FF25 9C504000 jmp dword ptr ds:[<&winmm.waveOutOpen>] ; WINMM.waveOutOpen
复制代码 Alt+F9
来到:
- 00040192F E8 76260000 call <jmp.&winmm.waveOutOpen>
- 00401934 |. 85C0 test eax,eax
- 把call <jmp.&winmm.waveOutOpen> nop掉,保存,然后启动改后的程序,世界清静了 ^_^
复制代码 ****************************************************************************
二:unlock key分析
现在开干正事:
0040123D cmp eax,6 ; 注册名的长度必须大于6
这个KeyGenme的unlock Key和active Key都只跟用户名的前6位有关
- 00401359 push eax ; eax为用户名的第一位,即name[0]
- 0040135A xor eax,dword ptr ds:[edx*4+406000] ; dword ptr ds:[edx*4+406000] 是根据edx的值到一张固定的表table1中取取值,把值取出来后eax异或
- 00401361 push eax
- 00401362 and eax,0FFFF ;取出eax的后16位
- 00401367 mov ebx,eax
- 00401369 pop eax
- 0040136A and eax,FFFF0000 ;取出eax的前16位
- 0040136F imul eax,ebx ;eax的前16位与后16相乘
- 00401372 xor eax,ebx ;上面相乘的结果和eax的后16位相加
- 00401374 mov dword ptr ds:[edi],eax ; 把上面的结果放入一张空表table2[0]中(table2为一个二维表)
- 00401376 add edi,4
- 00401379 add edx,4
- 0040137C pop eax
- 0040137D loopd short 1.00401359 ;根据ecx来判断循环是否要继续(共循环6次)
复制代码
- 00401380 push edi
- 00401381 call 0040152B ;这是一个算法call
复制代码 进入这个call后来到:
- 0040153F mov al,byte ptr ds:[esi] 把表table2[0]中的数据取出来(00401374处存入的数据)
- 00401541 cmp al,0
- 00401543 je short 1.0040155D 判断al是否为0,如果为0就跳出循环 相当于一个break;
- 00401545 div bx al的值对bx=2求余
- 00401548 or dx,dx
- 0040154B jnz short 1.0040155A 判断余数是否为0,如果为0就进行下一次循环 相当于continue
- 0040154D inc ecx
- 0040154E inc esi
- 0040154F push ecx
- 00401550 push dword ptr ss:[ebp+8]
- 00401553 call 1.00401562 ;这是一个算法call
- 00401558 jmp short 1.0040153F
- 0040155A inc esi
- 0040155B jmp short 1.0040153F
复制代码 进入call 00401562后来到
- 0040156E mov al,byte ptr ds:[esi] ;把表table2[0]中的数据取出来给al
- 00401570 xor al,10 ;al与16作异或
- 00401572 mov byte ptr ds:[esi],al ;把异或后的结果存入表table2[0]中
- 00401574 inc esi
- 00401575 loopd short 1.0040156E ;循环
复制代码 后面有5处是上面的重复
只不过eax不再是name[0],而分别是name[1],name[2],name[3],name[4],name[5]
上面的table2[0]表分别换成table2[1],table2[2],table2[3],table2[4],table2[5]
004013DD push eax
0040141D push eax
0040145D push eax
0040149D push eax
004014DD push eax
上面的程序用c++实现就是:
- UINT table1[]={0x77073096,0x706AF48F,0x79DCB8A4,0x7EB17CBD,0x6AB020F2,0x6DDDE4EB,
- 0x646BA8C0,0x63066CD9,0x4C69105E,0x4B04D447,0x42B2986C,0x45DF5C75,
- 0x51DE003A,0x56B3C423,0x5F058808,0x58684C11,0x01DB7106,0x06B6B51F,
- 0x0F00F934,0x086D3D2D,0x1C6C6162,0x1B01A57B,0x12B7E950,0x15DA2D49,
- 0x3AB551CE,0x3DD895D7,0x346ED9FC,0x33031DE5,0x270241AA,0x206F85B3,
- 0x29D9C998,0x2EB40D81,0x9ABFB3B6,0x9DD277AF,0x94643B84,0x9309FF9D};
- UINT table2[7][10]={0};
- for(i=0;i<6;i++)
- {
- for(j=0;j<6;j++,k++)
- {
- temp=name[i]^table1[k];
- temp1=temp&0x0FFFF;
- temp2=temp&0x0FFFF0000;
- temp2=temp1*temp2;
- temp2=temp2+temp1;
- table2[i][j]=temp2;
- }
- change1((char *)&table2[i][0]);
-
- }
- 其中:
- void change1(char* table)
- {
- int j=1;
- for(int i=0;i<24;i++)
- {
- if(table[i]==0) break;
- if(table[i]%2!=0) continue;
- j++;
- change2(table,j);
- }
- }
- 等同于算法中的call 0040152B
- 其中:
- void change2(char* table,int n)
- {
- for (int i=0;i<n;i++)
- {
- table[i]^=0x10;
- }
- }
- 等同于call 00401562
复制代码
- 00401595 inc edx
- 00401596 add esi,10
- 00401599 add eax,dword ptr ds:[esi]
- 0040159B add esi,4
- 0040159E loopd short 1.00401599 ;
- 把上面的表table2[i](i=0,1,2,3,4,5)中的值分别累计求和
- 得到sum[i](i=0,1,2,3,4,5)
复制代码-
- 004015A0 mov ecx,6
- 004015A5 push eax
- 004015A6 mov dword ptr ds:[ebx],eax
- 004015A8 add ebx,4
- 004015AB xor eax,eax
- 004015AD cmp edx,5
- 004015B0 jnz short 1.00401595
- 004015B2 push 1.004068A9
- 004015B7 push 1.0040686D
- 004015BC call <jmp.&user32.wsprintfA> ;
复制代码 把 sum(i=0,1,2,3,4,5) 以16进制的形式格式输出
如:name为:f3k0eibj0对应的
sum[0]=0X0B9A93087,sum[1]=0X0AA5CEF63,sum[2]=0X0EBCEC057
sum[3]=0X,sum[2]=0X0F7E943A7,sum[2]=0X44BF762B,sum[2]=0X0CD913F5F
结果就是:CD913F5F44BF762BF7E943A7EBCEC057AA5CEF63B9A93087
这个结果就是我们的unlock Key
- 00401269 push 1.0040686D ; ASCII "CD913F5F44BF762BF7E943A7EBCEC057AA5CEF63B9A93087"
- 0040126E push 1.004066B1 ; ASCII "CD913F5F44BF762BF7E943A7EBCEC057AA5CEF63B9A93087"
- 00401273 call 1.00401634
- 00401278 test eax,eax
- 0040127A je short 1.004012CF
复制代码 把你填入的unlock Key码和真码比较,看是否相等
**********************************************************************************
三 active Key的分析
- 004012B8 push eax
- 004012B9 push edi
- 004012BA push esi
- 004012BB call 0040165F //一个算法call
- 004012C0 add esi,28
- 004012C3 add edi,28
- 004012C6 add eax,2
- 004012C9 loopd short 1.004012B8 //循环5次
复制代码 进入上面的call后
- 00401675 mov ax,word ptr ds:[esi] //取出上面table2[i]中的值(i=0,1,2,3,4)
- 00401678 mov bx,word ptr ds:[edi] //取出上面table2[i+1]中的值
- 0040167B call 00401690 //一个算法call
- 00401680 add word ptr ds:[edx],ax //[edx]和ax相加,相加的结果放入表tablek中即[edx]
- 00401683 add esi,2
- 00401686 add edi,2
- 00401689 loopd short 00401675 //循环24次
复制代码 进入call 00401690
- 00401690 cmp ax,bx
- 00401693 jb short 1.00401697
- 00401695 xchg ax,bx //看ax和bx哪个大,大的给bx,小的给ax
- 00401697 sub bx,ax //大数减去小数
- 0040169A jnz short 1.00401690
复制代码 上面用c++实现就是:
- for(i=0;i<5;i++)
- {
- gettable((WORD *)table2[i],(WORD *)table2[i+1],i);
- if(i==3) scpy(table2[6],(UINT*)tablek);
- }
- 其中:
- void gettable(WORD* table1,WORD* table2,int index)
- {
- int i=0;
- int temp=0;
- for (i=0;i<0x18;i++)
- {
- temp+=sub(table1[i],table2[i]);
- }
- tablek[index]=temp;
- }
- 相当于call 0040165F
- 其中:
- int sub(int a,int b)
- {
- int max=a>b?a:b;
- int min=a<b?a:b;
- int temp=0;
- for(;;)
- {
- max=max-min;
- if(max<min)
- {
- temp=max;
- max=min;
- min=temp;
- }
- if(min==0) break;
- }
- return max;
- }
- 相当于:call 00401690
复制代码
- 004016C4 xor eax,7D079EB1
- 004016C9 mov edx,4ADFA541
- 004016CE xor eax,edx
- 004016D0 sub eax,3F4D1
- 004016D5 imul eax,eax,33
- 004016D8 loopd short 1.004016C4
- 004016DA cmp eax,CE337A1C
- 004016DF jnz short 1.004016EA
复制代码 //注册码的长度必须为48位,可以写一个小程序穷举出来
- int main(int argc, char* argv[])
- {
- int i=0;
- int j=0;
- unsigned int temp=0;
- for(i=1;;i++)
- {
- temp=i;
- for(j=0;j<6;j++)
- {
- temp^=0x7D079EB1;
- temp^=0x4ADFA541;
- temp-=0x3F4D1;
- temp=(temp*0x33)&0xFFFFFFFF;
- }
- if(temp==0x0CE337A1C) break;
- }
- printf("这个数是:%d",i);
- return 0;
- }
复制代码
- 00401723 mov bl,byte ptr ds:[edi]
- 00401725 cmp bl,30
- 00401728 jb short 1.00401733
- 0040172A cmp bl,39
- 0040172D ja short 1.00401733
- 0040172F jmp short 1.00401746
- 00401731 jmp short 1.00401746
- 00401733 cmp bl,41
- 00401736 jb short 1.00401741
- 00401738 cmp bl,5A
- 0040173B ja short 1.00401741
- 0040173D jmp short 1.00401746
- 0040173F jmp short 1.00401746
- 00401741 jmp 1.00401827
- // active Key的每一位只能是数字或大写字母
复制代码
- 00401746 mov al,byte ptr ds:[esi]
- 00401748 call 00401690
- //unl key的i位和active Key的i位作一运算,这个运算就是前面提到的int sub(int a,int b)
复制代码
- 00401752 mov dx,word ptr ds:[ebx] ;取出[ebx]中的值给dx,就相当于在talbleK中取值
- 00401755 xor dx,word ptr ds:[ebx+4] ;异或运算
- 00401759 add dx,word ptr ds:[ebx+8] ;加法运算
- 0040175D sub dx,word ptr ds:[ebx+B] ;减法运算
- 00401761 imul eax,edx ;乘法运算
- 00401764 xor edx,edx
- 00401766 push eax
- 00401767 call 1.004016F3 //对eax的值开方取整
-
复制代码
- 004017F1 div cx 上面的eax对cx求余
- 004017F4 or dx,dx
- 004017F7 pop ecx
- 0040180F jnz 00401602上面求余的结果必须为0
复制代码 大功告成
给一组:
Unlock key: ADBA3DEB9CDDA6071EC143A7C75DFEEF38CBDF4B631D20AF
User name: r668o6y8
Activation key:010011001010001001001100000001001200101011000100
********************************************
注:原程序和keygen的源码在附近里面
这个程序的用户名有限制是我后来才知道的,所以我的keygen有点问题,有时候点产生,不出来信息
多点几次就可以了 |
评分
-
参与人数 1 | 威望 +8 |
飘云币 +80 |
收起
理由
|
野猫III
| + 8 |
+ 80 |
PYG有你更精彩!希望兄弟发更多的好帖,供大 ... |
查看全部评分
|