-
-
[原创]KCTF2020秋季赛 第七题 鱼目混珠
-
发表于: 2020-12-5 00:36 5690
-
程序有很多花指令,不过都有特征,写个OD脚本去掉就行。
去掉以后dump下来丢给IDA F5,配合下动态调试分析
逻辑很清晰,除了最后那个溢出覆盖len比较坑了点
解开方程,再把结果按hexdecode的方法转回字符串就可以了
按hexdecode的方法转回字符串得到flag
10C7F30833B9C4563BF035C32D8C7709E040FCA64E211F34CD3FE773
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
char
*
v3;
/
/
edx
int
v4;
/
/
ecx
unsigned
int
v5;
/
/
eax
char
*
v6;
/
/
edx
int
v7;
/
/
ecx
unsigned
int
v8;
/
/
eax
char
*
v9;
/
/
kr00_4
int
v10;
/
/
esi
int
v11;
/
/
ecx
int
v12;
/
/
edi
int
v13;
/
/
ebx
int
v14;
/
/
esi
int
v16;
/
/
edx
unsigned
int
v17;
/
/
eax
int
v18;
/
/
edx
unsigned
int
v19;
/
/
eax
int
v20;
/
/
edx
unsigned
int
v21;
/
/
eax
unsigned
int
v22;
/
/
eax
int
v23;
/
/
[esp
+
1Ch
] [ebp
-
A0h]
unsigned
int
v24;
/
/
[esp
+
20h
] [ebp
-
9Ch
]
int
v25;
/
/
[esp
+
24h
] [ebp
-
98h
]
int
v26;
/
/
[esp
+
28h
] [ebp
-
94h
]
char v27;
/
/
[esp
+
2Ch
] [ebp
-
90h
]
_DWORD antidebug[
9
];
/
/
[esp
+
3Ch
] [ebp
-
80h
]
int
(
*
v29)(void);
/
/
[esp
+
60h
] [ebp
-
5Ch
]
int
(
*
v30)(void);
/
/
[esp
+
64h
] [ebp
-
58h
]
_DWORD v31[
2
];
/
/
[esp
+
68h
] [ebp
-
54h
] BYREF
char v32[
76
];
/
/
[esp
+
70h
] [ebp
-
4Ch
] BYREF
sub_40CA20();
antidebug[
0
]
=
sub_401700;
/
/
一大堆反调试
antidebug[
1
]
=
sub_401740;
antidebug[
2
]
=
sub_4017B0;
antidebug[
3
]
=
sub_401890;
antidebug[
4
]
=
sub_4018F0;
antidebug[
5
]
=
sub_401570;
dword_4C5028
=
0
;
antidebug[
6
]
=
sub_401820;
antidebug[
7
]
=
sub_401950;
antidebug[
8
]
=
sub_401AB0;
v29
=
sub_402F20;
v30
=
sub_402F90;
dword_4C5024
=
0
;
v31[
0
]
=
sub_401620;
v3
=
a104010010e4b4c;
do
{
v4
=
*
(_DWORD
*
)v3;
v3
+
=
4
;
v5
=
~v4 & (v4
-
16843009
) &
0x80808080
;
}
while
( !v5 );
if
( (~v4 & (v4
-
16843009
) &
0x8080
)
=
=
0
)
v5 >>
=
16
;
if
( (~v4 & (v4
-
16843009
) &
0x8080
)
=
=
0
)
v3
+
=
2
;
hexdecode((
int
*
)&result, (
int
)a104010010e4b4c, (
int
)&v3[
-
__CFADD__((_BYTE)v5, (_BYTE)v5)
-
0x4B9083
]);
/
/
解码两个大数 每字节的高位和低位互换
v6
=
a1e9705f8d92146;
do
{
v7
=
*
(_DWORD
*
)v6;
v6
+
=
4
;
v8
=
~v7 & (v7
-
16843009
) &
0x80808080
;
}
while
( !v8 );
if
( (~v7 & (v7
-
16843009
) &
0x8080
)
=
=
0
)
v8 >>
=
16
;
if
( (~v7 & (v7
-
16843009
) &
0x8080
)
=
=
0
)
v6
+
=
2
;
hexdecode((
int
*
)&big_c2, (
int
)a1e9705f8d92146, (
int
)&v6[
-
__CFADD__((_BYTE)v8, (_BYTE)v8)
-
4952147
]);
v23
=
*
(_DWORD
*
)&result.buf[
8
];
v24
=
*
(_DWORD
*
)&result.buf[
4
];
print
(
*
(_DWORD
*
)&result.buf[
12
]);
memset(v32,
0
,
0x40u
);
scan((
int
)&dword_4BA660, v32);
v9
=
&v32[strlen(v32)];
if
( (unsigned
int
)(v9
-
v32
-
13
) >
0x32
)
goto LABEL_22;
v10
=
sub_4030E0(v32,
7
);
v12
=
sub_4030E0((_BYTE
*
)v31
+
v9
-
v32
+
1
,
7
);
v13
=
0
;
v26
=
0
;
v25
=
0
;
do
{
v27
=
15
-
v13;
if
( (v13 &
1
)
=
=
((
int
(__fastcall
*
)(
int
))antidebug[v13])(v11) )
/
/
执行反调试
{
+
+
v25;
v10
=
v29() ^ __ROR4__(v10, v13);
/
/
两个crc防patch
v12
=
v30() ^ __ROR4__(v12, v27);
}
else
{
+
+
v26;
v10
=
v30() ^ __ROR4__(v10, v27);
v12
=
((
int
(__fastcall
*
)(
int
))v29)(v13) ^ __ROR4__(v12, v13);
}
+
+
v13;
}
while
( v13 !
=
9
);
if
( !v25 )
goto LABEL_22;
if
( !v26 )
goto LABEL_22;
v14
=
dword_4B904C ^ v10;
if
( v14 !
=
v23 || (v12 ^ dword_4B9048) !
=
v24 || hexdecode((
int
*
)&
input
, (
int
)v32, strlen(v32)) <
0
)
/
/
比较crc是否与预设值一样 动态调试时patch掉
goto LABEL_22;
big_r.buf[
4
]
=
0
;
*
(_DWORD
*
)big_r.buf
=
*
(_DWORD
*
)result.buf;
v16
=
4
;
while
(
1
)
{
v17
=
v16
-
1
;
if
( big_r.buf[v16
-
1
] )
break
;
-
-
v16;
if
( !v17 )
goto LABEL_29;
}
v17
=
v16;
LABEL_29:
big_r.
len
=
v17;
big_mul(&big_n, &
input
, &big_r);
input
.buf[
4
]
=
0
;
*
(_DWORD
*
)
input
.buf
=
0xE053D0F
;
v18
=
4
;
while
(
1
)
{
v19
=
v18
-
1
;
if
(
input
.buf[v18
-
1
] )
break
;
-
-
v18;
if
( !v19 )
goto LABEL_32;
}
v19
=
v18;
input
.
len
=
v19;
big_div(&big_n, &big_n, &
input
);
/
/
*
0xE053D0F
big_add(&big_n, &big_n, &result);
big_add(&big_n, &big_n, &big_c2);
/
/
+
0xfea1bd9e6964129d8f5079e1
big_mul(&big_c, &result, &big_c2);
big_sub(&big_r, &big_n, &big_c);
/
/
-
0x3f58d70f55459ad75491a4c3ea858c4961226c27f5a1f8a95b18fde1
if
( (
int
)big_r.
len
>
16
)
goto LABEL_22;
LABEL_32:
big_mul(&big_n, &big_n, &
input
);
/
/
*
0xE053D0F
input
.buf[
4
]
=
0
;
*
(_DWORD
*
)
input
.buf
=
37
;
v20
=
4
;
while
(
1
)
{
v21
=
v20
-
1
;
if
(
input
.buf[v20
-
1
] )
break
;
-
-
v20;
if
( !v21 )
goto LABEL_36;
}
v21
=
v20;
LABEL_36:
input
.
len
=
v21;
big_mul(&big_c, &big_n, &
input
);
/
/
*
37
big_add(&big_c, &big_c, &big_c);
/
/
此处溢出,最高位为
1
,刚好覆盖了result的长度
v22
=
big_r.
len
;
if
( big_r.
len
=
=
result.
len
)
{
while
( (
-
-
v22 &
0x80000000
)
=
=
0
)
{
if
( big_r.buf[v22] !
=
result.buf[v22] )
/
/
表面上跟
0x3faffa2b01b6ba9744c4b4e010010401
比较 实际上是
1
goto LABEL_22;
}
print
(v14);
/
/
GOOD
}
else
{
LABEL_22:
print
(v24);
/
/
ERROR
}
return
0
;
}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
char
*
v3;
/
/
edx
int
v4;
/
/
ecx
unsigned
int
v5;
/
/
eax
char
*
v6;
/
/
edx
int
v7;
/
/
ecx
unsigned
int
v8;
/
/
eax
char
*
v9;
/
/
kr00_4
int
v10;
/
/
esi
int
v11;
/
/
ecx
int
v12;
/
/
edi
int
v13;
/
/
ebx
int
v14;
/
/
esi
int
v16;
/
/
edx
unsigned
int
v17;
/
/
eax
int
v18;
/
/
edx
unsigned
int
v19;
/
/
eax
int
v20;
/
/
edx
unsigned
int
v21;
/
/
eax
unsigned
int
v22;
/
/
eax
int
v23;
/
/
[esp
+
1Ch
] [ebp
-
A0h]
unsigned
int
v24;
/
/
[esp
+
20h
] [ebp
-
9Ch
]
int
v25;
/
/
[esp
+
24h
] [ebp
-
98h
]
int
v26;
/
/
[esp
+
28h
] [ebp
-
94h
]
char v27;
/
/
[esp
+
2Ch
] [ebp
-
90h
]
_DWORD antidebug[
9
];
/
/
[esp
+
3Ch
] [ebp
-
80h
]
int
(
*
v29)(void);
/
/
[esp
+
60h
] [ebp
-
5Ch
]
int
(
*
v30)(void);
/
/
[esp
+
64h
] [ebp
-
58h
]
_DWORD v31[
2
];
/
/
[esp
+
68h
] [ebp
-
54h
] BYREF
char v32[
76
];
/
/
[esp
+
70h
] [ebp
-
4Ch
] BYREF
sub_40CA20();
antidebug[
0
]
=
sub_401700;
/
/
一大堆反调试
antidebug[
1
]
=
sub_401740;
antidebug[
2
]
=
sub_4017B0;
antidebug[
3
]
=
sub_401890;
antidebug[
4
]
=
sub_4018F0;
antidebug[
5
]
=
sub_401570;
dword_4C5028
=
0
;
antidebug[
6
]
=
sub_401820;
antidebug[
7
]
=
sub_401950;
antidebug[
8
]
=
sub_401AB0;
v29
=
sub_402F20;
v30
=
sub_402F90;
dword_4C5024
=
0
;
v31[
0
]
=
sub_401620;
v3
=
a104010010e4b4c;
do
{
v4
=
*
(_DWORD
*
)v3;
v3
+
=
4
;
v5
=
~v4 & (v4
-
16843009
) &
0x80808080
;
}
while
( !v5 );
if
( (~v4 & (v4
-
16843009
) &
0x8080
)
=
=
0
)
v5 >>
=
16
;
if
( (~v4 & (v4
-
16843009
) &
0x8080
)
=
=
0
)
v3
+
=
2
;
hexdecode((
int
*
)&result, (
int
)a104010010e4b4c, (
int
)&v3[
-
__CFADD__((_BYTE)v5, (_BYTE)v5)
-
0x4B9083
]);
/
/
解码两个大数 每字节的高位和低位互换
v6
=
a1e9705f8d92146;
do
{
v7
=
*
(_DWORD
*
)v6;
v6
+
=
4
;
v8
=
~v7 & (v7
-
16843009
) &
0x80808080
;
}
while
( !v8 );
if
( (~v7 & (v7
-
16843009
) &
0x8080
)
=
=
0
)
v8 >>
=
16
;
if
( (~v7 & (v7
-
16843009
) &
0x8080
)
=
=
0
)
v6
+
=
2
;
hexdecode((
int
*
)&big_c2, (
int
)a1e9705f8d92146, (
int
)&v6[
-
__CFADD__((_BYTE)v8, (_BYTE)v8)
-
4952147
]);
v23
=
*
(_DWORD
*
)&result.buf[
8
];
v24
=
*
(_DWORD
*
)&result.buf[
4
];
print
(
*
(_DWORD
*
)&result.buf[
12
]);
memset(v32,
0
,
0x40u
);
scan((
int
)&dword_4BA660, v32);
v9
=
&v32[strlen(v32)];
if
( (unsigned
int
)(v9
-
v32
-
13
) >
0x32
)
goto LABEL_22;
v10
=
sub_4030E0(v32,
7
);
v12
=
sub_4030E0((_BYTE
*
)v31
+
v9
-
v32
+
1
,
7
);
v13
=
0
;
v26
=
0
;
v25
=
0
;
do
{
v27
=
15
-
v13;
if
( (v13 &
1
)
=
=
((
int
(__fastcall
*
)(
int
))antidebug[v13])(v11) )
/
/
执行反调试
{
+
+
v25;
v10
=
v29() ^ __ROR4__(v10, v13);
/
/
两个crc防patch
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
看原图
赞赏
雪币:
留言: