[NPUCTF2020]Baby Obfuscation 64位无壳,主函数
int  __cdecl main (int  argc, const  char  **argv, const  char  **envp)   int  v3;    int  v4;    int  v5;    int  v6;    int  v7;    int  v8;    int  v9;    int  v10;    int  v11;    int  v12;    int  v13;    int  v14;    int  v15;    int  v16;    int  v17;    bool  v18;    int  v19;    int  v20;    int  v21;    int  v22;    int  v23;    int  v24;    int  v25;    int  v26;    int  A0X3[65 ];    char  A0X2[1001 ];    int  A0X1[1001 ];    int  A0X5[4 ];    int  A0X4[4 ];    int  V0X1;    int  i_1;    int  i_0;    int  i;    _main();   memset (A0X1, 0 , 0xFA0 ui64);   A0X1[1000 ] = 0 ;   memset (A0X3, 0 , 0x100 ui64);   A0X3[64 ] = 0 ;   for  ( i = 0 ; i <= 64 ; ++i )     A0X3[i] = i + 1 ;   A0X4[0 ] = 2 ;   A0X4[1 ] = 3 ;   A0X4[2 ] = 4 ;   A0X4[3 ] = 5 ;   A0X5[0 ] = 2 ;   A0X5[1 ] = 3 ;   A0X5[2 ] = 4 ;   A0X5[3 ] = 5 ;   puts ("WHERE IS MY KEY!?" );   scanf ("%32s" , A0X2);   V0X1 = strlen (A0X2);   v3 = F0X1 (A0X3[i_0], A0X3[i_0]);   for  ( i_0 = v3 / A0X3[i_0]; i_0 <= V0X1; ++i_0 )   {     v4 = (A0X3[i_0] + A0X3[i_0 + 1 ]) * (A0X3[i_0] + A0X3[i_0 + 1 ]);     if  ( v4 >= F0X5 (2 , 2 ) * A0X3[i_0] * A0X3[i_0 + 1 ] )     {       v5 = ~A0X2[F0X4 (i_0, 1 )];       v6 = F0X4 (i_0, 1 );       A0X1[i_0] = ~(v5 + A0X4[v6 % F0X5 (2 , 2 )]);     }     v7 = F0X1 (A0X3[i_0], A0X3[i_0 + 1 ]);     if  ( v7 > F0X1 (A0X3[i_0 + 1 ], ~(~A0X3[i_0 + 1 ] + A0X3[i_0])) )     {       v8 = A0X1[i_0];       v9 = F0X4 (i_0, 1 );       A0X1[i_0] = ~(~v8 + A0X3[v9 % F0X5 (2 , 2 )]) * v8;     }     v10 = A0X3[i_0 + 1 ];     v11 = F0X5 (2 , 1 ) * v10;     v12 = A0X3[i_0];     v13 = F0X5 (2 , 1 );     v14 = F0X1 (v12 * v13, v11);     v15 = F0X5 (2 , 1 );     if  ( v14 == v15 * F0X1 (A0X3[i_0], A0X3[i_0 + 1 ]) )     {       v16 = F0X4 (i_0, 1 );       A0X1[i_0] ^= A0X4[v16 % F0X5 (2 , 2 )];     }     v17 = F0X5 (V0X3, A0X3[i_0]);     v18 = v17 < A0X3[i_0] + 1 ;     v19 = F0X5 (2 , 4 );     if  ( F0X3 (v19 >= i_0, v18) )     {       v20 = ~A0X2[F0X4 (i_0, 1 )];       v21 = F0X4 (i_0, 1 );       A0X1[i_0] ^= ~(v20 + A0X4[v21 % F0X5 (2 , 2 )]);     }     v22 = F0X5 (2 , 3 );     v23 = F0X1 (A0X3[i_0], A0X3[i_0]);     A0X1[i_0] *= v22 + F0X5 (2 , v23 / A0X3[i_0]);   }   v24 = F0X5 (2 , 4 );   if  ( F0X4 (v24, 1 ) != V0X1 )     goto  LABEL_23;   v25 = F0X1 (A0X3[i_1], A0X3[i_1]);   for  ( i_1 = v25 / A0X3[i_1]; i_1 <= V0X1; ++i_1 )   {     v26 = A0X1[i_1];     if  ( v26 == F0X4 (A0X6[i_1], 1 ) / 10  )       ++V0X2;   }   if  ( V0X2 == V0X1 )     puts ("\nPASS" );   else  LABEL_23:     puts ("\nDENIED" );   return  0 ; } 
按顺序分析,逐个函数分析吧
各个函数 F0X1 int __cdecl F0X1(int a, int b) {   int result; // eax   if ( b )     result = F0X1(b, a % b);   else     result = a;   return result; } 
欧几里得算法,辗转相除法,求出最大公倍数
F0X3&F0X2 bool  __cdecl F0X3 (bool  a, bool  b)   bool  v2;    bool  v3;    v2 = F0X2(b, b);   v3 = F0X2(a, a);   return  F0X2(v3, v2); } bool  __cdecl F0X2 (bool  a, bool  b)   return  a == b && !a; } 
F0X4 int  __cdecl F0X4 (int  a, int  b)   return  ~(~a + b); } 
F0X5 int  __cdecl F0X5 (int  a, int  b)   int  ans;    ans = 1 ;   while  ( b )   {     if  ( (b & 1 ) != 0  )       ans *= a;     a *= a;     b >>= 1 ;   }   return  ans; } 
最后再程序整体中推断
for  ( i_0 = v3 / A0X3[i_0]; i_0 <= V0X1; ++i_0 )  {     v4 = (A0X3[i_0] + A0X3[i_0 + 1 ]) * (A0X3[i_0] + A0X3[i_0 + 1 ]);     if  ( v4 >= F0X5(2 , 2 ) * A0X3[i_0] * A0X3[i_0 + 1 ] )     {       v5 = ~key[F0X4(i_0, 1 )];       v6 = F0X4(i_0, 1 );       A0X1[i_0] = ~(v5 + A0X4[v6 % F0X5(2 , 2 )]);     }     v7 = F0X1(A0X3[i_0], A0X3[i_0 + 1 ]);     if  ( v7 > F0X1(A0X3[i_0 + 1 ], ~(~A0X3[i_0 + 1 ] + A0X3[i_0])) )     {       v8 = A0X1[i_0];       v9 = F0X4(i_0, 1 );       A0X1[i_0] = ~(~v8 + A0X3[v9 % F0X5(2 , 2 )]) * v8;     }     v10 = A0X3[i_0 + 1 ];     v11 = F0X5(2 , 1 ) * v10;     v12 = A0X3[i_0];     v13 = F0X5(2 , 1 );     v14 = F0X1(v12 * v13, v11);     v15 = F0X5(2 , 1 );     if  ( v14 == v15 * F0X1(A0X3[i_0], A0X3[i_0 + 1 ]) )     {       v16 = F0X4(i_0, 1 );       A0X1[i_0] ^= A0X4[v16 % F0X5(2 , 2 )];     }     v17 = F0X5(V0X3, A0X3[i_0]);     v18 = v17 < A0X3[i_0] + 1 ;     v19 = F0X5(2 , 4 );     if  ( F0X3(v19 >= i_0, v18) )                     {       v20 = ~key[F0X4(i_0, 1 )];       v21 = F0X4(i_0, 1 );       A0X1[i_0] ^= ~(v20 + A0X4[v21 % F0X5(2 , 2 )]);     }     v22 = F0X5(2 , 3 );     v23 = F0X1(A0X3[i_0], A0X3[i_0]);     A0X1[i_0] *= v22 + F0X5(2 , v23 / A0X3[i_0]);   } 
最后会执行的就如下所示,
A0X1[i_0] *= v22 + F0X5(2, v23 / A0X3[i_0]);
A0X1[i_0] ^= A0X4[v16 % F0X5(2, 2)];
A0X1[i_0] = ~(v5 + A0X4[v6 % F0X5(2, 2)]);
等效与
A0X1[i_0] *=10
A0X1[i_0] ^= A0X4[i_0-1 % 4]
然后这个替换 v5 = ~key[F0X4(i_0, 1 )]; v6 = F0X4(i_0, 1 ); A0X1[i_0] = ~(v5 + A0X4[v6 % F0X5(2 , 2 )]); A0X1[i_0] = key[(i_0-1 )%4 ]-A0X4[i_0-1  % 4 ] 
脚本 A0X4=[2 ,3 ,4 ,5 ] aox6=[0 ,0x1E79 ,0x1E79 ,0x2135 ,0x170D ,0x1F41 ,0x1901 ,0x2CED ,0x11F9 ,0x2649 ,0x2581 ,0x2DB5 ,0x14B5 ,0x25E5 ,0x2A31 ,0x30D5 ] for  i in  range (1 ,16 ):    aox6[i]//=100      aox6[i]^=A0X4[(i-1 )%4 ]     aox6[i]+=A0X4[(i-1 )%4 ]     print (chr (aox6[i]),end="" ) 
[NPUCTF2020]Baby Obfuscation