好友
阅读权限10
听众
最后登录1970-1-1
|
200吾爱币
某嵌入设备的激活码验证函数 通过IDA得出的伪代码如下 对于C++跟算法注册第一次接触 还望各位大佬指点
signed int __fastcall checkValidatecode(char *a1, char *a2)
{
int v2; // r5
dltLog *v3; // r0
dltLog *v4; // r7
int v5; // r3
int v6; // r0
int v7; // r5
dltLog *v8; // r0
dltLog *v9; // r7
int v10; // r0
dltLog *v11; // r5
int v12; // r0
dltLog *v13; // r0
dltLog *v14; // r10
int v15; // r0
dltLog *v16; // r0
dltLog *v17; // r8
int v18; // r0
dltLog *v19; // r0
dltLog *v20; // r10
int v21; // r0
dltLog *v22; // r0
dltLog *v23; // r10
int v24; // r0
dltLog *v25; // r0
dltLog *v26; // r8
int v27; // r0
signed int v28; // r5
dltLog *v29; // r6
int v30; // r0
dltLog *v32; // r0
dltLog *v33; // r5
int v34; // r0
dltLog *v35; // r0
dltLog *v36; // r6
int v37; // r0
dltLog *v38; // r6
int v39; // r0
dltLog *v40; // r0
dltLog *v41; // r6
int v42; // r0
int v43; // r0
dltLog *v44; // r0
dltLog *v45; // r6
int v46; // r0
dltLog *v47; // r0
dltLog *v48; // r6
int v49; // r0
char v50; // [sp+10h] [bp-114h]
int v51; // [sp+20h] [bp-104h]
const char *v52; // [sp+24h] [bp-100h]
int *v53; // [sp+28h] [bp-FCh]
int v54; // [sp+2Ch] [bp-F8h]
char *v55; // [sp+34h] [bp-F0h]
char *v56; // [sp+3Ch] [bp-E8h]
dltLog *v57; // [sp+40h] [bp-E4h]
void *src; // [sp+44h] [bp-E0h]
char s[8]; // [sp+48h] [bp-DCh]
int v60; // [sp+50h] [bp-D4h]
dltLog *v61; // [sp+54h] [bp-D0h]
int v62; // [sp+5Ch] [bp-C8h]
int v63; // [sp+60h] [bp-C4h]
int v64; // [sp+68h] [bp-BCh]
int v65; // [sp+6Ch] [bp-B8h]
int v66; // [sp+C8h] [bp-5Ch]
int v67; // [sp+CCh] [bp-58h]
int v68; // [sp+D0h] [bp-54h]
int v69; // [sp+D4h] [bp-50h]
int v70; // [sp+D8h] [bp-4Ch]
int v71; // [sp+DCh] [bp-48h]
char v72; // [sp+E0h] [bp-44h]
int v73; // [sp+E4h] [bp-40h]
int v74; // [sp+E8h] [bp-3Ch]
int v75; // [sp+ECh] [bp-38h]
char s1; // [sp+F0h] [bp-34h]
int v77; // [sp+F8h] [bp-2Ch]
__int16 v78; // [sp+FCh] [bp-28h]
char v79; // [sp+FEh] [bp-26h]
v2 = 0;
src = a1;
v56 = a2;
v79 = 0;
v77 = 0;
v78 = 0;
memset(s, 0, 0x80u);
strcpy(&s1, "1234567");
v55 = &s1;
v73 = 156;
v75 = 310000;
v74 = 310000;
v3 = (dltLog *)GDBL_GetDataProductDate((int)&v73, (int)s);
v57 = v3;
do
{
v4 = (dltLog *)dltLog::getInstance(v3);
v53 = (int *)v2;
v51 = 3086;
v52 = "checkValidatecode";
v5 = syscall(224);
v6 = *(_DWORD *)&s[4 * v2];
v7 = v2 + 1;
v54 = v6;
v8 = (dltLog *)dltLog::logInfo(v4, "PERS", "%ld:[%d]<%s>:czDate[%d] = %c", v5, 3086, "checkValidatecode", v53, v6);
v9 = (dltLog *)dltLog::getInstance(v8);
v10 = syscall(224);
v53 = (int *)v7;
v51 = 3086;
v52 = "checkValidatecode";
v54 = *(_DWORD *)&s[4 * v7];
v2 = v7 + 1;
v3 = (dltLog *)dltLog::logInfo(v9, "PERS", "%ld:[%d]<%s>:czDate[%d] = %c", v10, 3086, "checkValidatecode", v53, v54);
}
while ( v2 != 32 );
HIBYTE(v78) = v65;
LOBYTE(v77) = v60;
HIBYTE(v77) = v63;
LOBYTE(v78) = v64;
BYTE2(v77) = v62;
BYTE1(v77) = (_BYTE)v61;
v11 = (dltLog *)dltLog::getInstance(v61);
v12 = syscall(224);
v13 = (dltLog *)dltLog::logInfo(v11, "PERS", "%ld:[%d]<%s>:szTime = %s", v12, 3095, "checkValidatecode", &v77);
v14 = (dltLog *)dltLog::getInstance(v13);
v15 = syscall(224);
v16 = (dltLog *)dltLog::logInfo(v14, "PERS", "%ld:[%d]<%s>:rt %d", v15, 3096, "checkValidatecode", v57);
v17 = (dltLog *)dltLog::getInstance(v16);
v18 = syscall(224);
v19 = (dltLog *)dltLog::logInfo(v17, "PERS", "%ld:[%d]<%s>:czDate %s", v18, 3097, "checkValidatecode", s);
v20 = (dltLog *)dltLog::getInstance(v19);
v21 = syscall(224);
v22 = (dltLog *)dltLog::logInfo(v20, "PERS", "%ld:[%d]<%s>:activationcode %s", v21, 3098, "checkValidatecode", src);
v66 = 0;
v67 = 0;
v68 = 0;
v69 = 0;
v70 = 0;
v71 = 0;
v72 = 0;
v23 = (dltLog *)dltLog::getInstance(v22);
v24 = syscall(224);
dltLog::logInfo(v23, "PERS", "%ld:[%d]<%s>:sizeof(tmpActivationCode) %d", v24, 3100, "checkValidatecode", 25);
v25 = (dltLog *)memcpy(&v66, src, 0x19u);
v26 = (dltLog *)dltLog::getInstance(v25);
v27 = syscall(224);
v51 = 3102;
v52 = "checkValidatecode";
v53 = &v66;
dltLog::logInfo(v26, "PERS", "%ld:[%d]<%s>:tmpActivationCode %s", v27, 3102, "checkValidatecode", &v66);
if ( !strcmp(&s1, (const char *)src) )
{
v28 = 3;
dword_2F1FAC = 1;
v29 = (dltLog *)dltLog::getInstance(0);
v30 = syscall(224);
dltLog::logWarn(v29, "PERS", (const char *)&unk_DC780, v30, 3141, "checkValidatecode");
}
else
{
memset(&v50, 0, 0x15u);
v32 = (dltLog *)scGetBrand(&v50, 20);
v33 = (dltLog *)dltLog::getInstance(v32);
v34 = syscall(224);
dltLog::logInfo(v33, "UDEF", "%ld:[%d]<%s>:brand:%s", v34, 3109, "checkValidatecode", &v50);
if ( !strcmp(&v50, "DS") )
v35 = (dltLog *)ValidateCodeCAPSA(src, &v77, v56);
else
v35 = (dltLog *)ValidateCode(src, &v77, v56);
v28 = (signed int)v35;
if ( v35 == (dltLog *)1 )
{
v43 = NaviConfigForMid::getIntance((NaviConfigForMid *)1);
v44 = (dltLog *)NaviConfigForMid::setParam(v43, 15, &v66, 1);
s_bDRDataStatus = 1;
v45 = (dltLog *)dltLog::getInstance(v44);
v46 = syscall(224);
v47 = (dltLog *)dltLog::logInfo(v45, "PERS", (const char *)&unk_DC70C, v46, 3124, "checkValidatecode");
v48 = (dltLog *)dltLog::getInstance(v47);
v49 = syscall(224);
dltLog::logInfo(v48, "PERS", (const char *)&unk_DC728, v49, 3125, "checkValidatecode", v56);
}
else if ( v35 == (dltLog *)2 )
{
v38 = (dltLog *)dltLog::getInstance((dltLog *)2);
v39 = syscall(224);
v40 = (dltLog *)dltLog::logInfo(v38, "PERS", (const char *)&unk_DC744, v39, 3129, "checkValidatecode");
v41 = (dltLog *)dltLog::getInstance(v40);
v42 = syscall(224);
dltLog::logInfo(v41, "PERS", (const char *)&unk_DC728, v42, 3130, "checkValidatecode", v56);
}
else
{
v36 = (dltLog *)dltLog::getInstance(v35);
v37 = syscall(224);
dltLog::logWarn(v36, "PERS", (const char *)&unk_DC764, v37, 3134, "checkValidatecode");
}
}
return v28;
} 已知:
1、v28为返回值;
2、其中151行部分如成功返回3;
3、也就是实际的算法应该是在161行开始;
4、166行对取到的数值进行判断,是否为指定的字符串DS,实际的设备不为DS,再去调用专属的ValidateCode函数
下面是ValidateCode函数中的具体算法:
signed int __fastcall ValidateCode(const char *a1, const char *a2, void *a3)
{
signed int v3; // r3
void *v5; // [sp-E0h] [bp-E0h]
const char *v6; // [sp-DCh] [bp-DCh]
char *v7; // [sp-D8h] [bp-D8h]
int v8; // [sp-D4h] [bp-D4h]
int v9; // [sp-D0h] [bp-D0h]
int v10; // [sp-CCh] [bp-CCh]
int v11; // [sp-C8h] [bp-C8h]
int v12; // [sp-C4h] [bp-C4h]
int v13; // [sp-C0h] [bp-C0h]
int v14; // [sp-BCh] [bp-BCh]
int v15; // [sp-B8h] [bp-B8h]
char v16; // [sp-B4h] [bp-B4h]
int v17; // [sp-B0h] [bp-B0h]
char v18; // [sp-A9h] [bp-A9h]
char v19; // [sp-A4h] [bp-A4h]
char v20; // [sp-A1h] [bp-A1h]
int v21; // [sp-A0h] [bp-A0h]
char v22; // [sp-88h] [bp-88h]
int v23; // [sp-84h] [bp-84h]
int v24; // [sp-68h] [bp-68h]
int v25; // [sp-4Ch] [bp-4Ch]
int v26; // [sp-30h] [bp-30h]
int v27; // [sp-2Ch] [bp-2Ch]
unsigned __int8 *v28; // [sp-28h] [bp-28h]
int v29; // [sp-24h] [bp-24h]
signed int v30; // [sp-20h] [bp-20h]
signed int l; // [sp-1Ch] [bp-1Ch]
signed int v32; // [sp-18h] [bp-18h]
signed int v33; // [sp-14h] [bp-14h]
signed int j; // [sp-10h] [bp-10h]
signed int i; // [sp-Ch] [bp-Ch]
signed int k; // [sp-8h] [bp-8h]
int v37; // [sp-4h] [bp-4h]
v7 = (char *)a1;
v6 = a2;
v5 = a3;
v30 = MEMORY[0x410A4](a1);
if ( v30 <= 23 )
return 0;
for ( i = 0; i <= 24; ++i )
{
*((_BYTE *)&v25 + i) = g_szUserCode;
*((_BYTE *)&v24 + i) = g_szDevCode;
}
sub_416EC(&v23, 0, 0x19u);
MEMORY[0x40A98](&v23, v7, 0x19u);
v8 = *(_DWORD *)"ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
v9 = *(_DWORD *)"EFGHJKLMNPQRSTUVWXYZ23456789";
v10 = *(_DWORD *)"JKLMNPQRSTUVWXYZ23456789";
v11 = *(_DWORD *)"NPQRSTUVWXYZ23456789";
v12 = *(_DWORD *)"STUVWXYZ23456789";
v13 = *(_DWORD *)"WXYZ23456789";
v14 = *(_DWORD *)"23456789";
v15 = *(_DWORD *)"6789";
v16 = MEMORY[0xFAEB8][32];
Base32_Unmap32((unsigned __int8 *)v7, 24, (unsigned __int8 *)&v8);
v29 = Base32_GetDecode32Length(24);
v28 = (unsigned __int8 *)MEMORY[0x3FF88](v29 + 1);
Base32_Decode32((unsigned __int8 *)v7, 24, v28);
v28[v29] = 0;
Decrypt(v28, 0x10u, 0, 0);
g_AN_reYear = v28[3];
g_AN_reMonth = v28[7];
g_AN_reDay = v28[12];
for ( j = 0; j <= 23; ++j )
*((_BYTE *)&v21 + j) = g_szUserCode[j] ^ g_szDevCode[j];
v22 = 0;
v33 = 0;
v32 = 0;
while ( v33 <= 14 )
{
if ( v33 > 4 )
{
if ( v32 == 5 )
v32 = 10;
*((_BYTE *)&v17 + v33) = *((_BYTE *)&v21 + v32) ^ *((_BYTE *)&v37 + v32 - 152);
}
else
{
*((_BYTE *)&v17 + v33) = *((_BYTE *)&v21 + v32) ^ *((_BYTE *)&v37 + v32 - 151) ^ *((_BYTE *)&v37 + v32 - 146);
}
++v33;
++v32;
}
v20 = 0;
AutoNavi_EnCode((unsigned int *)&v17, (const unsigned int *)&v21);
HIBYTE(v17) = g_AN_reYear;
v18 = g_AN_reMonth;
v19 = g_AN_reDay;
for ( k = 0; k <= 14; ++k )
{
if ( k != 3 && k != 7 && k != 12 )
*((_BYTE *)&v17 + k) ^= (unsigned __int8)(HIBYTE(v17) ^ v18) ^ v19;
}
for ( l = 0; ; ++l )
{
if ( l > 14 )
{
if ( v28 )
MEMORY[0x40660](v28);
ReTime(&v23);
sub_416EC(v5, 0, 9u);
MEMORY[0x40A98](v5, &g_szTimeStamp, 9u);
v27 = MEMORY[0x40810](v6);
v26 = 10000 * g_AN_reYear + 100 * g_AN_reMonth + g_AN_reDay;
if ( v27 <= v26 )
v3 = 1;
else
v3 = 2;
return v3;
}
if ( *((unsigned __int8 *)&v17 + l) != v28[l] )
break;
}
if ( v28 )
MEMORY[0x40660](v28);
return 0;
} 这里应该就是具体的算法了。
不知道有哪位大佬可以抽空讲解下过程或能搞个注册机
如果有相关的文章也请大佬赐教
https://cloud.189.cn/t/UjmeQrvaEF7v(访问码:g2di) |
免费评分
-
查看全部评分
|