草庐IT

安洵杯——game(混淆控制流平坦化)

寻梦&之璐 2023-04-08 原文

文章目录

查壳

拖进ida

main函数

 printf("input your flag:", argv, envp);
  gets(&v8);
  v10 = general_inspection((int (*)[9])sudoku);
  v7 = -1804515313;
  while ( 1 )
  {
    while ( 1 )
    {
      while ( v7 == -2071121728 )
      {
        v4 = blank_num((int (*)[9])sudoku);
        v5 = mem_alloc(v4);
        trace(sudoku, v5, v4);
        check((int (*)[9])sudoku);
        check1(&v8);
        check3(&v8);
        v9 = 0;
        v7 = -303742386;
      }
      if ( v7 != -1804515313 )
        break;
      v3 = -2071121728;
      if ( v10 )
        v3 = 664169471;
      v7 = v3;
    }
    if ( v7 == -303742386 )
      break;
    if ( v7 == 664169471 )
    {
      printf("error");
      check((int (*)[9])sudoku);
      v9 = 0;
      v7 = -303742386;
    }
  }

分析

主函数中,需要分析的函数有general_inspection((int (*)[9])sudoku),blank_num((int (*)[9])sudoku)trace(sudoku, v5, v4);check((int (*)[9])sudoku);check1(&v8);check3(&v8);check3函数中还有个check2(a1)需要分析

general_inspection((int (*)[9])sudoku)


这里的v10一直是0,sudoku在前后也并非发生什么改变。。。忽略不计

blank_num((int (*)[9])sudoku)

代码

__int64 __fastcall blank_num(int (*a1)[9])
{
  signed int v1; // eax
  signed int v2; // eax
  signed int v3; // eax
  signed int v5; // [rsp+2Ch] [rbp-18h]
  unsigned int v6; // [rsp+30h] [rbp-14h]
  signed int v7; // [rsp+34h] [rbp-10h]
  signed int v8; // [rsp+38h] [rbp-Ch]

  v6 = 0;
  v8 = 0;
  v5 = 1046773218;
  while ( 1 )
  {
    while ( v5 == -1892951115 )
    {
      v7 = 0;
      v5 = -1048142948;
    }
    if ( v5 == -1585203536 )
      break;
    switch ( v5 )
    {
      case -1237447983:
        v5 = 1058605341;
        break;
      case -1048142948:
        v2 = -1237447983;
        if ( v7 < 9 )
          v2 = 1501457574;
        v5 = v2;
        break;
      case -1026222996:
        ++v7;
        v5 = -1048142948;
        break;
      case -516195663:
        ++v6;
        v5 = 710936108;
        break;
      case 710936108:
        v5 = -1026222996;
        break;
      case 1046773218:
        v1 = -1585203536;
        if ( v8 < 9 )
          v1 = -1892951115;
        v5 = v1;
        break;
      case 1058605341:
        ++v8;
        v5 = 1046773218;
        break;
      case 1501457574:
        v3 = 710936108;
        if ( !(*a1)[9 * v8 + v7] )
          v3 = -516195663;
        v5 = v3;
        break;
    }
  }
  return v6;
}

第一步

case 1046773218:                          
        v1 = -1585203536;                     
        if ( v8 < 9 )
          v1 = -1892951115;                    
        v5 = v1;
        break;

v8 < 9的话,就会进入-1892951115,否则进入-1585203536
我们先看v8>9的情况:

if ( v5 == -1585203536 )
      break;

直接退出。。。所以v8必须<9才出现下一步。

第二步

 while ( v5 == -1892951115 )
    {
      v7 = 0;                                   // 初始化v7
      v5 = -1048142948;
    }

这里初始化了一个v7,留心即可。

第三步

case -1048142948:
        v2 = -1237447983;                       
                                               
        if ( v7 < 9 )
          v2 = 1501457574;                     
        v5 = v2;
        break;

这里判断了v7的大小,利用v7来判断程序的执行流程,感觉应该是个for循环,
老样子,看看v7>9的情况

case -1237447983:
        v5 = 1058605341;
        break;

继续往下:

case 1058605341:
        ++v8;
        v5 = 1046773218;
        break;

这里进行了v8自增,还没看出有什么猫腻,继续往下:

v5 = 1046773218;

这不就是回到了第一步嘛?????嗯哼,回去了。.。

但是v7 < 9的话,流程进到1501457574;

第四步

case 1501457574:                         
        v3 = 710936108;                        
        if ( !(*sudoku)[9 * v8 + v7] )
          v3 = -516195663;                      
        v5 = v3;
        break;

这里为什么是v8*9+v7呢?我个人认为它把这个数组分成一个二维数组,每行是九个,v8也就代表行数,v7代表列数,当v7大于9时,那么只需要把行数+1(即v8自增,然后v7清零即可)。这个二维数组有9行9列,当行数大于9时(即v8>9时,那么就遍历完了,然后直接退出即可)

  1. 当数组中的元素值非0时
v3 = 710936108;

流程代码不用管

case 710936108:
        v5 = -1026222996;
        break;

依然是流程代码:

case -1026222996:
        ++v7;
        v5 = -1048142948;
        break;

v7自增,然后进行流程代码,往下进行。

v5 = -1048142948;

这个流程-1048142948;直接回到第三步。。灭了
2. 当数组中的元素值为0时

v3 = -516195663; 

流程进到了下一步:

第五步

case -516195663:
        ++v6;
        v5 = 710936108;
        break;

这里v6++,也就是统计0的个数,

case 710936108:
        v5 = -1026222996;
        break;

这里全是流程代码,没必要分开写了

case -1026222996:
        ++v7;
        v5 = -1048142948;
        break;

紧接着流程回到第三步v5 = -1048142948;

总结

它把这个数组分成一个二维数组,每行是九个,v8也就代表行数,v7代表列数,当v7大于9时,那么只需要把行数+1(即v8自增,然后v7清零即可)。这个二维数组有9行9列,当行数大于9时(即v8>9时,那么就遍历完了,然后直接退出即可)
也就是一个遍历,然后把0的个数找出来,也就是v6自增。(v6就代表0的个数,最后返回是v6,也就是这个数组中0的个数)

trace(sudoku, v5, v4);

代码

void __fastcall trace(__int64 a1, signed int *a2, int a3)
{
  signed int v3; // eax
  signed int v4; // eax
  signed int v5; // eax
  signed int v6; // eax
  int v7; // eax
  signed int v8; // er8
  signed int v9; // eax
  signed int v10; // eax
  signed int v11; // eax
  signed int v12; // eax
  signed int v13; // [rsp+78h] [rbp-28h]
  int v14; // [rsp+7Ch] [rbp-24h]
  signed int v15; // [rsp+80h] [rbp-20h]
  signed int v16; // [rsp+84h] [rbp-1Ch]
  signed int v17; // [rsp+88h] [rbp-18h]
  int v18; // [rsp+8Ch] [rbp-14h]

  v18 = a3;
  v14 = 0;
  v13 = 671940414;
  while ( 1 )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        while ( 1 )
        {
          while ( 1 )
          {
            while ( 1 )
            {
              while ( 1 )
              {
                while ( v13 == -2124394493 )
                {
                  v4 = 338033522;
                  if ( v17 < 9 )
                    v4 = -1264962160;
                  v13 = v4;
                }
                if ( v13 != -2084617164 )
                  break;
                ++v18;
                v17 = a2[12 * v14];
                v16 = a2[12 * v14 + 1];
                v13 = 295419890;
              }
              if ( v13 != -2069701336 )
                break;
              v5 = 942378879;
              if ( v16 < 9 )
                v5 = 1672958513;
              v13 = v5;
            }
            if ( v13 != -1561315505 )
              break;
            v13 = 2016120547;
          }
          if ( v13 != -1361654796 )
            break;
          ++v16;
          v13 = -2069701336;
        }
        if ( v13 != -1289862082 )
          break;
        v13 = -1361654796;
      }
      if ( v13 != -1264962160 )
        break;
      v16 = 0;
      v13 = -2069701336;
    }
    if ( v13 == -1246113443 )
      break;
    if ( v13 == -446534017 )
    {
      v9 = 1764791757;
      if ( !a2[12 * v14 + 2] )
        v9 = 1923573299;
      v13 = v9;
    }
    else if ( v13 == -264375465 )
    {
      *(_DWORD *)(36LL * a2[12 * v14] + a1 + 4LL * a2[12 * v14 + 1]) = 0;
      ++v18;
      --v14;
      v13 = -446534017;
    }
    else if ( v13 == -127108152 )
    {
      a2[12 * v14] = v17;
      a2[12 * v14 + 1] = v16;
      v7 = findvalue(a1, &a2[12 * v14]);
      v8 = 295419890;
      *(_DWORD *)(36LL * v17 + a1 + 4LL * v16) = v7;
      if ( *(_DWORD *)(36LL * v17 + a1 + 4LL * v16) == -1 )
        v8 = 1601744610;
      v13 = v8;
    }
    else if ( v13 == 67917660 )
    {
      *(_DWORD *)(36LL * a2[12 * v14] + a1 + 4LL * a2[12 * v14 + 1]) = v15;
      a2[12 * v14 + 2 + v15] = 1;
      --a2[12 * v14 + 2];
      v13 = -2084617164;
    }
    else if ( v13 == 295419890 )
    {
      ++v14;
      v18 = v18 - 1146223301 + 1146223300;
      v13 = -1289862082;
    }
    else if ( v13 == 338033522 )
    {
      v13 = 671940414;
    }
    else if ( v13 == 376448068 )
    {
      v17 = 0;
      v13 = -2124394493;
    }
    else if ( v13 == 599244415 )
    {
      v11 = -2084617164;
      if ( v15 < 10 )
        v11 = 1332608024;
      v13 = v11;
    }
    else if ( v13 == 671940414 )
    {
      v3 = -1246113443;
      if ( v18 )
        v3 = 376448068;
      v13 = v3;
    }
    else if ( v13 == 942378879 )
    {
      v13 = 1396614849;
    }
    else if ( v13 == 1332608024 )
    {
      v12 = -1561315505;
      if ( !a2[12 * v14 + 2 + v15] )
        v12 = 67917660;
      v13 = v12;
    }
    else if ( v13 == 1396614849 )
    {
      ++v17;
      v13 = -2124394493;
    }
    else if ( v13 == 1601744610 )
    {
      *(_DWORD *)(36LL * v17 + a1 + 4LL * v16) = 0;
      --v14;
      v13 = -446534017;
    }
    else if ( v13 == 1672958513 )
    {
      v6 = -1289862082;
      if ( !*(_DWORD *)(36LL * v17 + a1 + 4LL * v16) )
        v6 = -127108152;
      v13 = v6;
    }
    else
    {
      if ( v13 == 1751405620 )
      {
        printf(aGameOver);
        exit(1);
      }
      switch ( v13 )
      {
        case 1764791757:
          v15 = 1;
          v13 = 599244415;
          break;
        case 1923573299:
          v10 = -264375465;
          if ( !v14 )
            v10 = 1751405620;
          v13 = v10;
          break;
        case 2016120547:
          ++v15;
          v13 = 599244415;
          break;
      }
    }
  }
  free(a2);
}

第一步

 else if ( v13 == 671940414 )              
    {
      v3 = -1246113443;                       
      if ( v18 )
        v3 = 376448068;
      v13 = v3;
    }

这里利用v18来控制流程,先假设反面,v18为0,v3 = -1246113443;,

 if ( v13 == -1246113443 )
      break;

好了,直接退出。,所以v18必不可能为0.

第二步

else if ( v13 == 376448068 )
    {
      i = 0;
      v13 = -2124394493;
    }

i赋值为0,然后紧接流程代码

while ( v13 == -2124394493 )
                {
                  v4 = 338033522;            
                  if ( i < 9 )
                    v4 = -1264962160;         
                  v13 = v4;
                }

判断了i值和9,先假设坏情况,i>9,v4 = 338033522;,

else if ( v13 == 338033522 )
    {
      v13 = 671940414;
    }

流程代码,直接进行下一个(好家伙,回到第一步了。回到第一步呢,紧接着就会执行第二步,也就是把i置零。):

else if ( v13 == 671940414 )               
    {
      v3 = -1246113443;                         
      if ( v18 )
        v3 = 376448068;
      v13 = v3;
    }

接下来来分析一下i<9的情况v4 = -1264962160;

第三步:

if ( v13 != -1264962160 )
        break;
      j = 0;
      v13 = -2069701336;
    }

这里给j赋值了,然后接下来是流程代码

if ( v13 != -2069701336 )
                break;
              v5 = 942378879;                  
              if ( j < 9 )
                v5 = 1672958513;              
              v13 = v5;
            }

这里判断j值,然后再来进行程序的执行,反向,j>9时v5 = 942378879;

else if ( v13 == 942378879 )
    {
      v13 = 1396614849;
    }

流程代码,继续往下:

else if ( v13 == 1396614849 )
    {
      ++i;
      v13 = -2124394493;
    }

好家伙,i自增,那么这个i就是行数,大于9然后++,盲猜下一步要把j置零。

while ( v13 == -2124394493 )
                {
                  v4 = 338033522;              
                  if ( i < 9 )
                    v4 = -1264962160;          
                  v13 = v4;
                }

这里判断了行数是否大于9,那么不大于9的话,下一步就是列数置零喽

if ( v13 != -1264962160 )
        break;
      j = 0;
      v13 = -2069701336;
    }

好了,我们继续分析,列数小于9,

 if ( j < 9 )
                v5 = 1672958513;            
              v13 = v5;
            }

流程代码,继续分析:

第四步

 else if ( v13 == 1672958513 )               
    {
      v6 = -1289862082;                      
      if ( !*(_DWORD *)(36LL * i + sudoku + 4LL * j) )
        v6 = -127108152;                        
      v13 = v6;
    }

这里又来判断元素是否为0喽。。。。假设非0,v6 = -1289862082;

if ( v13 != -1289862082 )
          break;
        v13 = -1361654796;
      }

流程代码:

if ( v13 != -1361654796 )
            break;
          ++j;
          v13 = -2069701336;
        }

也就是继续遍历下一个元素喽。直到遇到0,好了,我们假设0吧:

第五步

 else if ( v13 == -127108152 )               // step5
    {
      v5_1[12 * v14] = i;
      v5_1[12 * v14 + 1] = j;
      v7 = findvalue(sudoku, &v5_1[12 * v14]);
      v8 = 295419890;
      *(_DWORD *)(36LL * i + sudoku + 4LL * j) = v7;
      if ( *(_DWORD *)(36LL * i + sudoku + 4LL * j) == -1 )
        v8 = 1601744610;
      v13 = v8;
    }

这里把0位置的行数和列数记在一个新数组中,然后,先往下吧,v8 = 295419890;

 else if ( v13 == 295419890 )
    {
      ++v14;
      v18 = v18 - 1146223301 + 1146223300;     
      v13 = -1289862082;
    }

v14自增,然后v18自减,接着流程代码

if ( v13 != -1289862082 )
          break;
        v13 = -1361654796;
      }

流程代码,不用管,接着走。

if ( v13 != -1361654796 )
            break;
          ++j;
          v13 = -2069701336;
        }

继续遍历下一个元素,那没事了。。。。

第六步

继续下一种情况:v8 = 1601744610;

 else if ( v13 == 1601744610 )
    {
      *(_DWORD *)(36LL * i + sudoku + 4LL * j) = 0;
      --v14;
      v13 = -446534017;
    }

