本帖最后由 missviola 于 2011-6-24 18:46 编辑
【文章标题】: A-one Video to Audio Converter V7.5.5注册算法分析
【文章作者】: cyane
【下载地址】: 网上搜索
【使用工具】: OD IDA PEID
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
首先用PEID分析下,没壳,方便了。
用OD看下,载入
很容易就可以发现关键地方,字符串搜索,断点什么的都可以。
这里不罗嗦了,直接入题
.text:004079D1 call 00406B40 ;关键CALL
.text:004079D6 add esp, 4
.text:004079D9 cmp eax, 1
.text:004079DC jnz short loc_407A0F
.text:004079DE push 40h
.text:004079E0 push offset aRegisterSucces ; "register successful"
.text:004079E5 push offset aThankYouForReg ; " Thank you for registering "
.text:004079EA mov ecx, ebx
.text:004079EC call CWnd::MessageBoxA(char const *,char const *,uint)
.text:004079F1 mov edx, dword ptr Dest+28h
.text:004079F7 mov eax, dword_42C570
.text:004079FC push edx
.text:004079FD push eax
.text:004079FE mov dword_42C7F4, 1
.text:00407A08 push offset aSVS ; "%s V%s "
.text:00407A0D jmp short loc_407A3E
.text:00407A0F ; ---------------------------------------------------------------------------
.text:00407A0F
.text:00407A0F loc_407A0F: ; CODE XREF: sub_4078E0+FCj
.text:00407A0F push 10h
.text:00407A11 push offset aRegisterFailed ; "register failed"
.text:00407A16 push offset aRegistrationCo ; " Registration code is error "
.text:00407A1B mov ecx, ebx
.text:00407A1D call CWnd::MessageBoxA(char const *,char const *,uint)
跟入关键CALL
.text:00406B40 sub esp, 300h
......
.text:00406B5C cmp ecx, 30h ;注册码位数要求48位
.text:00406B5F jnz loc_406C4A
.text:00406B65 xor ebx, ebx
......
.text:00406BD0 push 10h ; Count
.text:00406BD2 lea eax, [esp+328h+tmp3]
.text:00406BD9 push esi ; Source
.text:00406BDA push eax ; Dest
.text:00406BDB call edi ; strncpy ;将48位注册码分成3部分A、B、C,这里省略了其他2个strcpy函数
.text:00406BDD lea ecx, [esp+330h+tmp1]
.text:00406BE4 push offset a5328f38b191399 ; "5328F38B19139991"
.text:00406BE9 push ecx
.text:00406BEA mov [esp+338h+var_1F0], bl
.text:00406BF1 mov [esp+338h+var_2F0], bl
.text:00406BF5 mov [esp+338h+var_F0], bl
.text:00406BFC call RSA_check ;分别将A、B、C与系统的硬件码进行RSA运算
......
.text:00406C26 add esp, 3Ch
.text:00406C29 cmp esi, ebx ;RSA(A,Hard_1)>0
.text:00406C2B jle short loc_406C4A
.text:00406C2D cmp edi, ebx ;RSA(B,Hard_2)>0 其实Hard1_1 与 Hard_2相等
.text:00406C2F jle short loc_406C4A
.text:00406C31 cmp eax, ebx ;RSA(C,Hard_3)>0
.text:00406C33 jle short loc_406C4A
.text:00406C35 add edi, esi
.text:00406C37 xor ecx, ecx
.text:00406C39 cmp edi, eax ;RSA(A,Hard_1)+RSA(B,Hard_2) == RSA(C,Hard_3)
.text:00406C3B pop edi
.text:00406C3C setz cl ;关键标志位
.text:00406C3F pop esi
.text:00406C40 mov eax, ecx
.text:00406C42 pop ebx
.text:00406C43 add esp, 300h
.text:00406C49 retn
伪C码:
if( RSA(A,Hard1)>0 && RSA(B,Hard2)>0 && RSA(C,Hard3)>0 )
{
if( RSA(A,Hard1) + RSA(B,Hard2) == RSA(C,Hard3) )
ShowMessage('successful');
}
为什么会认为会是RSA函数,IDA使用Miracl库即可识别,当然了高手们都是用脑识别的,更精确(我不是高手)。
这里只把伪C码写下吧,方便阅读。
v3 = mirvar(0);
v8 = mirvar(0);
v4 = mirvar(0);
v9 = mirvar(0);
Str = 0;
cinstr(v3, A/B/C); // 将大数字符转为大数
cinstr(v4, Hard1/Hard2/Hard3);
cinstr(v9, "10001");
if ( compare(v3, v4) == -1 ) // 比较2数大小,V3>V4 返回1 V3=V4 返回0 V3<V4 返回-1
{
powmod(v3, v9, v4, v8); // 模幂运算 V8=V3^V9 MOD V4
big_to_bytes(256, v8, &Str, FALSE); // 将V8转换成数组写入str
mirkill(v3);
mirkill(v8);
mirkill(v4);
mirkill(v9);
mirexit();
}
return atoi(&Str);
}
写的都是关键地方,不重要的统统忽略了,比较懒。
既然知道了软件的注册方式,那就可以写注册机了。
代码很烂,请凑合看吧,只要能算码就可以了。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include "miracl.h"
#include "mirdef.h"
int main()
{
char temp[256]={0};
char serial1[20]={0};
char c[20]={"1234567890ABCDEF"};
int i=0, l=0;
srand((int)time(0));
while(1)
{
for(i=0;i<16;i++)
serial1 = c[rand()%16];
miracl* mir=mirsys(0x64,0x0);
big m = mirvar(0);
big c = mirvar(0);
big n = mirvar(0);
big e = mirvar(0);
mir->IOBASE=0x10;
cinstr(m, serial1);
if(l<2)
cinstr(n, "5328F38B19139991");
else
cinstr(n, "78C3A965FD910221"
cinstr(e, "10001");
if(compare(m, n) == -1)
{
powmod(m, e, n, c);
big_to_bytes(256, c, temp, FALSE);
mir->IOBASE=60;
if(temp[0] == 0x32 && l == 0)
{
printf("%s",serial1);
l++;
}
else if(temp[0] == 0x32 && l == 1)
{
printf("%s", serial1);
l++;
}
else if(temp[0] == 0x34 && l == 2)
{
printf("%s", serial1);
l++;
}
mirkill(m);
mirkill(c);
mirkill(n);
mirkill(e);
mirexit();
}
if(l>=3)
break;
}
return TRUE;
}
好了,分析道这里就结束了,现提供一组可用的注册码吧,方便有和我一样懒得同志!
SN: 321FC6C451FECF4D32AF4A2C051052293456789012345678
这里给大家提供Miracl库,方便想要的人使用
miracl.zip
(1.51 MB, 下载次数: 54)
--------------------------------------------------------------------------------
【版权声明】: 本文原创于52pojie技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
|