运行分析
- 需要输入calc计算结果
PE分析
- upx壳,32位
- upx -d fty_crkme3.exe脱壳
- 重新查壳,发现是Delphi程序
静态分析&动态调试
- ida找到关键字符串,进入函数
int sub_444B30()
{
int v0; // edx
int i; // ebx
unsigned __int8 v2; // al
char *v3; // edx
int v4; // eax
int v5; // ebx
int v6; // ecx
int v7; // ecx
int v8; // ecx
int v9; // ecx
int v10; // ecx
int v11; // ecx
int v12; // esi
int v13; // eax
int v14; // edi
int v15; // eax
int v16; // edi
int v17; // eax
int v18; // edi
int v19; // eax
int v20; // edi
int v21; // eax
int v22; // edi
int v23; // eax
int v24; // edi
int v25; // eax
int v26; // ecx
int v27; // ecx
int v28; // ecx
int v29; // ecx
int v30; // ecx
int v31; // ecx
int v32; // ecx
int v33; // esi
int v34; // eax
int v35; // edi
int v36; // eax
int v37; // edi
int v38; // eax
int v39; // edi
int v40; // eax
int v41; // edi
int v42; // eax
int v43; // edi
int v44; // eax
int v45; // edi
int v46; // eax
int v47; // edi
int v48; // eax
int v49; // ecx
int v50; // ecx
int v51; // ecx
int v52; // ecx
int v53; // ecx
int v54; // ecx
int v55; // ecx
int v56; // ecx
int v57; // esi
int v58; // eax
int v59; // edi
int v60; // eax
int v61; // edi
int v62; // eax
int v63; // edi
int v64; // eax
int v65; // edi
int v66; // eax
int v67; // edi
int v68; // eax
int v69; // edi
int v70; // eax
int v71; // edi
int v72; // eax
int v73; // edi
int v74; // eax
unsigned int v76[2]; // [esp-Ch] [ebp-D0h] BYREF
int *v77; // [esp-4h] [ebp-C8h]
int v78; // [esp+Ch] [ebp-B8h] BYREF
int v79; // [esp+10h] [ebp-B4h] BYREF
int v80; // [esp+14h] [ebp-B0h] BYREF
int v81; // [esp+18h] [ebp-ACh] BYREF
int v82; // [esp+1Ch] [ebp-A8h] BYREF
int v83; // [esp+20h] [ebp-A4h] BYREF
int v84; // [esp+24h] [ebp-A0h] BYREF
int v85; // [esp+28h] [ebp-9Ch] BYREF
int v86; // [esp+2Ch] [ebp-98h] BYREF
unsigned __int8 v87[12]; // [esp+30h] [ebp-94h] BYREF
int v88; // [esp+3Ch] [ebp-88h] BYREF
int v89; // [esp+40h] [ebp-84h] BYREF
int v90; // [esp+44h] [ebp-80h] BYREF
int v91; // [esp+48h] [ebp-7Ch] BYREF
int v92; // [esp+4Ch] [ebp-78h] BYREF
int v93; // [esp+50h] [ebp-74h] BYREF
int v94; // [esp+54h] [ebp-70h] BYREF
int v95; // [esp+58h] [ebp-6Ch] BYREF
int v96; // [esp+5Ch] [ebp-68h] BYREF
unsigned __int8 v97[12]; // [esp+60h] [ebp-64h] BYREF
int v98; // [esp+6Ch] [ebp-58h] BYREF
int v99; // [esp+70h] [ebp-54h] BYREF
int v100; // [esp+74h] [ebp-50h] BYREF
int v101; // [esp+78h] [ebp-4Ch] BYREF
int v102; // [esp+7Ch] [ebp-48h] BYREF
int Serial_4; // [esp+80h] [ebp-44h] BYREF
int Serial_2; // [esp+84h] [ebp-40h] BYREF
int Serial_1; // [esp+88h] [ebp-3Ch] BYREF
unsigned __int8 v106[8]; // [esp+8Ch] [ebp-38h] BYREF
char v107[8]; // [esp+94h] [ebp-30h] BYREF
char v108[8]; // [esp+9Ch] [ebp-28h] BYREF
char v109[8]; // [esp+A4h] [ebp-20h] BYREF
char v110[4]; // [esp+ACh] [ebp-18h] BYREF
char v111; // [esp+B0h] [ebp-14h] BYREF
char v112; // [esp+B1h] [ebp-13h]
char v113[4]; // [esp+B4h] [ebp-10h] BYREF
char v114; // [esp+B8h] [ebp-Ch] BYREF
char v115; // [esp+B9h] [ebp-Bh]
int System__AnsiString; // [esp+BCh] [ebp-8h] BYREF
char *v117; // [esp+C0h] [ebp-4h]
int savedregs; // [esp+C4h] [ebp+0h] BYREF
v77 = &savedregs;
v76[1] = (unsigned int)&loc_445382;
v76[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)v76);
TControl::GetText(*(TControl **)(dword_447844 + 720));
if ( v117 )
{
for ( i = 1; i <= length((int)v117); ++i )
{
if ( v117[i - 1] != '-' ) // Serial的每一位是-或者数字[0-9]
{
v2 = v117[i - 1];
if ( v2 < '0' )
goto LABEL_23;
v3 = v117;
if ( v2 > '9' )
goto LABEL_23;
}
}
v4 = length((int)v117);
v5 = v4;
if ( v4 < 9 || v4 > 11 ) // Serial长度为9-11
goto LABEL_23;
if ( v4 != 9 ) // Serial为10-11时跳转
goto LABEL_28;
if ( v117[2] != '-' || v117[6] != '-' ) // Serial的第3位和第7为必须是-
goto LABEL_23;
v115 = *v117;
v114 = 1;
setstr(v113, &v114);
v112 = v117[1];
v111 = 1;
LOBYTE(v6) = 2;
System::__linkproc__ PStrNCat(v113, &v111, v6);
setstr(v110, v113);
v112 = v117[3];
v111 = 1;
LOBYTE(v7) = 3;
System::__linkproc__ PStrNCat(v110, &v111, v7);
setstr(v109, v110);
v112 = v117[4];
v111 = 1;
LOBYTE(v8) = 4;
System::__linkproc__ PStrNCat(v109, &v111, v8);
setstr(v108, v109);
v112 = v117[5];
v111 = 1;
LOBYTE(v9) = 5;
System::__linkproc__ PStrNCat(v108, &v111, v9);
setstr(v107, v108);
v112 = v117[7];
v111 = 1;
LOBYTE(v10) = 6;
System::__linkproc__ PStrNCat(v107, &v111, v10);
setstr((char *)v106, v107);
v112 = v117[8];
v111 = 1;
LOBYTE(v11) = 7;
System::__linkproc__ PStrNCat(v106, &v111, v11);// 上面一系列操作就是将输入的Serial去除-
copy(&System__AnsiString, v106);
v12 = Sysutils::StrToInt(System__AnsiString);// str转int,v12 = Serial去除'-'后的16进制数
v5 = 7;
first_byte((int)&Serial_1); // 取第一位的值
v13 = Sysutils::StrToInt(Serial_1);
v14 = pow_Serial_i__5(v13, 7); // v14 = Serial_2的7次方,以下是一样的
first_byte((int)&Serial_2); // 取第二位的值
v15 = Sysutils::StrToInt(Serial_2);
v16 = pow_Serial_i__5(v15, 7) + v14;
first_byte((int)&Serial_4); // 取第四位的值
v17 = Sysutils::StrToInt(Serial_4);
v18 = pow_Serial_i__5(v17, 7) + v16;
first_byte((int)&v102); // 取第五位的值
v19 = Sysutils::StrToInt(v102);
v20 = pow_Serial_i__5(v19, 7) + v18;
first_byte((int)&v101); // 取第六位的值
v21 = Sysutils::StrToInt(v101);
v22 = pow_Serial_i__5(v21, 7) + v20;
first_byte((int)&v100); // 取第八位的值
v23 = Sysutils::StrToInt(v100);
v24 = pow_Serial_i__5(v23, 7) + v22;
first_byte((int)&v99); // 取第九位的值
v25 = Sysutils::StrToInt(v99);
if ( v12 != pow_Serial_i__5(v25, 7) + v24 ) // 必须跳转
{
LABEL_28:
if ( v5 != 10 )
goto LABEL_19;
if ( v117[2] != 45 || v117[6] != 45 )
goto LABEL_23;
v115 = *v117;
v114 = 1;
setstr(v113, &v114);
v112 = v117[1];
v111 = 1;
LOBYTE(v26) = 2;
System::__linkproc__ PStrNCat(v113, &v111, v26);
setstr(v110, v113);
v112 = v117[3];
v111 = 1;
LOBYTE(v27) = 3;
System::__linkproc__ PStrNCat(v110, &v111, v27);
setstr(v109, v110);
v112 = v117[4];
v111 = 1;
LOBYTE(v28) = 4;
System::__linkproc__ PStrNCat(v109, &v111, v28);
setstr(v108, v109);
v112 = v117[5];
v111 = 1;
LOBYTE(v29) = 5;
System::__linkproc__ PStrNCat(v108, &v111, v29);
setstr(v107, v108);
v112 = v117[7];
v111 = 1;
LOBYTE(v30) = 6;
System::__linkproc__ PStrNCat(v107, &v111, v30);
setstr((char *)v106, v107);
v112 = v117[8];
v111 = 1;
LOBYTE(v31) = 7;
System::__linkproc__ PStrNCat(v106, &v111, v31);
setstr((char *)v97, v106);
v112 = v117[9];
v111 = 1;
LOBYTE(v32) = 8;
System::__linkproc__ PStrNCat(v97, &v111, v32);
copy(&v98, v97);
v33 = Sysutils::StrToInt(v98);
v5 = 8;
first_byte((int)&v96);
v34 = Sysutils::StrToInt(v96);
v35 = pow_Serial_i__5(v34, 8);
first_byte((int)&v95);
v36 = Sysutils::StrToInt(v95);
v37 = pow_Serial_i__5(v36, 8) + v35;
first_byte((int)&v94);
v38 = Sysutils::StrToInt(v94);
v39 = pow_Serial_i__5(v38, 8) + v37;
first_byte((int)&v93);
v40 = Sysutils::StrToInt(v93);
v41 = pow_Serial_i__5(v40, 8) + v39;
first_byte((int)&v92);
v42 = Sysutils::StrToInt(v92);
v43 = pow_Serial_i__5(v42, 8) + v41;
first_byte((int)&v91);
v44 = Sysutils::StrToInt(v91);
v45 = pow_Serial_i__5(v44, 8) + v43;
first_byte((int)&v90);
v46 = Sysutils::StrToInt(v90);
v47 = pow_Serial_i__5(v46, 8) + v45;
first_byte((int)&v89);
v48 = Sysutils::StrToInt(v89);
if ( v33 != pow_Serial_i__5(v48, 8) + v47 )
{
LABEL_19:
if ( v5 != 11 )
goto LABEL_23;
if ( v117[3] != 45 )
goto LABEL_23;
if ( v117[7] != 45 )
goto LABEL_23;
v115 = *v117;
v114 = 1;
setstr(v113, &v114);
v112 = v117[1];
v111 = 1;
LOBYTE(v49) = 2;
System::__linkproc__ PStrNCat(v113, &v111, v49);
setstr(v110, v113);
v112 = v117[2];
v111 = 1;
LOBYTE(v50) = 3;
System::__linkproc__ PStrNCat(v110, &v111, v50);
setstr(v109, v110);
v112 = v117[4];
v111 = 1;
LOBYTE(v51) = 4;
System::__linkproc__ PStrNCat(v109, &v111, v51);
setstr(v108, v109);
v112 = v117[5];
v111 = 1;
LOBYTE(v52) = 5;
System::__linkproc__ PStrNCat(v108, &v111, v52);
setstr(v107, v108);
v112 = v117[6];
v111 = 1;
LOBYTE(v53) = 6;
System::__linkproc__ PStrNCat(v107, &v111, v53);
setstr((char *)v106, v107);
v112 = v117[8];
v111 = 1;
LOBYTE(v54) = 7;
System::__linkproc__ PStrNCat(v106, &v111, v54);
setstr((char *)v97, v106);
v112 = v117[9];
v111 = 1;
LOBYTE(v55) = 8;
System::__linkproc__ PStrNCat(v97, &v111, v55);
setstr((char *)v87, v97);
v112 = v117[10];
v111 = 1;
LOBYTE(v56) = 9;
System::__linkproc__ PStrNCat(v87, &v111, v56);
copy(&v88, v87);
v57 = Sysutils::StrToInt(v88);
first_byte((int)&v86);
v58 = Sysutils::StrToInt(v86);
v59 = pow_Serial_i__5(v58, 9);
first_byte((int)&v85);
v60 = Sysutils::StrToInt(v85);
v61 = pow_Serial_i__5(v60, 9) + v59;
first_byte((int)&v84);
v62 = Sysutils::StrToInt(v84);
v63 = pow_Serial_i__5(v62, 9) + v61;
first_byte((int)&v83);
v64 = Sysutils::StrToInt(v83);
v65 = pow_Serial_i__5(v64, 9) + v63;
first_byte((int)&v82);
v66 = Sysutils::StrToInt(v82);
v67 = pow_Serial_i__5(v66, 9) + v65;
first_byte((int)&v81);
v68 = Sysutils::StrToInt(v81);
v69 = pow_Serial_i__5(v68, 9) + v67;
first_byte((int)&v80);
v70 = Sysutils::StrToInt(v80);
v71 = pow_Serial_i__5(v70, 9) + v69;
first_byte((int)&v79);
v72 = Sysutils::StrToInt(v79);
v73 = pow_Serial_i__5(v72, 9) + v71;
first_byte((int)&v78);
v74 = Sysutils::StrToInt(v78);
if ( v57 != pow_Serial_i__5(v74, 9) + v73 )
{
LABEL_23:
Dialogs::ShowMessage((Dialogs *)&str_Nope__Your_calc[1], (const int)v3);// 失败弹窗
goto LABEL_25;
}
}
}
Dialogs::ShowMessage((Dialogs *)&str_Good_boy__Now_f[1], (const int)v3);// 成功弹窗
goto LABEL_25;
}
Dialogs::ShowMessage((Dialogs *)&str_Hey__loggerhead[1], v0);// 提示未输入弹窗
LABEL_25:
__writefsdword(0, v76[0]);
v77 = (int *)&loc_445389;
unknown_libname_29(&v78, 9);
unknown_libname_29(&v88, 9);
unknown_libname_29(&v98, 8);
return unknown_libname_29(&System__AnsiString, 2);
}
- 通过静态分析,想要跳转到成功,if ( v12 != pow_Serial_i__5(v25, 7) + v24 )处必须跳转
- Serial必须是9位,第3位和第7位是’-',其他是数字
- 通过动态调试发现,System__AnsiString的值是输入Serial去除-后的字符串
- v12为System__AnsiString转int
- 动调unknown_libname_32函数,发现是取System__AnsiString第n个值传入相应地址
int __fastcall sub_444B20(int result, int a2)
{
int v2; // ecx
bool v3; // cc
int v4; // edx
int v5; // edx
v2 = result;
v3 = a2 < 2;
v4 = a2 - 2;
if ( !v3 )
{
v5 = v4 + 1;
do
{
result *= v2;
--v5;
}
while ( v5 );
}
return result;
}
- 解析sub_444B20()函数,发现是对输入的数字进行7次方运算
- 通过以上分析,得到以下结论
- 一、Serial必须是9位,第3位和第7位是’-',其他是数字
- 二、v12为Serial去除’-'后的int值
- 三、Serial每个数字7次方相加的值,要等于v12
算法分析
Serial = ''
for Serial_byte1 in range(0, 10):
for Serial_byte2 in range(0, 10):
for Serial_byte4 in range(0, 10):
for Serial_byte5 in range(0, 10):
for Serial_byte6 in range(0, 10):
for Serial_byte8 in range(0, 10):
for Serial_byte9 in range(0, 10):
Serial = str(Serial_byte1) + str(Serial_byte2) + '-' + str(Serial_byte4) + str(Serial_byte5) + str(Serial_byte6) + '-' + str(Serial_byte8) + str(Serial_byte9)
System__AnsiString = Serial.replace('-','') # 去除-
v12 = hex(int(System__AnsiString))[2:] # 转16进制数
v12_cmp = 0
for i in range(len(System__AnsiString)):
v12_cmp += pow(int(System__AnsiString[i]),7) # 7次方
v12_cmp = hex(v12_cmp)[2:]
if v12 == v12_cmp:
print(Serial)
- 运行算法脚本,发现有多个解,一一验证均成功