把数组相应位置赋0,然后v14自减。接着流程代码:

if ( v13 == -446534017 )
    {
      v9 = 1764791757;
      if ( !v5_1[12 * v14 + 2] )
        v9 = 1923573299;
      v13 = v9;
    }

此处判断所处的数组元素是否为0,为0的话v9 = 1764791757;

case 1764791757:
          v15 = 1;
          v13 = 599244415;
          break;

v15赋值1,然后流程代码

 v13 = 599244415;
          break;

流程代码,

else if ( v13 == 599244415 )
    {
      v11 = -2084617164;
      if ( v15 < 10 )
        v11 = 1332608024;
      v13 = v11;
    }

再来判断是否小于10,首先假设大于10,v11 = -2084617164;

if ( v13 != -2084617164 )
                  break;
                ++v18;
                i = v5_1[12 * v14];
                j = v5_1[12 * v14 + 1];
                v13 = 295419890;
              }

i ,j被利用数组中的值赋上,然后v18自增,紧接着流程代码:
绕回来了:

 else if ( v13 == 295419890 )
    {
      ++v14;
      v18 = v18 - 1146223301 + 1146223300;     
      v13 = -1289862082;
    }

然后假设小于10,v11 = 1332608024;

 else if ( v13 == 1332608024 )
    {
      v12 = -1561315505;
      if ( !v5_1[12 * v14 + 2 + v15] )
        v12 = 67917660;
      v13 = v12;
    }

然后判断数组元素是否为0,非零情况下:v12 = -1561315505;

 if ( v13 != -1561315505 )
              break;
            v13 = 2016120547;
          }

流程代码,继续,

 case 2016120547:
          ++v15;
          v13 = 599244415;
          break;

v15自增,流程代码:

 else if ( v13 == 599244415 )
    {
      v11 = -2084617164;
      if ( v15 < 10 )
        v11 = 1332608024;
      v13 = v11;
    }

为0情况下,v12 = 67917660;

else if ( v13 == 67917660 )
    {
      *(_DWORD *)(36LL * v5_1[12 * v14] + sudoku + 4LL * v5_1[12 * v14 + 1]) = v15;
      v5_1[12 * v14 + 2 + v15] = 1;
      --v5_1[12 * v14 + 2];
      v13 = -2084617164;
    }

改变了数组的内容,紧接着流程代码,然后回到上级

  if ( v13 != -2084617164 )
                  break;
                ++v18;
                i = v5_1[12 * v14];
                j = v5_1[12 * v14 + 1];
                v13 = 295419890;
              }

第七步(第五步的第二种情况)

v8 = 1601744610;这时流程代码如下:

 else if ( v13 == 1601744610 )
    {
      *(_DWORD *)(36LL * i + sudoku + 4LL * j) = 0;
      --v14;
      v13 = -446534017;
    }

数组元素被赋值0,v14自减,紧接着流程代码:

if ( v13 == -446534017 )
    {
      v9 = 1764791757;
      if ( !v5_1[12 * v14 + 2] )
        v9 = 1923573299;
      v13 = v9;
    }

然后又返回去了。

总结

check(int (*a1)[9])

代码

__int64 __fastcall check(int (*a1)[9])
{
  __int64 result; // rax
  signed int v2; // eax
  signed int v3; // eax
  signed int v4; // [rsp+24h] [rbp-18h]
  signed int v5; // [rsp+2Ch] [rbp-10h]
  signed int v6; // [rsp+30h] [rbp-Ch]

  v6 = 0;
  v4 = 1715923540;
  while ( 1 )
  {
    while ( 1 )
    {
      while ( v4 == -1955732718 )
        v4 = 927738670;
      if ( v4 != -1010822917 )
        break;
      v5 = 0;
      v4 = -135298689;
    }
    result = (unsigned int)(v4 + 849866751);
    if ( v4 == -849866751 )
      break;
    switch ( v4 )
    {
      case -135298689:
        v3 = 623468669;
        if ( v5 < 9 )
          v3 = -1955732718;
        v4 = v3;
        break;
      case 623468669:
        v4 = 2055416056;
        break;
      case 927738670:
        ++v5;
        v4 = -135298689;
        break;
      case 1715923540:
        v2 = -849866751;
        if ( v6 < 9 )
          v2 = -1010822917;
        v4 = v2;
        break;
      case 2055416056:
        ++v6;
        v4 = 1715923540;
        break;
    }
  }
  return result;
}

__int64 __fastcall findvalue(__int64 a1, int *a2)

代码

__int64 __fastcall findvalue(__int64 a1, int *a2)
{
  signed int v2; // eax
  signed int v3; // eax
  signed int v4; // eax
  signed int v5; // eax
  signed int v6; // eax
  signed int v7; // eax
  signed int v8; // eax
  signed int v9; // eax
  signed int v10; // eax
  signed int v12; // [rsp+8Ch] [rbp-2Ch]
  int v13; // [rsp+90h] [rbp-28h]
  int v14; // [rsp+94h] [rbp-24h]
  signed int v15; // [rsp+98h] [rbp-20h]
  signed int v16; // [rsp+9Ch] [rbp-1Ch]
  unsigned int v17; // [rsp+B4h] [rbp-4h]

  v14 = *a2;
  v13 = a2[1];
  v16 = 0;
  v12 = -791724132;
  while ( 1 )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        while ( 1 )
        {
          while ( 1 )
          {
            while ( 1 )
            {
              while ( 1 )
              {
                while ( 1 )
                {
                  while ( 1 )
                  {
                    while ( 1 )
                    {
                      while ( 1 )
                      {
                        while ( 1 )
                        {
                          while ( 1 )
                          {
                            while ( 1 )
                            {
                              while ( 1 )
                              {
                                while ( 1 )
                                {
                                  while ( 1 )
                                  {
                                    while ( 1 )
                                    {
                                      while ( 1 )
                                      {
                                        while ( 1 )
                                        {
                                          while ( v12 == -1704444406 )
                                          {
                                            v17 = v16;
                                            v12 = 981711445;
                                          }
                                          if ( v12 != -1635553414 )
                                            break;
                                          ++v16;
                                          v12 = 1796887582;
                                        }
                                        if ( v12 != -1431966323 )
                                          break;
                                        ++v15;
                                        v12 = -53637786;
                                      }
                                      if ( v12 != -1235584672 )
                                        break;
                                      ++v16;
                                      v12 = 156864788;
                                    }
                                    if ( v12 != -1228737224 )
                                      break;
                                    v8 = -1104998472;
                                    if ( v16 < 10 )
                                      v8 = -890529193;
                                    v12 = v8;
                                  }
                                  if ( v12 != -1144155234 )
                                    break;
                                  ++v16;
                                  v12 = -1228737224;
                                }
                                if ( v12 != -1104998472 )
                                  break;
                                v10 = -1704444406;
                                if ( v16 == 10 )
                                  v10 = 2089198738;
                                v12 = v10;
                              }
                              if ( v12 != -890529193 )
                                break;
                              v9 = 862823000;
                              if ( !a2[v16 + 2] )
                                v9 = 771361621;
                              v12 = v9;
                            }
                            if ( v12 != -791724132 )
                              break;
                            v2 = -611155481;
                            if ( v16 < 10 )
                              v2 = 1792341902;
                            v12 = v2;
                          }
                          if ( v12 != -611155481 )
                            break;
                          v16 = 1;
                          v12 = 522488884;
                        }
                        if ( v12 != -248881259 )
                          break;
                        ++a2[2];
                        v12 = 1986744843;
                      }
                      if ( v12 != -53637786 )
                        break;
                      v5 = -32951658;
                      if ( v15 < 3 )
                        v5 = 432619495;
                      v12 = v5;
                    }
                    if ( v12 != -32951658 )
                      break;
                    v12 = -1635553414;
                  }
                  if ( v12 != 156864788 )
                    break;
                  v6 = 507587421;
                  if ( v16 < 10 )
                    v6 = 810472009;
                  v12 = v6;
                }
                if ( v12 != 432619495 )
                  break;
                a2[*(signed int *)(36LL * (v16 - -3 * (v14 / 3)) + a1 + 4LL * (v15 - -3 * (v13 / 3))) + 2] = 1;
                v12 = -1431966323;
              }
              if ( v12 != 507587421 )
                break;
              v16 = 1;
              v12 = -1228737224;
            }
            if ( v12 != 522488884 )
              break;
            v3 = 1921980522;
            if ( v16 < 10 )
              v3 = 1524139080;
            v12 = v3;
          }
          if ( v12 != 771361621 )
            break;
          a2[v16 + 2] = 1;
          --a2[2];
          v12 = -1104998472;
        }
        if ( v12 != 810472009 )
          break;
        v7 = 1986744843;
        if ( !a2[v16 + 2] )
          v7 = -248881259;
        v12 = v7;
      }
      if ( v12 != 862823000 )
        break;
      v12 = -1144155234;
    }
    if ( v12 == 981711445 )
      break;
    switch ( v12 )
    {
      case 1044110222:
        ++v16;
        v12 = -791724132;
        break;
      case 1275000702:
        ++v16;
        v12 = 522488884;
        break;
      case 1353319228:
        a2[2] = 0;
        v16 = 1;
        v12 = 156864788;
        break;
      case 1404549511:
        v15 = 0;
        v12 = -53637786;
        break;
      case 1524139080:
        a2[*(signed int *)(36LL * v14 + a1 + 4LL * (v16 - 1)) + 2] = 1;
        a2[*(signed int *)(36LL * (v16 - 832240230 + 832240229) + a1 + 4LL * v13) + 2] = 1;
        v12 = 1275000702;
        break;
      case 1792341902:
        a2[v16 + 2] = 0;
        v12 = 1044110222;
        break;
      case 1796887582:
        v4 = 1353319228;
        if ( v16 < 3 )
          v4 = 1404549511;
        v12 = v4;
        break;
      case 1921980522:
        v16 = 0;
        v12 = 1796887582;
        break;
      case 1986744843:
        v12 = -1235584672;
        break;
      case 2089198738:
        v17 = -1;
        v12 = 981711445;
        break;
    }
  }
  return v17;
}

第一步

				if ( v12 != -791724132 )
                       break;
                        v2 = -611155481;

控制流代码,没什么好说的,v2 = -611155481;

 				if ( v12 != -611155481 )
                            break;
                          v16 = 1;
                          v12 = 522488884;
                        

v16赋值1,然后控制流代码,v12 = 522488884;

