一个kegenMe的简要分析与kegen
一:去掉烦人的音乐这个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位有关
00401359push eax ; eax为用户名的第一位,即name
0040135Axor eax,dword ptr ds: ; dword ptr ds: 是根据edx的值到一张固定的表table1中取取值,把值取出来后eax异或
00401361push eax
00401362and eax,0FFFF ;取出eax的后16位
00401367mov ebx,eax
00401369pop eax
0040136Aand eax,FFFF0000 ;取出eax的前16位
0040136Fimul eax,ebx ;eax的前16位与后16相乘
00401372xor eax,ebx ;上面相乘的结果和eax的后16位相加
00401374mov dword ptr ds:,eax ; 把上面的结果放入一张空表table2中(table2为一个二维表)
00401376add edi,4
00401379add edx,4
0040137Cpop eax
0040137Dloopd short 1.00401359 ;根据ecx来判断循环是否要继续(共循环6次)
00401380 push edi
00401381 call 0040152B ;这是一个算法call
进入这个call后来到:
0040153Fmov al,byte ptr ds: 把表table2中的数据取出来(00401374处存入的数据)
00401541cmp al,0
00401543je short 1.0040155D 判断al是否为0,如果为0就跳出循环 相当于一个break;
00401545div bx al的值对bx=2求余
00401548or dx,dx
0040154Bjnz short 1.0040155A 判断余数是否为0,如果为0就进行下一次循环 相当于continue
0040154Dinc ecx
0040154Einc esi
0040154Fpush ecx
00401550push dword ptr ss:
00401553call 1.00401562 ;这是一个算法call
00401558jmp short 1.0040153F
0040155Ainc esi
0040155Bjmp short 1.0040153F
进入call 00401562后来到
0040156Emov al,byte ptr ds: ;把表table2中的数据取出来给al
00401570xor al,10 ;al与16作异或
00401572mov byte ptr ds:,al ;把异或后的结果存入表table2中
00401574inc esi
00401575loopd short 1.0040156E ;循环
后面有5处是上面的重复
只不过eax不再是name,而分别是name,name,name,name,name
上面的table2表分别换成table2,table2,table2,table2,table2
004013DDpush eax
0040141Dpush eax
0040145Dpush eax
0040149Dpush eax
004014DDpush 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={0};
for(i=0;i<6;i++)
{
for(j=0;j<6;j++,k++)
{
temp=name^table1;
temp1=temp&0x0FFFF;
temp2=temp&0x0FFFF0000;
temp2=temp1*temp2;
temp2=temp2+temp1;
table2=temp2;
}
change1((char *)&table2);
}
其中:
void change1(char* table)
{
int j=1;
for(int i=0;i<24;i++)
{
if(table==0) break;
if(table%2!=0) continue;
j++;
change2(table,j);
}
}
等同于算法中的call 0040152B
其中:
void change2(char* table,int n)
{
for (int i=0;i<n;i++)
{
table^=0x10;
}
}
等同于call 00401562
00401595inc edx
00401596add esi,10
00401599add eax,dword ptr ds:
0040159Badd esi,4
0040159Eloopd short 1.00401599 ;
把上面的表table2(i=0,1,2,3,4,5)中的值分别累计求和
得到sum(i=0,1,2,3,4,5)
004015A0mov ecx,6
004015A5push eax
004015A6mov dword ptr ds:,eax
004015A8add ebx,4
004015ABxor eax,eax
004015ADcmp edx,5
004015B0jnz short 1.00401595
004015B2push 1.004068A9
004015B7push 1.0040686D
004015BCcall <jmp.&user32.wsprintfA>;
把 sum(i=0,1,2,3,4,5) 以16进制的形式格式输出
如:name为:f3k0eibj0对应的
sum=0X0B9A93087,sum=0X0AA5CEF63,sum=0X0EBCEC057
sum=0X,sum=0X0F7E943A7,sum=0X44BF762B,sum=0X0CD913F5F
结果就是:CD913F5F44BF762BF7E943A7EBCEC057AA5CEF63B9A93087
这个结果就是我们的unlock Key
00401269push 1.0040686D ;ASCII "CD913F5F44BF762BF7E943A7EBCEC057AA5CEF63B9A93087"
0040126Epush 1.004066B1 ;ASCII "CD913F5F44BF762BF7E943A7EBCEC057AA5CEF63B9A93087"
00401273call 1.00401634
00401278test eax,eax
0040127Aje short 1.004012CF
把你填入的unlock Key码和真码比较,看是否相等
**********************************************************************************
三 active Key的分析
004012B8push eax
004012B9push edi
004012BApush esi
004012BBcall 0040165F //一个算法call
004012C0add esi,28
004012C3add edi,28
004012C6add eax,2
004012C9loopd short 1.004012B8 //循环5次
进入上面的call后
00401675mov ax,word ptr ds: //取出上面table2中的值(i=0,1,2,3,4)
00401678mov bx,word ptr ds: //取出上面table2中的值
0040167Bcall 00401690 //一个算法call
00401680add word ptr ds:,ax//和ax相加,相加的结果放入表tablek中即
00401683add esi,2
00401686add edi,2
00401689loopd short 00401675 //循环24次
进入call 00401690
00401690cmp ax,bx
00401693jb short 1.00401697
00401695xchg ax,bx //看ax和bx哪个大,大的给bx,小的给ax
00401697sub bx,ax //大数减去小数
0040169Ajnz short 1.00401690
上面用c++实现就是:
for(i=0;i<5;i++)
{
gettable((WORD *)table2,(WORD *)table2,i);
if(i==3) scpy(table2,(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,table2);
}
tablek=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
004016C4xor eax,7D079EB1
004016C9mov edx,4ADFA541
004016CExor eax,edx
004016D0sub eax,3F4D1
004016D5imul eax,eax,33
004016D8loopd short 1.004016C4
004016DAcmp eax,CE337A1C
004016DFjnz 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:
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的每一位只能是数字或大写字母
00401746mov al,byte ptr ds:
00401748call 00401690
//unl key的i位和active Key的i位作一运算,这个运算就是前面提到的int sub(int a,int b)
00401752 mov dx,word ptr ds: ;取出中的值给dx,就相当于在talbleK中取值
00401755 xor dx,word ptr ds: ;异或运算
00401759 add dx,word ptr ds: ;加法运算
0040175D sub dx,word ptr ds: ;减法运算
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有点问题,有时候点产生,不出来信息
多点几次就可以了 “无字天书”高深/:L 看一下这个软件的声音 我OD一载入就异常啊!!!直接退出不知道怎么回事! 真够详细的,要慢慢看 写得很详细,学习了! 不懂,不懂还不懂啊 谢谢 :loveliness: :loveliness: 出来冒个泡先!/:good /:good /:good
页:
[1]