标 题: AudioEditor2注册码算法分析
发信站: BBS 水木清华站 (Fri Nov 14 09:45:27 2003), 转信
闲来无事,帮人破解一个软件,AudioEditor2,是一个ActiveX控件,本身提供一个
注册方法Register(username, password),如果不注册或者注册码错误的话在某些
重要的操作前面会弹出一个对话框,拉过来,w32dasm之,再加上ollydbg,很容易
就找到了判断注册的函数,爆破非常easy.
后来想想反正没事儿做,就把它的算法弄一弄吧,运行ollydbg和w32dasm连跟踪带
猜,反编译出来如下的代码:
说明一下,代码中的tempxx对应汇编码中的[ebp-xx], tempxxyy代表一个__int64类
型,在汇编码中用[ebp-xx], [ebp-yy]两个dword表示,其中[ebp-xx]是高32位。
同样eaxedx表示一个64位整数使用eax,edx表示。
AudioEditor2下载地址:
http://www.nctsoft.com/download/NCTAudioEditor2/ver2-3/NCTAudioEditor2.exe
//CALC CODE FROM USERNAME
ADDR_1001AD8D:
TEMP4C = USERNAME;
TEMP24 = 0;
INT64 TEMP4044 = 1;
FOR ( TEMP24 = 0 ; TEMP24 < STRLEN(USERNAME);TEMP24 ++ )
{
INT64 EDXEAX = USERNAME[TEMP24];
TEMP4044 *= EDXEAX;
IF ( TEMP4044 > 0X16B13ED3 )
TEMP4044 MOD = 0X16B13ED3 ;
}
ADDR_1001AE1C:
INT64 TEMP2838 = TEMP4044 ;
TEMP34 = 0;
INT64 TEMP181C = 0;
TEMP4C = REGKEY;
TEMP24 = 11;
FOR (TEMP24 = 11; TEMP24 >= 0; TEMP24 -- )
{
EDX = REGKEY[TEMP24];
IF ( EDX > '9' )
EDX -= 7;
TEMP181C <<= 5;
TEMP181C += EDX - 0X30; //ASSERT(EDX - 0X30 < 32)
}
TEMP28 = TEMP181C >> 0X1E;
TEMP34 = TEMP181C & 0X3FFFFFFF;
ADDR_1001AF0D:
TEMP20 = 0;
TEMP5054 = 6D0D;
WHILE ( TEMP5040 > 0 )
{
TEMP20 ++ ;
TEMP5040 /= 2 ;
}
TEMP5C = MALLOC(TEMP20);
TEMP48 = TEMP5C;
TEMP60 = MALLOC(TEMP20 * 8);
TEMP2C = TEMP48;
TEMP24 = 0;
TEMP5054 = 6D0D;
FOR ( TEMP24 = 0; TEMP24 < TEMP20; TEMP24 ++)
{
IF ( TEMP5054 MOD 2 == 1 )
TEMP48[TEMP24] = 1 ;
ELSE
TEMP48[TEMP24] = 0 ;
}
TEMP2C[0] = TEMP28 MOD 0X16B13ED3 ;
FOR ( TEMP24 = 1; TEMP24 < TEMP20; TEMP24 ++ )
{
EAXEDI = TEMP2C[TEMP24 - 1];
TEMP2C[TEMP24] = ( EAXEDI ^ 2 ) MOD 0X16B13ED3 ;
}
ADDR_1001B077:
TEMP1410 = 0;
TEMP24 = 0;
FOR (TEMP24 = 0; TEMP24 < TEMP20; TEMP24 ++ )
{
IF (TEMP48[TEMP24] != 0)
{
IF (TEMP1410 == 0 )
TEMP1410 = 1;
TEMP1410 *= TEMP2C[TEMP24];
TEMP1410 MOD = 0X16B13ED3 ;
}
}
TEMP28 = TEMP1410 ;
ADDR_1001B0FE:
TEMP24 = 0 ;
TEMP5450 = 0X6D0D;
FOR ( TEMP24 = 0; TEMP24 < TEMP20; TEMP24 ++)
{
IF ( TEMP5054 MOD 2 == 1 )
TEMP48[TEMP24] = 1 ;
ELSE
TEMP48[TEMP24] = 0 ;
}
TEMP2C[0] = TEMP34 MOD 0X16B13ED3 ;
FOR ( TEMP24 = 1; TEMP24 < TEMP20; TEMP24 ++ )
{
EAXEDI = TEMP2C[TEMP24 - 1];
TEMP2C[TEMP24] = ( EAXEDI ^ 2 ) MOD 0X16B13ED3 ;
}
ADDR_100B1F4:
TEMP1410 = 0;
TEMP24 = 0;
FOR (TEMP24 = 0; TEMP24 < TEMP20; TEMP24 ++ )
{
IF (TEMP48[TEMP24] != 0)
{
IF (TEMP1410 == 0 )
TEMP1410 = 1;
TEMP1410 *= TEMP2C[TEMP24];
TEMP1410 MOD = 0X16B13ED3 ;
}
}
TEMP34 = TEMP1410 ;
ADDR_1001B27B:
IF ( TEMP28 == TEMP38 && TEMP34 = TEMP38 + 1 )
REG_OK:
ELSE
REG_FAIL:
//算法:
usercode = f(username);
key = g(regkey);
regcode_hi = (key_hi ^ 27917) mod 0x16b13ed3;
regcode_low = (key_low ^ 27917) mod 0x16b13ed3;
if ( regcode_hi == usercode + 1 && regcode_low == usercode )
register ok;
else
fail;
根据以上代码,可以看出作者的验证流程如下:
首先把username和regkey转换成两个数字,
对于username先变为大写字母,然后如果长度不足
12个字符则用A补满12个。然后采用模0x16b13ed3累乘得到一个32位的usercode;
对于regkey变换有些复杂,首先regkey是一个64比特数字的32进制表示法,字符
为0~9, A~F,根据这个字符串还原出64比特的数字,然后再经过一系列的乘法和取
模运算,最终得到一个regcode,从这里可以看出,作者的加密手段是标准的RSA,
可以求得幂指数为27917,然后把这个regcode分成两半,前一半应该等于usercode,
后一半应该等于usercode + 1;
原理搞明白了,开始写注册机吧,
根据密码学原理上的算法可以很容易的算出
27917 ^ -1 mod 0x16b13ed3 = 70579781
根据算法,我们可以知道
regcode_hi = ( usercode ^ 70579781 ) mod 0x16b13ed3 ;
合并regcode_hi, regcode_low,转化成32进制字符串表示,完毕.
发信站: BBS 水木清华站 (Fri Nov 14 09:45:27 2003), 转信
闲来无事,帮人破解一个软件,AudioEditor2,是一个ActiveX控件,本身提供一个
注册方法Register(username, password),如果不注册或者注册码错误的话在某些
重要的操作前面会弹出一个对话框,拉过来,w32dasm之,再加上ollydbg,很容易
就找到了判断注册的函数,爆破非常easy.
后来想想反正没事儿做,就把它的算法弄一弄吧,运行ollydbg和w32dasm连跟踪带
猜,反编译出来如下的代码:
说明一下,代码中的tempxx对应汇编码中的[ebp-xx], tempxxyy代表一个__int64类
型,在汇编码中用[ebp-xx], [ebp-yy]两个dword表示,其中[ebp-xx]是高32位。
同样eaxedx表示一个64位整数使用eax,edx表示。
AudioEditor2下载地址:
http://www.nctsoft.com/download/NCTAudioEditor2/ver2-3/NCTAudioEditor2.exe
//CALC CODE FROM USERNAME
ADDR_1001AD8D:
TEMP4C = USERNAME;
TEMP24 = 0;
INT64 TEMP4044 = 1;
FOR ( TEMP24 = 0 ; TEMP24 < STRLEN(USERNAME);TEMP24 ++ )
{
INT64 EDXEAX = USERNAME[TEMP24];
TEMP4044 *= EDXEAX;
IF ( TEMP4044 > 0X16B13ED3 )
TEMP4044 MOD = 0X16B13ED3 ;
}
ADDR_1001AE1C:
INT64 TEMP2838 = TEMP4044 ;
TEMP34 = 0;
INT64 TEMP181C = 0;
TEMP4C = REGKEY;
TEMP24 = 11;
FOR (TEMP24 = 11; TEMP24 >= 0; TEMP24 -- )
{
EDX = REGKEY[TEMP24];
IF ( EDX > '9' )
EDX -= 7;
TEMP181C <<= 5;
TEMP181C += EDX - 0X30; //ASSERT(EDX - 0X30 < 32)
}
TEMP28 = TEMP181C >> 0X1E;
TEMP34 = TEMP181C & 0X3FFFFFFF;
ADDR_1001AF0D:
TEMP20 = 0;
TEMP5054 = 6D0D;
WHILE ( TEMP5040 > 0 )
{
TEMP20 ++ ;
TEMP5040 /= 2 ;
}
TEMP5C = MALLOC(TEMP20);
TEMP48 = TEMP5C;
TEMP60 = MALLOC(TEMP20 * 8);
TEMP2C = TEMP48;
TEMP24 = 0;
TEMP5054 = 6D0D;
FOR ( TEMP24 = 0; TEMP24 < TEMP20; TEMP24 ++)
{
IF ( TEMP5054 MOD 2 == 1 )
TEMP48[TEMP24] = 1 ;
ELSE
TEMP48[TEMP24] = 0 ;
}
TEMP2C[0] = TEMP28 MOD 0X16B13ED3 ;
FOR ( TEMP24 = 1; TEMP24 < TEMP20; TEMP24 ++ )
{
EAXEDI = TEMP2C[TEMP24 - 1];
TEMP2C[TEMP24] = ( EAXEDI ^ 2 ) MOD 0X16B13ED3 ;
}
ADDR_1001B077:
TEMP1410 = 0;
TEMP24 = 0;
FOR (TEMP24 = 0; TEMP24 < TEMP20; TEMP24 ++ )
{
IF (TEMP48[TEMP24] != 0)
{
IF (TEMP1410 == 0 )
TEMP1410 = 1;
TEMP1410 *= TEMP2C[TEMP24];
TEMP1410 MOD = 0X16B13ED3 ;
}
}
TEMP28 = TEMP1410 ;
ADDR_1001B0FE:
TEMP24 = 0 ;
TEMP5450 = 0X6D0D;
FOR ( TEMP24 = 0; TEMP24 < TEMP20; TEMP24 ++)
{
IF ( TEMP5054 MOD 2 == 1 )
TEMP48[TEMP24] = 1 ;
ELSE
TEMP48[TEMP24] = 0 ;
}
TEMP2C[0] = TEMP34 MOD 0X16B13ED3 ;
FOR ( TEMP24 = 1; TEMP24 < TEMP20; TEMP24 ++ )
{
EAXEDI = TEMP2C[TEMP24 - 1];
TEMP2C[TEMP24] = ( EAXEDI ^ 2 ) MOD 0X16B13ED3 ;
}
ADDR_100B1F4:
TEMP1410 = 0;
TEMP24 = 0;
FOR (TEMP24 = 0; TEMP24 < TEMP20; TEMP24 ++ )
{
IF (TEMP48[TEMP24] != 0)
{
IF (TEMP1410 == 0 )
TEMP1410 = 1;
TEMP1410 *= TEMP2C[TEMP24];
TEMP1410 MOD = 0X16B13ED3 ;
}
}
TEMP34 = TEMP1410 ;
ADDR_1001B27B:
IF ( TEMP28 == TEMP38 && TEMP34 = TEMP38 + 1 )
REG_OK:
ELSE
REG_FAIL:
//算法:
usercode = f(username);
key = g(regkey);
regcode_hi = (key_hi ^ 27917) mod 0x16b13ed3;
regcode_low = (key_low ^ 27917) mod 0x16b13ed3;
if ( regcode_hi == usercode + 1 && regcode_low == usercode )
register ok;
else
fail;
根据以上代码,可以看出作者的验证流程如下:
首先把username和regkey转换成两个数字,
对于username先变为大写字母,然后如果长度不足
12个字符则用A补满12个。然后采用模0x16b13ed3累乘得到一个32位的usercode;
对于regkey变换有些复杂,首先regkey是一个64比特数字的32进制表示法,字符
为0~9, A~F,根据这个字符串还原出64比特的数字,然后再经过一系列的乘法和取
模运算,最终得到一个regcode,从这里可以看出,作者的加密手段是标准的RSA,
可以求得幂指数为27917,然后把这个regcode分成两半,前一半应该等于usercode,
后一半应该等于usercode + 1;
原理搞明白了,开始写注册机吧,
根据密码学原理上的算法可以很容易的算出
27917 ^ -1 mod 0x16b13ed3 = 70579781
根据算法,我们可以知道
regcode_hi = ( usercode ^ 70579781 ) mod 0x16b13ed3 ;
合并regcode_hi, regcode_low,转化成32进制字符串表示,完毕.
浙公网安备 33010602011771号