Kerio Connect中的License验证部份 分析
本帖最后由 Tee8088 于 2013-11-26 12:08 编辑分析完了,用的Open SSL的库函数,生成16个字节的MD5串用于签名的明文,License文件中signature段中256字节的签名密文串经转换成后成128字节的十六进制内存串,反向排列这个signature内存串做为签名密文,把exe文件中存着的128个密钥Key反向排列做为解码用的密钥KEY,这个签名密文的最后四字节应小于密钥KEY的后四字节,开始RSA1024签名解码,E值是10001,经签名解码后生成解码结果,解码结果存放在一个数组中,最后比较解码结果和MD5签明明文是否相等,相等就是正式,不相等就成了试用。下面是IDA中F5出来的
signed int __thiscall Check_License(void *this, int a2)
{
void *v2; // esp@1
int v3; // esi@1
void *v4; // ebx@1
bool v5; // cf@1
void *v7; // eax@11
bool v8; // zf@20
int v9; // esi@22
char v10; // bl@24
void *v11; // eax@42
char *v12; // edx@45
char *v13; // edi@51
const char *v14; // esi@53
int v15; // eax@60
unsigned int v16; // @1
int (__thiscall **v17)(void *, char); // @38
int v18; // @39
int (__thiscall **v19)(void *, char); // @106
int v20; // @107
int (__thiscall **v21)(void *, char); // @14
int v22; // @15
int (__thiscall **v23)(void *, char); // @108
int v24; // @109
int v25; // @1
char v26; // @6
int (__thiscall **v27)(void *, char); // @1
char v28; // @1
char v29; // @1
char *v30; // @1
char *v31; // @1
int v32; // @1
int v33; // @1
char v34; // @1
int v35; // @1
char v36; // @1
char v37; // @1
char v38; // @11
char v39; // @33
char v40; // @18
char *Dst; // @35
unsigned int v42; // @51
void *Src; // @29
int v44; // @29
unsigned int v45; // @29
void *v46; // @5
int v47; // @5
unsigned int v48; // @5
void *Str; // @24
int v50; // @24
unsigned int v51; // @24
unsigned int v52; // @1
unsigned int *v53; // @1
int v54; // @1
int v55; // @1
v2 = alloca(9204);
v52 = (unsigned int)&v55 ^ __security_cookie;
v16 = (unsigned int)&v55 ^ __security_cookie;
v53 = &v16;
v3 = a2;
v4 = this;
v30 = &v28;
v25 = (int)this;
v31 = &v29;
v32 = 0;
v33 = 4096;
v34 = 0;
v54 = 0;
v27 = &off_1679F04;
sub_AA93F0(&v37);
v35 = -1;
v36 = 0;
v5 = *(_DWORD *)(a2 + 20) < 0x10u;
v54 = 1;
if ( !v5 )
v3 = *(_DWORD *)a2;
if ( !sub_AA9D10((LPCSTR)v3, "rb") )
{
v54 = -1;
sub_AA9A90(&v27);
return 2;
}
sub_AA21D0(&v27);
v48 = 15;
v47 = 0;
LOBYTE(v46) = 0;
LOBYTE(v54) = 3;
sub_AA2090(v16);
if ( (unsigned __int8)sub_47C4B0((int)&v46, "--LICENSE--") )// 扫描读行比较字串
{
v26 = 0;
}
else
{
if ( !(unsigned __int8)sub_47C4B0((int)&v46, "--PRODUCT-LICENSE--") )// 扫描读行比较字串
{
std::exception::exception(&v23);
v23 = &off_1724EE0;
v24 = 2;
CxxThrowException();
}
v26 = 1;
}
sub_AA57D0(0, 1);
LOBYTE(v54) = 4;
while ( 1 )
{
sub_AA2090(v16);
if ( (unsigned __int8)sub_47C4B0((int)&v46, "--SIGNATURE--") )// 扫描读行比较字串,如果是SIGNATURE这行就跳出循环
break;
v51 = 15;
v50 = 0;
LOBYTE(Str) = 0;
sub_401560(&Str, (int)&v46, 0, 0xFFFFFFFFu);
LOBYTE(v54) = 5;
sub_429BA0((int)&Str, 1u, 0);
sub_407CB0(&v39, &Str);
LOBYTE(v54) = 4;
if ( v51 >= 0x10 )
operator delete(Str);
sub_AA2370(&Dst, (int)&v46);
v45 = 15;
v44 = 0;
LOBYTE(Src) = 0;
LOBYTE(v54) = 7;
if ( (unsigned __int8)sub_47C4B0((int)&v46, "Feature-Begin") )
{
sub_401560(&Src, (int)&Dst, 0, 0xFFFFFFFFu);
while ( 1 )
{
sub_AA2090(v16);
if ( (unsigned __int8)sub_47C4B0((int)&v46, "--SIGNATURE--") )
{
std::exception::exception(&v17);
v17 = &off_1724EE0;
v18 = 2;
CxxThrowException();
}
v51 = 15;
v50 = 0;
LOBYTE(Str) = 0;
sub_401560(&Str, (int)&v46, 0, 0xFFFFFFFFu);
LOBYTE(v54) = 8;
sub_429BA0((int)&Str, 1u, 0);
sub_407CB0(&v39, &Str);
LOBYTE(v54) = 7;
if ( v51 >= 0x10 )
operator delete(Str);
v11 = sub_AA2370(&Str, (int)&v46);
LOBYTE(v54) = 9;
sub_402C50((void **)&Dst, (void **)v11);
LOBYTE(v54) = 7;
if ( v51 >= 0x10 )
operator delete(Str);
if ( (unsigned __int8)sub_47C4B0((int)&v46, "Feature-End") )
break;
v12 = (char *)Src;
if ( v45 < 0x10 )
v12 = (char *)&Src;
v51 = 15;
v50 = 0;
LOBYTE(Str) = 0;
sub_401860((int)&Str, v12, strlen(v12));
LOBYTE(v54) = 10;
sub_AA3040((int)((char *)v4 + 476), (int)&Str, (int)&v46, (int)&Dst);
LOBYTE(v54) = 7;
if ( v51 >= 0x10 )
operator delete(Str);
}
}
v51 = 15;
v50 = 0;
LOBYTE(Str) = 0;
sub_401860((int)&Str, "Main", 4u);
LOBYTE(v54) = 11;
sub_AA3040((int)((char *)v4 + 476), (int)&Str, (int)&v46, (int)&Dst);
LOBYTE(v54) = 7;
if ( v51 >= 0x10 )
operator delete(Str);
v13 = Dst;
if ( v42 < 0x10 )
v13 = (char *)&Dst;
v14 = (const char *)v46;
if ( v48 < 0x10 )
v14 = (const char *)&v46;
if ( !v14 || !v13 )
{
std::exception::exception(&v19);
v19 = &off_1724EE0;
v20 = 2;
CxxThrowException();
}
if ( !strcmp(v14, "Product") )
{
sub_401960((int)((char *)v4 + 8), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "Product-ID") )
{
v15 = atoi(v13);
sub_AA0040(v15);
goto LABEL_102;
}
if ( !strcmp(v14, "Version") )
{
sub_401960((int)((char *)v4 + 40), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "Edition") )
{
sub_401960((int)((char *)v4 + 68), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "Min-Version") )
{
sub_401960((int)((char *)v4 + 124), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "OS") )
{
sub_401960((int)((char *)v4 + 96), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "Base-ID") )
{
sub_401960((int)((char *)v4 + 152), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "Company") )
{
sub_401960((int)((char *)v4 + 208), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "Person") )
{
sub_401960((int)((char *)v4 + 180), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "E-Mail") )
{
sub_401960((int)((char *)v4 + 236), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "Host-ID") )
{
sub_401960((int)((char *)v4 + 264), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "Features") )
{
sub_401960((int)((char *)v4 + 292), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "License-Expires") )
{
sub_401990((int)&Str, v13);
LOBYTE(v54) = 12;
sub_AA1ED0((int)((char *)v4 + 328), (int)&Str);
LABEL_101:
sub_11DF8E0(&Str);
goto LABEL_102;
}
if ( !strcmp(v14, "Subscription-Expires") )
{
sub_401990((int)&Str, v13);
LOBYTE(v54) = 13;
sub_AA1ED0((int)((char *)v4 + 336), (int)&Str);
goto LABEL_101;
}
if ( !strcmp(v14, "Antivirus-Expires") )
{
sub_401990((int)&Str, v13);
LOBYTE(v54) = 14;
sub_AA1ED0((int)((char *)v4 + 344), (int)&Str);
goto LABEL_101;
}
if ( !strcmp(v14, "Warranty-Expires") )
{
sub_401990((int)&Str, v13);
LOBYTE(v54) = 15;
sub_AA1ED0((int)((char *)v4 + 352), (int)&Str);
goto LABEL_101;
}
if ( !strcmp(v14, "License-Type") )
{
sub_401990((int)&Str, v13);
LOBYTE(v54) = 16;
sub_AA1C40(&Str);
goto LABEL_101;
}
if ( !strcmp(v14, "License-Version") )
{
sub_401960((int)((char *)v4 + 360), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "License-Info") )
{
sub_401960((int)((char *)v4 + 388), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "Comment") )
{
sub_401960((int)((char *)v4 + 416), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "Format-Version") )
{
sub_401960((int)((char *)v4 + 448), v13);
goto LABEL_102;
}
if ( !strcmp(v14, "Users") )
{
sub_401990((int)&Str, v13);
LOBYTE(v54) = 17;
sub_AA1F50((int)((char *)v4 + 320), (char *)&Str);
goto LABEL_101;
}
LABEL_102:
if ( v45 >= 0x10 )
operator delete(Src);
v45 = 15;
v44 = 0;
LOBYTE(Src) = 0;
LOBYTE(v54) = 4;
if ( v42 >= 0x10 )
operator delete(Dst);
}
Check_signature(v4, (int)&v38, (int)&v27); // 验证签名
sub_AA2090(v16);
v7 = "--PRODUCT-END--";
if ( !v26 )
v7 = "--END--";
if ( !(unsigned __int8)sub_47C4B0((int)&v46, v7) )// 是否已经到最后行的标志串
{
std::exception::exception(&v21);
v21 = &off_1724EE0;
v22 = 2;
CxxThrowException();
}
if ( !v26 )
sub_AA1C40((char *)v4 + 68);
sub_AA9730(&v27);
LOBYTE(v54) = 3;
sub_AA54C0(&v40);
std::basic_ios<char_std::char_traits<char>>::_basic_ios<char_std::char_traits<char>>(&v40);
if ( v48 >= 0x10 )
operator delete(v46);
v8 = *((_DWORD *)v4 + 77) == 0;
v54 = 1;
if ( v8 )
sub_AA1440((char *)v4 + 292);
v9 = (int)((char *)v4 + 344);
if ( !*((_DWORD *)v4 + 86) && !*((_DWORD *)v4 + 87) )
{
v51 = 15;
v50 = 0;
LOBYTE(Str) = 0;
sub_401860((int)&Str, "Sophos", 6u);
LOBYTE(v54) = 19;
v10 = sub_AA1B60(v25 + 476, (int)&Str);
LOBYTE(v54) = 1;
if ( v51 >= 0x10 )
operator delete(Str);
if ( v10 )
{
v51 = 15;
v50 = 0;
LOBYTE(Str) = 0;
sub_401860((int)&Str, "Sophos", 6u);
LOBYTE(v54) = 20;
sub_AA1CD0((int)&Str, v9);
LOBYTE(v54) = 1;
if ( v51 >= 0x10 )
operator delete(Str);
}
else
{
v45 = 15;
v44 = 0;
LOBYTE(Src) = 0;
sub_401860((int)&Src, "McAfee", 6u); //竟然有Mcafee,难道还有自带防毒是麦咖啡的版本?
LOBYTE(v54) = 21;
sub_AA1CD0((int)&Src, v9);
LOBYTE(v54) = 1;
if ( v45 >= 0x10 )
operator delete(Src);
v45 = 15;
v44 = 0;
LOBYTE(Src) = 0;
}
}
sub_AA2000(v25);
v54 = -1;
sub_AA9A90(&v27);
return 0;
}
本帖最后由 Tee8088 于 2013-11-20 13:13 编辑
void __thiscall Check_signature(void *this, int a2, int a3)
{
int (__stdcall *v3)(_DWORD, _DWORD, _DWORD); // eax@1
void **v4; // eax@1
const void *v5; // eax@3
signed int v6; // edi@5
int v7; // eax@6
int *v8; // eax@7
int v9; // ebx@7
char v10; // bl@12
char *v11; // eax@14
int v12; // ecx@14
int v13; // eax@15
int *v14; // eax@16
int v15; // ebx@16
int v16; // eax@22
int v17; // eax@23
int v18; // ST14_4@24
signed int v19; // eax@29
int v20; // ecx@29
void *v21; // @1
int v22; // @24
void *Src; // @1
size_t Size; // @1
unsigned int v25; // @1
void *v26; // @1
int Dst; // @5
unsigned int v28; // @1
int v29; // @18
int v30; // @24
int SIGNATURE; // @5
unsigned int v32; // @1
int v33; // @1
int v34; // @1
v32 = (unsigned int)&v34 ^ __security_cookie;
v21 = this;
v25 = 15;
Size = 0;
LOBYTE(Src) = 0;
v3 = (int (__stdcall *)(_DWORD, _DWORD, _DWORD))**(_DWORD **)a2;// 获取签名明文call,调用了Open SSL库
v33 = 0;
v4 = (void **)v3(&v26, 0, (unsigned int)&v34 ^ __security_cookie);// v4是16个字节的签名明文
LOBYTE(v33) = 1;
sub_402C50(&Src, v4);
LOBYTE(v33) = 0;
if ( v28 >= 0x10 )
operator delete(v26);
v5 = Src;
if ( v25 < 0x10 )
v5 = &Src;
memcpy(Dst, v5, Size); // Dst是一个数组,下标为4
memset(&SIGNATURE, 0, 0x80u); // 取v31为128个空字节
v6 = 0;
while ( 1 ) // 转换sig签名为16进制字节放到128字节里
{
v7 = *(_DWORD *)(a3 + 8204);
if ( v7 <= 0 )
{
v9 = sub_AA8D40(a3);
}
else
{
*(_DWORD *)(a3 + 8204) = v7 - 1;
v8 = *(int **)(a3 + 8196);
v9 = *(_BYTE *)v8;
*(_DWORD *)(a3 + 8196) = (char *)v8 + 1;
}
if ( v9 == -1 )
{
std::exception::exception(Dst);
Dst = (int)&off_1724EE0;
v29 = 2;
CxxThrowException();
}
if ( !isspace((unsigned __int8)v9) )
{
v10 = v9 < 97 ? v9 - 48 : v9 - 87;
v11 = (char *)&SIGNATURE + v6 / 2;
v12 = v6++ % 2;
*v11 |= v10 << (v12 != 0 ? 0 : 4);
if ( v6 >= 256 )
break;
}
} // 上面while的功能:把sig转换成ASCII码
do
{
v13 = *(_DWORD *)(a3 + 8204);
if ( v13 <= 0 )
{
v15 = sub_AA8D40(a3);
}
else
{
*(_DWORD *)(a3 + 8204) = v13 - 1;
v14 = *(int **)(a3 + 8196);
v15 = *(_BYTE *)v14;
*(_DWORD *)(a3 + 8196) = (char *)v14 + 1;
}
if ( v15 == -1 )
{
std::exception::exception(Dst);
Dst = (int)&off_1724EE0;
v29 = 2;
CxxThrowException();
}
}
while ( isspace((unsigned __int8)v15) );
v16 = *(_DWORD *)(a3 + 8196);
if ( v16 != a3 + 4 )
{
v17 = v16 - 1;
++*(_DWORD *)(a3 + 8204);
*(_DWORD *)(a3 + 8196) = v17;
*(_BYTE *)v17 = v15;
}
v18 = *(_DWORD *)v21; // v18=1024
v22 = 128;
if ( sub_AA1340(v30, (int)&v22, (int)&SIGNATURE, 0x80u, v18) )// 签名解码算法 v30为解密后返回的明文,函数返回0表示解码成功,OD里跟进v18这个地址里,后面跟的就是128字节的公钥了,如果用自己生成的公钥,那就是替换这串128字节的东西了。
{
LABEL_25:
std::exception::exception(Dst);
Dst = (int)&off_1724EE0;
v29 = 3;
CxxThrowException();
}
v19 = 16;
v20 = 0;
do
{
if ( v30 != Dst ) // 签名解码出来后的串与原始明文比较
goto LABEL_25; //如果爆破签名检测,就直接复制原始明文的16字节去覆盖解码后的16字节
v19 -= 4;
++v20;
}
while ( (unsigned int)v19 >= 4 );
if ( v25 >= 0x10 )
operator delete(Src);
}
楼主真是高手!有没有办法替换密钥部分,生成自己的License,而不去爆破,这样的的话全平台破解都不是问题了,甚至于Kerio Control 也解决了 不知道Kerio的系列产品中是否都是用的这样的验证License的方式 我分析过代码,都是这种方式 newdiy 发表于 2013-11-20 12:42 static/image/common/back.gif
我分析过代码,都是这种方式
那你看看这段是个啥个算法来着??知道了这个算法的名称,就可以替换了,这东西就是把签名密文解码成明文的函数。
00AA10D0 55 push ebp
00AA10D1 8BEC mov ebp,esp
00AA10D3 81EC 1C020000 sub esp,21C
00AA10D9 A1 E05EAC01 mov eax,dword ptr ds:
00AA10DE 33C5 xor eax,ebp
00AA10E0 8945 FC mov dword ptr ss:,eax
00AA10E3 8B45 08 mov eax,dword ptr ss:
00AA10E6 53 push ebx
00AA10E7 8B5D 10 mov ebx,dword ptr ss:
00AA10EA 56 push esi
00AA10EB 8985 E8FDFFFF mov dword ptr ss:,eax
00AA10F1 8B45 0C mov eax,dword ptr ss:
00AA10F4 57 push edi
00AA10F5 33F6 xor esi,esi
00AA10F7 8BFA mov edi,edx
00AA10F9 898D E4FDFFFF mov dword ptr ss:,ecx
00AA10FF 48 dec eax
00AA1100 85C0 test eax,eax
00AA1102 78 29 js short mailserv.00AA112D
00AA1104 33D2 xor edx,edx
00AA1106 33C9 xor ecx,ecx
00AA1108 83F9 20 cmp ecx,20
00AA110B 73 11 jnb short mailserv.00AA111E
00AA110D 0FB61C38 movzx ebx,byte ptr ds:
00AA1111 D3E3 shl ebx,cl
00AA1113 83C1 08 add ecx,8
00AA1116 0BD3 or edx,ebx
00AA1118 48 dec eax
00AA1119 8B5D 10 mov ebx,dword ptr ss:
00AA111C ^ 79 EA jns short mailserv.00AA1108
00AA111E 8994B5 70FEFFFF mov dword ptr ss:,edx
00AA1125 46 inc esi
00AA1126 83FE 21 cmp esi,21
00AA1129 ^ 72 D5 jb short mailserv.00AA1100
00AA112B EB 17 jmp short mailserv.00AA1144
00AA112D 83FE 21 cmp esi,21
00AA1130 73 12 jnb short mailserv.00AA1144
00AA1132 B9 21000000 mov ecx,21
00AA1137 2BCE sub ecx,esi
00AA1139 8DBCB5 70FEFFFF lea edi,dword ptr ss:
00AA1140 33C0 xor eax,eax
00AA1142 F3:AB rep stosd
00AA1144 33F6 xor esi,esi
00AA1146 B8 7F000000 mov eax,7F
00AA114B EB 03 jmp short mailserv.00AA1150
00AA114D 8D49 00 lea ecx,dword ptr ds:
00AA1150 85C0 test eax,eax
00AA1152 78 27 js short mailserv.00AA117B
00AA1154 33D2 xor edx,edx
00AA1156 33C9 xor ecx,ecx
00AA1158 83F9 20 cmp ecx,20
00AA115B 73 0F jnb short mailserv.00AA116C
00AA115D 0FB67C18 04 movzx edi,byte ptr ds:
00AA1162 D3E7 shl edi,cl
00AA1164 83C1 08 add ecx,8
00AA1167 0BD7 or edx,edi
00AA1169 48 dec eax
00AA116A ^ 79 EC jns short mailserv.00AA1158
00AA116C 8994B5 78FFFFFF mov dword ptr ss:,edx
00AA1173 46 inc esi
00AA1174 83FE 21 cmp esi,21
00AA1177 ^ 72 D7 jb short mailserv.00AA1150
00AA1179 EB 17 jmp short mailserv.00AA1192
00AA117B 83FE 21 cmp esi,21
00AA117E 73 12 jnb short mailserv.00AA1192
00AA1180 B9 21000000 mov ecx,21
00AA1185 2BCE sub ecx,esi
00AA1187 8DBCB5 78FFFFFF lea edi,dword ptr ss:
00AA118E 33C0 xor eax,eax
00AA1190 F3:AB rep stosd
00AA1192 33F6 xor esi,esi
00AA1194 B8 7F000000 mov eax,7F
00AA1199 8DA424 00000000 lea esp,dword ptr ss:
00AA11A0 85C0 test eax,eax
00AA11A2 78 2A js short mailserv.00AA11CE
00AA11A4 33D2 xor edx,edx
00AA11A6 33C9 xor ecx,ecx
00AA11A8 83F9 20 cmp ecx,20
00AA11AB 73 12 jnb short mailserv.00AA11BF
00AA11AD 0FB6BC18 84000000 movzx edi,byte ptr ds:
00AA11B5 D3E7 shl edi,cl
00AA11B7 83C1 08 add ecx,8
00AA11BA 0BD7 or edx,edi
00AA11BC 48 dec eax
00AA11BD ^ 79 E9 jns short mailserv.00AA11A8
00AA11BF 8994B5 F4FEFFFF mov dword ptr ss:,edx
00AA11C6 46 inc esi
00AA11C7 83FE 21 cmp esi,21
00AA11CA ^ 72 D4 jb short mailserv.00AA11A0
00AA11CC EB 17 jmp short mailserv.00AA11E5
00AA11CE 83FE 21 cmp esi,21
00AA11D1 73 12 jnb short mailserv.00AA11E5
00AA11D3 B9 21000000 mov ecx,21
00AA11D8 2BCE sub ecx,esi
00AA11DA 8DBCB5 F4FEFFFF lea edi,dword ptr ss:
00AA11E1 33C0 xor eax,eax
00AA11E3 F3:AB rep stosd
00AA11E5 B9 20000000 mov ecx,20
00AA11EA 8D45 F0 lea eax,dword ptr ss:
00AA11ED 8D49 00 lea ecx,dword ptr ds:
00AA11F0 8378 08 00 cmp dword ptr ds:,0
00AA11F4 75 1B jnz short mailserv.00AA1211
00AA11F6 8378 04 00 cmp dword ptr ds:,0
00AA11FA 75 0F jnz short mailserv.00AA120B
00AA11FC 8338 00 cmp dword ptr ds:,0
00AA11FF 75 0D jnz short mailserv.00AA120E
00AA1201 83E8 0C sub eax,0C
00AA1204 83E9 03 sub ecx,3
00AA1207 ^ 79 E7 jns short mailserv.00AA11F0
00AA1209 EB 06 jmp short mailserv.00AA1211
00AA120B 49 dec ecx
00AA120C EB 03 jmp short mailserv.00AA1211
00AA120E 83E9 02 sub ecx,2
00AA1211 8D79 01 lea edi,dword ptr ds:
00AA1214 B8 20000000 mov eax,20
00AA1219 8D8D 6CFFFFFF lea ecx,dword ptr ss:
00AA121F 90 nop
00AA1220 8379 08 00 cmp dword ptr ds:,0
00AA1224 75 1B jnz short mailserv.00AA1241
00AA1226 8379 04 00 cmp dword ptr ds:,0
00AA122A 75 0F jnz short mailserv.00AA123B
00AA122C 8339 00 cmp dword ptr ds:,0
00AA122F 75 0D jnz short mailserv.00AA123E
00AA1231 83E9 0C sub ecx,0C
00AA1234 83E8 03 sub eax,3
00AA1237 ^ 79 E7 jns short mailserv.00AA1220
00AA1239 EB 06 jmp short mailserv.00AA1241
00AA123B 48 dec eax
00AA123C EB 03 jmp short mailserv.00AA1241
00AA123E 83E8 02 sub eax,2
00AA1241 8D70 01 lea esi,dword ptr ds:
00AA1244 8D47 FF lea eax,dword ptr ds:
00AA1247 85C0 test eax,eax
00AA1249 78 1C js short mailserv.00AA1267
00AA124B EB 03 jmp short mailserv.00AA1250
00AA124D 8D49 00 lea ecx,dword ptr ds:
00AA1250 8B8C85 78FFFFFF mov ecx,dword ptr ss:
00AA1257 8B9485 70FEFFFF mov edx,dword ptr ss:
00AA125E 3BD1 cmp edx,ecx
00AA1260 77 05 ja short mailserv.00AA1267
00AA1262 72 19 jb short mailserv.00AA127D
00AA1264 48 dec eax
00AA1265 ^ 79 E9 jns short mailserv.00AA1250
00AA1267 5F pop edi
00AA1268 5E pop esi
00AA1269 B8 01040000 mov eax,401
00AA126E 5B pop ebx
00AA126F 8B4D FC mov ecx,dword ptr ss:
00AA1272 33CD xor ecx,ebp
00AA1274 E8 BF5C7A00 call mailserv.01246F38
00AA1279 8BE5 mov esp,ebp
00AA127B 5D pop ebp
00AA127C C3 retn
00AA127D 57 push edi
00AA127E 8D95 78FFFFFF lea edx,dword ptr ss:
00AA1284 52 push edx
00AA1285 56 push esi
00AA1286 8D85 F4FEFFFF lea eax,dword ptr ss:
00AA128C 50 push eax
00AA128D 8D8D 70FEFFFF lea ecx,dword ptr ss:
00AA1293 51 push ecx
00AA1294 8D95 ECFDFFFF lea edx,dword ptr ss:
00AA129A 52 push edx
00AA129B E8 00F8FFFF call mailserv.00AA0AA0
00AA12A0 8B03 mov eax,dword ptr ds:
00AA12A2 8B8D E4FDFFFF mov ecx,dword ptr ss:
00AA12A8 83C0 07 add eax,7
00AA12AB 57 push edi
00AA12AC C1E8 03 shr eax,3
00AA12AF 8D95 ECFDFFFF lea edx,dword ptr ss:
00AA12B5 52 push edx
00AA12B6 50 push eax
00AA12B7 8901 mov dword ptr ds:,eax
00AA12B9 8B85 E8FDFFFF mov eax,dword ptr ss:
00AA12BF 50 push eax
00AA12C0 E8 9BEEFFFF call mailserv.00AA0160
00AA12C5 8B4D FC mov ecx,dword ptr ss:
00AA12C8 83C4 28 add esp,28
00AA12CB 5F pop edi
00AA12CC 5E pop esi
00AA12CD 33CD xor ecx,ebp
00AA12CF 33C0 xor eax,eax
00AA12D1 5B pop ebx
00AA12D2 E8 615C7A00 call mailserv.01246F38
00AA12D7 8BE5 mov esp,ebp
00AA12D9 5D pop ebp
00AA12DA C3 retn
如何得到16个字节的签名验证明文,在OD中载入8.2.1_win32的mailserver.exe,在这里下断得到。
00AA6180 55 push ebp
00AA6181 8BEC mov ebp,esp
00AA6183 51 push ecx
00AA6184 807D 0C 00 cmp byte ptr ss:,0
00AA6188 56 push esi
00AA6189 57 push edi
00AA618A 8BF1 mov esi,ecx
00AA618C C745 FC 00000000 mov dword ptr ss:,0
00AA6193 74 16 je short mailserv.00AA61AB
00AA6195 83BE A8000000 00 cmp dword ptr ds:,0
00AA619C 75 0D jnz short mailserv.00AA61AB
00AA619E 8B46 0C mov eax,dword ptr ds:
00AA61A1 8B50 0C mov edx,dword ptr ds:
00AA61A4 8D4E 0C lea ecx,dword ptr ds:
00AA61A7 6A FF push -1
00AA61A9 FFD2 call edx
00AA61AB 807E 60 00 cmp byte ptr ds:,0
00AA61AF 75 34 jnz short mailserv.00AA61E5
00AA61B1 8D4E 08 lea ecx,dword ptr ds:
00AA61B4 FF15 E8176701 call dword ptr ds:[<&MSVCP100.std::basic_ost>; MSVCP100.std::basic_ostream<wchar_t,std::char_traits<wchar_t> >::flush
00AA61BA 8D86 A8000000 lea eax,dword ptr ds: ; 666666666666666666666
00AA61C0 50 push eax ; 0
00AA61C1 8D4E 68 lea ecx,dword ptr ds:
00AA61C4 51 push ecx ; 用来存16个字节的结果
00AA61C5 8D56 48 lea edx,dword ptr ds:
00AA61C8 52 push edx
00AA61C9 E8 8CD57900 call <jmp.&KTLIBEAY100_1.0.1e.#267> ; EVP_DigestFinal
00AA61CE 83C4 0C add esp,0C
00AA61D1 85C0 test eax,eax
00AA61D3 75 0C jnz short mailserv.00AA61E1
00AA61D5 E8 06FEFFFF call mailserv.00AA5FE0
00AA61DA 8BC8 mov ecx,eax
00AA61DC E8 2F820100 call mailserv.00ABE410
00AA61E1 C646 60 01 mov byte ptr ds:,1
00AA61E5 8B86 A8000000 mov eax,dword ptr ds:
00AA61EB 8B7D 08 mov edi,dword ptr ss:
00AA61EE 50 push eax
00AA61EF 83C6 68 add esi,68
00AA61F2 C747 14 0F000000 mov dword ptr ds:,0F
00AA61F9 C747 10 00000000 mov dword ptr ds:,0
00AA6200 56 push esi
00AA6201 8BCF mov ecx,edi
00AA6203 C607 00 mov byte ptr ds:,0
00AA6206 E8 55B695FF call mailserv.00401860
00AA620B 8BC7 mov eax,edi
00AA620D 5F pop edi
00AA620E 5E pop esi
00AA620F 8BE5 mov esp,ebp
00AA6211 5D pop ebp
00AA6212 C2 0800 retn 8
这么强大,意思是说,从此你就可以无限破解了? 本帖最后由 Tee8088 于 2013-11-21 16:27 编辑
钉子 发表于 2013-11-21 11:46 static/image/common/back.gif
这么强大,意思是说,从此你就可以无限破解了?
只要验证license部份的代码没变动,那就是老套路了。
签名解码成明文的十六字节部份我分析不出来,看着有点复杂烦人,象是个自定义的算法,如果这个分析出来,又会拿Open ssl的函数来用,那就可以写一个通用的补丁和License生成工具了。
我现在是爆破那个签名的解码后明文比较部份来实现的。
早上捣鼓了一下,NND签名算法原来是RSA1024。
页:
[1]
2