-
-
[原创]看雪.京东 2018CTF 第十三题 NeuralCrackme Writeup
-
发表于: 2018-7-15 18:58 4194
-
此题暴破,SN是10位16进制数,如果对所有组合测试时间太长,不过,对输入的一些验证可以缩小范围,之后可瞬间出结果,分析如下:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rax
char *v4; // rdx
int v5; // ecx
unsigned int v6; // eax
__int64 v7; // rax
__int64 v9; // rax
__int64 v10; // rax
double v11; // xmm0_8
__int64 v12; // rax
BYTE snbin[5]; // [rsp+20h] [rbp-198h]
char Format[4]; // [rsp+30h] [rbp-188h]
char v15; // [rsp+34h] [rbp-184h]
double result; // [rsp+40h] [rbp-178h]
double d[4]; // [rsp+50h] [rbp-168h]
char v18[8]; // [rsp+70h] [rbp-148h]
__int64 v19; // [rsp+78h] [rbp-140h]
__int64 v20; // [rsp+80h] [rbp-138h]
__int64 v21; // [rsp+88h] [rbp-130h]
char buf; // [rsp+90h] [rbp-128h]
char v23; // [rsp+91h] [rbp-127h]
char v24; // [rsp+92h] [rbp-126h]
char v25; // [rsp+93h] [rbp-125h]
int v26; // [rsp+190h] [rbp-28h]
sub_401F00(*(_QWORD *)&argc, argv, envp);
snbin[4] = 0;
memset(&buf, 0, 0x100ui64);
v15 = 0;
d[0] = 0.0;
d[1] = 0.0;
d[2] = 0.0;
d[3] = 0.0;
result = 0.0;
v26 = 0;
*(_DWORD *)snbin = 0;
*(_DWORD *)Format = 0;
*(_QWORD *)v18 = 0i64;
v19 = 0i64;
v20 = 0i64;
v21 = 0i64;
sub_401790();
sub_401C50(252);
v3 = 0i64;
do
{
v18[v3] = (byte_408D00[v3] ^ 0x19) - v3;
++v3;
}
while ( v3 != 16 );
printf(v18);
Format[0] = byte_408D70 ^ 0x25;
Format[1] = (byte_408D71 ^ 0x25) - 1;
scanf(Format, &buf);
v4 = &buf;
do
{
v5 = *(_DWORD *)v4;
v4 += 4;
v6 = ~v5 & (v5 - 16843009) & 0x80808080;
}
while ( !v6 );
if ( !(~v5 & (v5 - 16843009) & 0x8080) )
v6 >>= 16;
if ( !(~v5 & (v5 - 16843009) & 0x8080) )
v4 += 2;
if ( &v4[-__CFADD__((_BYTE)v6, (_BYTE)v6) - 3] - &buf != 10 )// sn长度为10
{
v7 = 0i64;
do
{
v18[v7] = (byte_408D10[v7] ^ 0xF) - v7;
++v7;
}
while ( v7 != 16 );
goto LABEL_12;
}
if ( (unsigned int)sub_401CE0((__int64)&buf, (__int64)snbin, 10) != 5 )// 将输入的10位字符串转为5字节十六进制数,计为snbin
{
v9 = 0i64;
do
{
v18[v9] = (byte_408D20[v9] ^ 0x21) - v9;
++v9;
}
while ( v9 != 16 );
goto LABEL_12;
}
HIWORD(d[0]) = *(_WORD *)snbin; // 将snbin前二个字节装入第一个浮点数符号位,指数和高位小数
d[2] = d[0];
*(_WORD *)((char *)&d[1] + 5) = *(_WORD *)&snbin[2];// 将snbin最后三个字节装入第二个浮点数符号位,指数和高位小数
HIBYTE(d[1]) = snbin[4];
d[3] = d[1];
((void (__fastcall *)(double *, double *))unk_410000)(d, &result);// 核心计算函数,输入4个(其实是二个)64位浮点数,返回一个64位浮点数
Format[0] = byte_408D72 ^ 0x12;
Format[1] = (byte_408D73 ^ 0x12) - 1;
Format[2] = (byte_408D74 ^ 0x12) - 2;
sprintf(&buf, Format, result); // 分离返回的浮点数前三位值,及个位,小数点后一位和小数点后二位
if ( v23 != '.' )
{
v10 = 0i64;
do
{
v18[v10] = (byte_408D40[v10] ^ 0x3F) - v10;
++v10;
}
while ( v10 != 16 );
goto LABEL_12;
}
v11 = (double)(buf - '0') * (double)(buf - '0')// 计算前三位平方和
+ (double)(v24 - '0') * (double)(v24 - '0')
+ (double)(v25 - '0') * (double)(v25 - '0');
v11 = sqrt(v11);
if ( v11 <= 15.5 || snbin[2] & 0xF ) // 前三位平方和开平方要大于15.5且sn[5]要为0
{
v12 = 0i64;
}
else
{
v12 = 0i64;
if ( COERCE_DOUBLE(COERCE_UNSIGNED_INT64(d[2] + d[3] - result) & xmmword_409080) < 0.003 )// 由输入生成的二个浮点数之和与计算返回值之差的绝对值要小于0.003
{
do
{
v18[v12] = (byte_408D50[v12] ^ 0x47) - v12;
++v12;
}
while ( v12 != 16 );
goto LABEL_12;
}
}
do
{
v18[v12] = (byte_408D60[v12] ^ 0x37) - v12;
++v12;
}
while ( v12 != 16 );
LABEL_12:
printf(v18);
return 0;
}
关键计算函数:
__int64 __fastcall sub_4015E0(double d[4], double *a2)
{
double v2; // xmm7_8
__int64 *v3; // r13
double *v4; // r12
double v5; // xmm1_8
double *v7; // rbx
double v8; // xmm2_8
double v9; // xmm0_8
double v10; // xmm2_8
double v11; // xmm0_8
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
看原图
赞赏
雪币:
留言: