这题主要是对if()
内的两个函数进行分析,
第一个函数
int __usercall sub_321240@<eax>(int a1@<edx>, byte *a2@<ecx>, int *a3)
{
int v3; // ebx
int i; // esi
unsigned int m; // edi
char v6; // al
signed int j; // ecx
int v9; // ecx
byte *v10; // [esp+0h] [ebp-64h]
int v11; // [esp+4h] [ebp-60h]
__int128 arr[5]; // [esp+Ch] [ebp-58h]
char v14; // [esp+5Ch] [ebp-8h]
arr[0] = (__int128)_mm_load_si128((const __m128i *)&xmmword_336280);
v3 = 0;
arr[1] = (__int128)_mm_load_si128((const __m128i *)&xmmword_3362A0);
i = 0;
v11 = a1;
v10 = a2;
v14 = 113;
arr[2] = (__int128)_mm_load_si128((const __m128i *)&xmmword_336270);
arr[3] = (__int128)_mm_load_si128((const __m128i *)&xmmword_336290);
arr[4] = (__int128)_mm_load_si128((const __m128i *)&xmmword_336260);// 并不是顺序存储,动调获取结果
if ( a1 <= 0 )
return 1;
m = 0;
while ( 1 )
{
v6 = a2[i];
if ( v6 > '0' && v6 <= '9' )
break;
j = m;
if ( m >= 0x51 )
return 0;
while ( v6 != *((_BYTE *)arr + j) )
{
if ( (unsigned int)++j >= 81 ) // 获取下标
return 0;
}
v9 = j % 9 + 1; // 存储范围:1~9
if ( v9 == -1 )
return 0;
*a3 = v9; // 最终结果保存到a3中
a2 = v10;
++v3;
++a3;
a1 = v11;
LABEL_13:
if ( ++i >= a1 ) //说明要遍历一遍输入的值,判断是否符合条件
return 1;
}
if ( v3 + v6 == '9' ) // 每成功取一个值,下一次起点偏移+9
{
v3 = 0;
m += 9; // 9个为一组
goto LABEL_13;
}
return -1;
}
目前还不能看出究竟在做什么,
第二个函数
可以知道这是一个数独
它先是将第一个函数获取的内容填充到数独表中
do // 插入由第一个函数获取的值
{
if ( !*(v3 - 1) )
{
v4 = *(_DWORD *)&a1[4 * v2++];
*(v3 - 1) = v4;
}
if ( !*v3 )
{
v5 = *(_DWORD *)&a1[4 * v2++];
*v3 = v5;
}
if ( !v3[1] )
{
v6 = *(_DWORD *)&a1[4 * v2++];
v3[1] = v6;
}
if ( !v3[2] )
{
v7 = *(_DWORD *)&a1[4 * v2++];
v3[2] = v7;
}
if ( !v3[3] )
{
v8 = *(_DWORD *)&a1[4 * v2++];
v3[3] = v8;
}
if ( !v3[4] )
{
v9 = *(_DWORD *)&a1[4 * v2++];
v3[4] = v9;
}
if ( !v3[5] )
{
v10 = *(_DWORD *)&a1[4 * v2++];
v3[5] = v10;
}
if ( !v3[6] )
{
v11 = *(_DWORD *)&a1[4 * v2++];
v3[6] = v11;
}
if ( !v3[7] )
{
v12 = *(_DWORD *)&a1[4 * v2++];
v3[7] = v12;
}
if ( v2 >= a2 )
break;
v3 += 9; // +9说明9个数据为一行
}
while ( (int)v3 < (int)&ByteEnd ); // 结束位置
然后分别进行判断
行判断
while ( 2 ) // 判断每一行的值是否都不相等
{
v15 = 1;
v16 = v13;
do
{
v17 = v15;
if ( v15 < 9 )
{
v18 = *v16;
while ( v18 )
{
v19 = ByteStart[v14 + v17];
if ( !v19 || v18 == v19 ) // 同一排的值不能相等
break;
if ( ++v17 >= 9 )
goto LABEL_30;
}
return 0;
}
LABEL_30:
++v15;
++v16;
}
while ( v15 < 10 ); // 一共81位
v14 += 9;
v13 = v41 + 9;
v41 = v13;
if ( (int)v13 < (int)&unk_338904 )
continue;
break;
}
列判断
while ( 2 ) // 判断每一列的值是否都不相等
{
v21 = 1;
v42 = v20;
v22 = v20 - 9;
v23 = v20;
do
{
v24 = v21;
if ( v21 < 9 )
{
v25 = *v22;
while ( v25 && *v23 && v25 != *v23 ) // 比较
{
++v24;
v23 += 9;
if ( v24 >= 9 )
{
v23 = v42;
goto LABEL_41;
}
}
return 0;
}
LABEL_41:
++v21;
v23 += 9;
v22 += 9;
v42 = v23;
}
while ( v21 < 10 );
v20 = v39 + 4;
v39 = (char *)v20;
if ( (int)v20 < (int)&unk_338808 )
continue;
break;
}
小九宫格判断
LABEL_45: // 这里开始到最后,判断每个小九宫格是否每个数都不一致
i = 0;
LABEL_46:
*(_QWORD *)v26 = 0i64;
v26[4] = 0;
if ( !__OFSUB__(v27, v27 + 3) ) // 减
{
v30 = 3;
v31 = &ByteStart[j + i];
v40 = 3;
do
{
if ( !__OFSUB__(i, i + 3) )
{
v32 = v31; // 取byte[]
v33 = 3;
do
{
v34 = *v32++; // byte[i++]
++*((_BYTE *)v26 + v34); // v34++
--v33;
}
while ( v33 );
v30 = v40;
}
v31 += 9; // 一排一排的查看
v40 = --v30;
}
while ( v30 );
v27 = v43;
j = v38;
}
if ( !*(_BYTE *)v26 )
{
v35 = 0;
v36 = 1;
while ( *((char *)v26 + v36) <= 1 )
{
++v36;
++v35;
if ( v36 >= 10 )
{
if ( v35 != 9 )
break;
i += 3;
if ( i < 9 )
goto LABEL_46;
j += 27;
v27 += 3;
v43 = v27;
v38 = j;
if ( j < 81 )
goto LABEL_45;
free(v26);
return 1; // 当所有判断都成立后,返回1
}
}
}
free(v26);
}
return 0;
两个函数总的意思:将输入的值获取处于指定字符串中的下标,然后转换成1~9之间的数,并填充到数独表中,然后进行数独的行,列以及小九宫格的判断
解题
通过网上的数独在线工具,获得内容
然后就快乐的搓脚本
arr=[0x24, 0x42, 0x50, 0x56, 0x3A, 0x75, 0x62, 0x66, 0x59, 0x70,
0x7D, 0x5D, 0x44, 0x74, 0x4E, 0x3E, 0x61, 0x54, 0x5E, 0x4D,
0x47, 0x6D, 0x4A, 0x51, 0x23, 0x2A, 0x48, 0x72, 0x60, 0x4F,
0x27, 0x77, 0x6A, 0x69, 0x63, 0x30, 0x21, 0x68, 0x64, 0x79,
0x7B, 0x6F, 0x5A, 0x7A, 0x2D, 0x40, 0x6E, 0x2B, 0x3F, 0x26,
0x25, 0x73, 0x5F, 0x2F, 0x67, 0x3C, 0x65, 0x5B, 0x57, 0x29,
0x58, 0x55, 0x78, 0x52, 0x46, 0x53, 0x4C, 0x52, 0x41, 0x3B,
0x2E, 0x6C, 0x3D, 0x43, 0x45, 0x6B, 0x76, 0x4B, 0x2D, 0x28,
0x71, 0xF7, 0x2A]
sudu=[[5,6,1,9,2,3,8],[1,8,3,4,5],[7,6,2,1,9],[7,8,4,6,9,2,5],[4,5,3,9,7,8,6],[6,9,2,8,7,1,3],[2,8,5,6,3],[6,1,7,2,8],[1,7,9,3,4,5,2]]
for i in range(len(sudu)):
tmp=len(sudu[i])
for j in range(tmp):
for x in range(i*9,len(arr)):
if(x%9+1==sudu[i][j]):
print(chr(arr[x]),end="")
break
print(9-tmp,end="")
获得flag:
:u$YBPf2pa]Dt4#QM^H4ic'j0`w2y{d-Zzo2%/n_s@+2<UW)e4AR;F.4=-qEkvC2