if ( v12 != 522488884 )
              break;
            v3 = 1921980522;

控制流代码v3 = 1921980522;

case 1921980522:
        v16 = 0;
        v12 = 1796887582;
        break;

v16被赋值0,然后控制流代码v12 = 1796887582;

case 1796887582:
        v4 = 1353319228;
        if ( v16 < 3 )
          v4 = 1404549511;
        v12 = v4;
        break;

这里利用v16来判断接下来的流程,先看v16>3的情况吧,

 case 1353319228:
        a2[2] = 0;
        v16 = 1;
        v12 = 156864788;
        break;

数组的第三个元素被赋值为0,然后v16被赋值为1,然后流程代码,v12 = 156864788;

 if ( v12 != 156864788 )
                    break;
                  v6 = 507587421;
                  if ( v16 < 10 )
                    v6 = 810472009;
                  v12 = v6;

这里又来进行第二波判断,v16的值,假设大于10,流程代码,v6 = 507587421;

 if ( v12 != 507587421 )
                break;
              v16 = 1;
              v12 = -1228737224;
            }

v16被赋值为1,然后流程代码,

                                    if ( v12 != -1228737224 )
                                      break;
                                    v8 = -1104998472;
                                    if ( v16 < 10 )
                                      v8 = -890529193;
                                    v12 = v8;
                                  }

v16>10的话,v8 = -1104998472

 			if ( v12 != -1104998472 )
                                  break;
                                v10 = -1704444406;
                                if ( v16 == 10 )
                                  v10 = 2089198738;
                                v12 = v10;
  1. 如果v16等于10,v10 = 2089198738;
case 2089198738:
        v17 = -1;
        v12 = 981711445;
        break;

返回-1,然后退出,if ( v12 == 981711445 ) break;

  1. 如果不等于10的话,
while ( v12 == -1704444406 )
                                     {
                                         v17 = v16;
                                         v12 = 981711445;
                                         }
      

v16赋给v17,然后退出

if ( v12 == 981711445 )
      break;

然后来看看v16<3的情况

				if ( v12 != 432619495 )
                  break;
                a2[*(signed int *)(36LL * (v16 - -3 * (v14 / 3)) + a1 + 4LL * (v15 - -3 * (v13 / 3))) + 2] = 1;
                v12 = -1431966323;

把你赋值给a2数组的某个位置,然后流程控制代码

                                       if ( v12 != -1431966323 )
                                          break;
                                        ++v15;
                                        v12 = -53637786;

v15自增,紧接着流程控制代码,然后执行回去,近一步探索

 if ( v12 != -53637786 )
                        break;
                      v5 = -32951658;
                      if ( v15 < 3 )
                        v5 = 432619495;
                      v12 = v5;

最上面的v16的值,小于10时,流程代码,v6 = 810472009;

if ( v12 != 810472009 )
          break;
        v7 = 1986744843;
        if ( !a2[v16 + 2] )
          v7 = -248881259;
        v12 = v7;

判断数组元素是否为0,

  1. 非0的情况v7 = 1986744843;
case 1986744843:
        v12 = -1235584672;
        break;

流程代码:

					                                     if ( v12 != -1235584672 )
                                        break;
                                      ++v16;
                                      v12 = 156864788;
                                    }

v16自增,然后流程代码,

                    if ( v12 != 156864788 )
                    break;
                  v6 = 507587421;
                  if ( v16 < 10 )
                    v6 = 810472009;
                  v12 = v6;
  1. 为0情况v7 = -248881259;
 if ( v12 != -248881259 )
                          break;
                        ++a2[2];
                        v12 = 1986744843;
                      }
				case 1986744843:
        v12 = -1235584672;
        break;
                                      if ( v12 != -1235584672 )
                                        break;
                                      ++v16;
                                      v12 = 156864788;
                                    }
 if ( v12 != 156864788 )
                    break;
                  v6 = 507587421;
                  if ( v16 < 10 )
                    v6 = 810472009;
                  v12 = v6;

第二步

v16<10的话,v8 = -890529193

					if ( v12 != -890529193 )
                            break;
                              v9 = 862823000;
                              if ( !a2[v16 + 2] )
                                v9 = 771361621;
                              v12 = v9;

判断数组元素是否为0,

  1. 非0的情况v9 = 862823000;
if ( v12 != 862823000 )
        break;
      v12 = -1144155234;

流程代码:

						if ( v12 != -1144155234 )
                                    break;
                                  ++v16;
                                  v12 = -1228737224;

v16自增,然后流程代码,

                                   if ( v12 != -1228737224 )
                                      break;
                                    v8 = -1104998472;
                                    if ( v16 < 10 )
                                      v8 = -890529193;
                                    v12 = v8;
  1. 为0情况v9 = 771361621;
if ( v12 != 771361621 )
            break;
          a2[v16 + 2] = 1;
          --a2[2];
          v12 = -1104998472;
					if ( v12 != -1104998472 )
                                  break;
                                v10 = -1704444406;
                                if ( v16 == 10 )
                                  v10 = 2089198738;
                                v12 = v10;

check1(char *a1)

代码

__int64 __fastcall check1(char *a1)
{
  __int64 result; // rax
  size_t v2; // rax
  signed int v3; // ecx
  char v4; // ST6F_1
  size_t v5; // rax
  signed int v6; // ecx
  char v7; // ST6E_1
  size_t v8; // rax
  signed int v9; // ecx
  signed int v10; // [rsp+68h] [rbp-18h]
  int v11; // [rsp+70h] [rbp-10h]
  int v12; // [rsp+74h] [rbp-Ch]

  v12 = strlen(a1) >> 1;
  v11 = 0;
  v10 = 1519002972;
  while ( 1 )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        while ( 1 )
        {
          while ( 1 )
          {
            while ( 1 )
            {
              while ( 1 )
              {
                while ( v10 == -2084833488 )
                {
                  v8 = strlen(a1);
                  v9 = -67245798;
                  if ( v12 < v8 )
                    v9 = 1974939745;
                  v10 = v9;
                }
                if ( v10 != -1988665894 )
                  break;
                v12 = 0;
                v10 = -2084833488;
              }
              if ( v10 != -1393133668 )
                break;
              v5 = strlen(a1);
              v6 = -1988665894;
              if ( v12 < v5 )
                v6 = -1018472136;
              v10 = v6;
            }
            if ( v10 != -1018472136 )
              break;
            v7 = a1[v12];
            a1[v12] = a1[v12 + 1];
            a1[v12 + 1] = v7;
            v10 = -146751883;
          }
          if ( v10 != -831482631 )
            break;
          ++v12;
          v10 = -2084833488;
        }
        if ( v10 != -291294424 )
          break;
        ++v11;
        ++v12;
        v10 = 1519002972;
      }
      if ( v10 != -146751883 )
        break;
      v12 += 2;
      v10 = -1393133668;
    }
    result = (unsigned int)(v10 + 67245798);
    if ( v10 == -67245798 )
      break;
    switch ( v10 )
    {
      case 75381312:
        v4 = a1[v12];
        a1[v12] = a1[v11];
        a1[v11] = v4;
        v10 = -291294424;
        break;
      case 1519002972:
        v2 = strlen(a1);
        v3 = 1555725255;
        if ( v11 < v2 >> 1 )
          v3 = 75381312;
        v10 = v3;
        break;
      case 1555725255:
        v12 = 0;
        v10 = -1393133668;
        break;
      case 1974939745:
        a1[v12] = (a1[v12] & 0xF3 | ~a1[v12] & 0xC) - 20;
        v10 = -831482631;
        break;
    }
  }
  return result;
}

check3(char *a1)

代码

__int64 __fastcall check3(char *a1)
{
  __int64 result; // rax
  signed int v2; // eax
  signed int v3; // [rsp+28h] [rbp-18h]
  int v4; // [rsp+3Ch] [rbp-4h]

  v4 = check2(a1);
  v3 = 16123822;
  while ( 1 )
  {
    while ( v3 == 16123822 )
    {
      v2 = 1478060410;
      if ( !v4 )
        v2 = 1274132590;
      v3 = v2;
    }
    result = (unsigned int)(v3 - 824643665);
    if ( v3 == 824643665 )
      break;
    if ( v3 == 1274132590 )
    {
      v3 = 824643665;
      printf("error!\n");
    }
    else if ( v3 == 1478060410 )
    {
      v3 = 824643665;
      printf("you get it!\n");
    }
  }
  return result;
}

check2(char *a1)

代码

__int64 __fastcall check2(char *a1)
{
  size_t v1; // rax
  signed int v2; // ecx
  signed int v3; // eax
  signed int v4; // eax
  signed int v5; // eax
  signed int v6; // eax
  signed int v7; // eax
  signed int v8; // eax
  signed int v9; // eax
  signed int v11; // [rsp+8Ch] [rbp-C4h]
  unsigned int v12; // [rsp+90h] [rbp-C0h]
  int v13; // [rsp+94h] [rbp-BCh]
  signed int v14; // [rsp+98h] [rbp-B8h]
  signed int v15; // [rsp+9Ch] [rbp-B4h]
  int v16[42]; // [rsp+A0h] [rbp-B0h]
  char *s; // [rsp+148h] [rbp-8h]

  s = a1;
  v13 = 0;
  v12 = 1;
  v15 = 0;
  v11 = -2671583;
  while ( 1 )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        while ( 1 )
        {
          while ( 1 )
          {
            while ( 1 )
            {
              while ( 1 )
              {
                while ( 1 )
                {
                  while ( 1 )
                  {
                    while ( 1 )
                    {
                      while ( 1 )
                      {
                        while ( 1 )
                        {
                          while ( 1 )
                          {
                            while ( 1 )
                            {
                              while ( 1 )
                              {
                                while ( v11 == -2119125118 )
                                {
                                  ++v15;
                                  v11 = -94879051;
                                }
                                if ( v11 != -1998111552 )
                                  break;
                                v6 = 396170963;
                                if ( v15 < 9 )
                                  v6 = -512482015;
                                v11 = v6;
                              }
                              if ( v11 != -1695072055 )
                                break;
                              ++v15;
                              v11 = -1998111552;
                            }
                            if ( v11 != -1658909923 )
                              break;
                            v8 = -1129833658;
                            if ( D0g3[9 * v15 + v14] != sudoku[9 * v15 + v14] )
                              v8 = -528396247;
                            v11 = v8;
                          }
                          if ( v11 != -1613667829 )
                            break;
                          v11 = -2119125118;
                        }
                        if ( v11 != -1369143226 )
                          break;
                        v14 = 0;
                        v11 = -740861019;
                      }
                      if ( v11 != -1244045086 )
                        break;
                      D0g3[9 * v15 + v14] = v16[v13++];
                      v11 = 1611237474;
                    }
                    if ( v11 != -1129833658 )
                      break;
                    v11 = -90011013;
                  }
                  if ( v11 != -740861019 )
                    break;
                  v4 = -1613667829;
                  if ( v14 < 9 )
                    v4 = 705300330;
                  v11 = v4;
                }
                if ( v11 != -528396247 )
                  break;
                v12 = 0;
                v11 = 1954800504;
              }
              if ( v11 != -512482015 )
                break;
              v14 = 0;
              v11 = 564268595;
            }
            if ( v11 != -334121999 )
              break;
            v15 = 0;
            v11 = -1998111552;
          }
          if ( v11 != -94879051 )
            break;
          v3 = -334121999;
          if ( v15 < 9 )
            v3 = -1369143226;
          v11 = v3;
        }
        if ( v11 != -90011013 )
          break;
        ++v14;
        v11 = 564268595;
      }
      if ( v11 != -2671583 )
        break;
      v1 = strlen(s);
      v2 = 2101131376;
      if ( v15 < v1 )
        v2 = 441246003;
      v11 = v2;
    }
    if ( v11 == 396170963 )
      break;
    switch ( v11 )
    {
      case 430996436:
        ++v15;
        v11 = -2671583;
        break;
      case 441246003:
        v16[v15] = s[v15] - 232084296 + 232084248;
        v11 = 430996436;
        break;
      case 564268595:
        v7 = 1954800504;
        if ( v14 < 9 )
          v7 = -1658909923;
        v11 = v7;
        break;
      case 705300330:
        v5 = 1611237474;
        if ( !D0g3[9 * v15 + v14] )
          v5 = -1244045086;
        v11 = v5;
        break;
      case 1611237474:
        v11 = 2119231421;
        break;
      case 1908623879:
        v11 = -1695072055;
        break;
      case 1954800504:
        v9 = 1908623879;
        if ( !v12 )
          v9 = 2014359934;
        v11 = v9;
        break;
      case 2014359934:
        v11 = 396170963;
        break;
      case 2101131376:
        v15 = 0;
        v11 = -94879051;
        printf("\n");
        break;
      case 2119231421:
        ++v14;
        v11 = -740861019;
        break;
    }
  }
  return v12;
}

有关安洵杯——game(混淆控制流平坦化)的更多相关文章

  1. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  2. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  3. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  4. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  5. ruby-on-rails - 在 Rails 控制台中使用 asset_path - 2

    在我的Character模型中,我添加了:字符.rbbefore_savedoself.profile_picture_url=asset_path('icon.png')end但是,对于数据库中已存在的所有角色,它们的profile_picture_url为nil。因此,我想进入控制台并遍历所有这些并进行设置。在我试过的控制台中:Character.find_eachdo|c|c.profile_picture_url=asset_path('icon.png')end但这给出了错误:NoMethodError:undefinedmethod`asset_path'formain:O

  6. ruby-on-rails - 带有 Pry 的 Rails 控制台 - 2

    当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question

  7. ruby - 将全局 $stdout 重新分配给控制台 - ruby - 2

    我正在尝试将$stdout设置为临时写入一个文件,然后返回到一个文件。test.rb:old_stdout=$stdout$stdout.reopen("mytestfile.out",'w+')puts"thisgoesinmytestfile"$stdout=old_stdoutputs"thisshouldbeontheconsole"$stdout.reopen("mytestfile1.out",'w+')puts"thisgoesinmytestfile1:"$stdout=old_stdoutputs"thisshouldbebackontheconsole"这是输出。r

  8. ruby-on-rails - Ruby 流量控制 : throw an exception, 返回 nil 还是让它失败? - 2

    我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id

  9. ruby-on-rails - ruby 新手,有人可以帮我从控制台破译这个错误吗? - 2

    我真的只是不确定这意味着什么或我应该做什么才能让网页在我的本地主机上运行。现在它只是显示一个错误,上面写着“我们很抱歉,但出了点问题。”当我运行railsserver并在chrome中打开localhost:3000时。这是控制台输出:StartedGET"/users/sign_in"for127.0.0.1at2013-07-0512:07:07-0400ProcessingbyDevise::SessionsController#newasHTMLCompleted500InternalServerErrorin55msNoMethodError(undefinedmethod`

  10. ruby-on-rails - Rails 控制台的 YAML 输出 - 2

    在Rails控制台中执行类似yGrau.all的命令时,我得到这些奇怪的!binary字符串而不是属性名称。知道如何解决这个问题吗?谢谢。irb(main):003:0>yGrau.all←[1m←[36mGrauLoad(0.0ms)←[0m←[1mSELECT"graus".*FROM"gr←[1m←[35mEXPLAIN(0.0ms)←[0mEXPLAINQUERYPLANSELECT"grauEXPLAINfor:SELECT"graus".*FROM"graus"0|0|0|SCANTABLEgraus(~1000000rows)----!ruby/object:Grauat

随机推荐