首页
社区
课程
招聘
[原创]看雪.京东 2018CTF 第十三题 NeuralCrackme Writeup
发表于: 2018-7-15 18:58 4194

[原创]看雪.京东 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期)

收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//