-
-
[原创]KCTF2021 第四题 英雄救美 writeup
-
发表于: 2021-5-14 21:06 5801
-
IDA
sub_691240
通过输入的字符串生成一个数组仅包含数字1-9。
在9*9的初始化表中匹配字符,每出现数字就从下一行开始匹配,将匹配到的第几列存下来。按数字分割字符串,数字=9-数字前字符串的长度。
通过main中sub_691000(v10, v3 - 9)
的调用可以知道数字会出现9次。
导出初始化表
sub_691000(arr, arr_len)
是个数独的判断。
首先将arr
顺序填充到006A87C0非零的值上,9行9列,其中0值有55个,则要输入64(55+9)个字符。
接下来就是判断每行每列每个9宫格不能有重复数字。
导出数独初始值
求出数独
得到arr值5619238183457621978469254539786692871328563617281793452
然而并不知道如何分割为9份。
感谢出题人手下留情,按照数独分行即可。
:u$YBPf2pa]Dt4#QM^H4ic'j0`w2y{d-Zzo2%/n_s@+2<UW)e4AR;F.4=-qEkvC2
main(){
/
/
...
printf(
"Serial: "
);
scanf_s(
"%s"
, v12);
v3
=
strlen(v12);
if
( v3 <
=
64
&& sub_691240(v3, (
int
)v12, v10)
=
=
1
&& sub_691000(v10, v3
-
9
)
=
=
1
)
{
/
/
...
}
/
/
...
}
main(){
/
/
...
printf(
"Serial: "
);
scanf_s(
"%s"
, v12);
v3
=
strlen(v12);
if
( v3 <
=
64
&& sub_691240(v3, (
int
)v12, v10)
=
=
1
&& sub_691000(v10, v3
-
9
)
=
=
1
)
{
/
/
...
}
/
/
...
}
int
__usercall sub_691240@<eax>(
int
a1@<edx>,
int
a2@<ecx>,
int
*
a3)
{
/
/
...
__int128 v13[
5
];
/
/
[esp
+
Ch] [ebp
-
58h
]
9
*
9
初始化表
char v14;
/
/
[esp
+
5Ch
] [ebp
-
8h
]
v13[
0
]
=
(__int128)_mm_load_si128(&stru_6A6280);
v3
=
0
;
v13[
1
]
=
(__int128)_mm_load_si128(stru_6A62A0);
v4
=
0
;
v11
=
a1;
v10
=
a2;
v14
=
'q'
;
v13[
2
]
=
(__int128)_mm_load_si128(&stru_6A6270);
v13[
3
]
=
(__int128)_mm_load_si128(&stru_6A6290);
v13[
4
]
=
(__int128)_mm_load_si128(&stru_6A6260);
if
( a1 <
=
0
)
return
1
;
v5
=
0
;
while
(
1
)
{
v6
=
*
(_BYTE
*
)(v4
+
a2);
if
( v6 >
'0'
&& v6 <
=
'9'
)
break
;
v7
=
v5;
if
( v5 >
=
81
)
/
/
数字不可以超过
9
个
return
0
;
while
( v6 !
=
*
((_BYTE
*
)v13
+
v7) )
/
/
从数字的个数
*
9
的位置开始检索 就是第n行开始
{
if
( (unsigned
int
)
+
+
v7 >
=
81
)
return
0
;
}
v9
=
v7
%
9
+
1
;
if
( v9
=
=
-
1
)
return
0
;
*
a3
=
v9;
/
/
属于第几列的 记录下来
a2
=
v10;
+
+
v3;
+
+
a3;
a1
=
v11;
LABEL_13:
if
(
+
+
v4 >
=
a1 )
return
1
;
}
if
( v3
+
v6
=
=
'9'
)
/
/
数字在字符串后为(
9
-
字符长度)
{
v3
=
0
;
v5
+
=
9
;
goto LABEL_13;
}
return
-
1
;
}
int
__usercall sub_691240@<eax>(
int
a1@<edx>,
int
a2@<ecx>,
int
*
a3)
{
/
/
...
__int128 v13[
5
];
/
/
[esp
+
Ch] [ebp
-
58h
]
9
*
9
初始化表
char v14;
/
/
[esp
+
5Ch
] [ebp
-
8h
]
v13[
0
]
=
(__int128)_mm_load_si128(&stru_6A6280);
v3
=
0
;
v13[
1
]
=
(__int128)_mm_load_si128(stru_6A62A0);
v4
=
0
;
v11
=
a1;
v10
=
a2;
v14
=
'q'
;
v13[
2
]
=
(__int128)_mm_load_si128(&stru_6A6270);
v13[
3
]
=
(__int128)_mm_load_si128(&stru_6A6290);
v13[
4
]
=
(__int128)_mm_load_si128(&stru_6A6260);
if
( a1 <
=
0
)
return
1
;
v5
=
0
;
while
(
1
)
{
v6
=
*
(_BYTE
*
)(v4
+
a2);
if
( v6 >
'0'
&& v6 <
=
'9'
)
break
;
v7
=
v5;
if
( v5 >
=
81
)
/
/
数字不可以超过
9
个
return
0
;
while
( v6 !
=
*
((_BYTE
*
)v13
+
v7) )
/
/
从数字的个数
*
9
的位置开始检索 就是第n行开始
{
if
( (unsigned
int
)
+
+
v7 >
=
81
)
return
0
;
}
v9
=
v7
%
9
+
1
;
if
( v9
=
=
-
1
)
return
0
;
*
a3
=
v9;
/
/
属于第几列的 记录下来
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2021-5-14 21:17
被Wblank编辑
,原因:
赞赏
他的文章
看原图
赞赏
雪币:
留言: