通过阅读上述代码,我们知道这个算法的流程如下:
遍历我们输入的Flag值,每次取1个字母
计算取出的字母在g_szStr数组中的下标值,为nStrIdx
按照以下公式计算出两个Switch值
根据Swicth中的值,去改变byte_4B7080二维数组中的行列坐标值
最后若byte_4B7080数组中的值全部不为0,则说明Flag有效
通过阅读源代码得知,我们输入的Flag中的每个单个字母会影响Switch的值,进而影响在byte_4B7080数组中取出的值
根据Switch修改的nRow nCol,要满足
每个字母,会计算出两个Switch值,进而得到两个坐标
先来计算Flag的第一个字母
如行走路线为上图,则前两个坐标为(0, 1), (1, 2)
根据坐标初始值为(0, 0), 以及上述Switch影响坐标的规则,可以逆向推出两个Switch的值分别为 1 2
根据下述代码,得到Flag的第一个字母
最后按照上述路线图全部走完,利用上述代码计算单个Flag值,将其拼接起来就是有效的Flag
char g_szStr[]
=
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
;
int
g_StrLen
=
0x24
;
char byte_4B7080[]
=
{
0x53
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x01
,
0x01
,
0x01
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x00
,
0x00
,
0x01
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x01
,
0x01
,
0x01
,
0x00
,
0x01
,
0x01
,
0x01
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x01
,
0x01
,
0x01
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x01
,
0x01
,
0x00
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x01
,
0x00
,
0x00
};
/
/
计算cFlag在g_szStr中的下标
bool
LuoCalcStrIndex(char cFlag,
int
& nStrIndex)
{
bool
bFlag
=
false;
for
(
int
i
=
0
; i < g_StrLen; i
+
+
)
{
if
(g_szStr[i]
=
=
cFlag)
{
bFlag
=
true;
nStrIndex
=
i;
}
}
return
bFlag;
}
int
main()
{
char szFlag[
80
]
=
{};
memset(szFlag,
0
, sizeof(szFlag));
printf(
"Input your code: \r\n"
);
scanf(
"%s"
, szFlag);
int
nStrIdx
=
0
;
int
nFlagIdx
=
0
;
char cFlag
=
szFlag[
0
];
int
nSwitch
=
0
;
int
v7
=
0
;
int
v8
=
0
;
int
v12
=
0
;
char
*
v13
=
NULL;
int
v17
=
0
;
int
v18
=
0
;
int
v19
=
0
;
int
v20
=
0
;
int
v22
=
0
;
unsigned
int
nCol
=
0
;
unsigned
int
nRow
=
0
;
int
nFlagLen
=
strlen(szFlag);
if
(nFlagLen >
0x30
)
{
printf(
"Try again...\r\n"
);
return
0
;
}
int
i
=
0
;
for
(nFlagIdx
=
0
; nFlagIdx < nFlagLen; )
{
/
/
计算cFlag在g_szStr中的下标
if
(!LuoCalcStrIndex(cFlag, nStrIdx))
{
printf(
"cFlag = %c 不在g_szStr数组中\r\n"
, cFlag);
system(
"pause"
);
return
0
;
}
v20
=
(nFlagIdx
+
nStrIdx
/
6
)
%
6
;
nCol
=
v22;
nSwitch
=
5
-
(nFlagIdx
+
nStrIdx)
%
6
;
for
(
int
i
=
0
; ;i
=
1
)
{
switch (nSwitch)
{
case
1
:
+
+
nCol;
/
/
列
+
+
break
;
case
2
:
v17
=
(nRow
+
+
&
1
)
=
=
0
;
/
/
偶数行, 行
+
+
列
+
+
nCol
+
=
v17;
/
/
奇数行, 行
+
+
列不变
break
;
case
3
:
v12
=
(nRow
+
+
&
1
) !
=
0
;
/
/
奇数行, 行
+
+
列
-
-
nCol
-
=
v12;
/
/
偶数行, 行
+
+
列不变
break
;
case
4
:
-
-
nCol;
/
/
列
-
-
break
;
case
5
:
v19
=
(nRow
-
-
&
1
) !
=
0
;
/
/
奇数行, 行
-
-
列
-
-
nCol
-
=
v19;
/
/
偶数行, 行
-
-
列不变
break
;
default:
v18
=
(nRow
-
-
&
1
)
=
=
0
;
/
/
偶数行, 行
-
-
列
+
+
nCol
+
=
v18;
/
/
奇数行, 行
-
-
列不变
break
;
}
if
(nCol >
9
)
{
printf(
"Try again...\r\n"
);
return
0
;
}
if
(nRow >
8
)
{
printf(
"Try again...\r\n"
);
return
0
;
}
v13
=
&byte_4B7080[
0xA
*
nRow
+
nCol];
if
(
*
v13)
{
printf(
"Try again...\r\n"
);
return
0
;
}
*
v13
=
1
;
if
(i
=
=
1
)
{
+
+
nFlagIdx;
v22
=
nCol;
cFlag
=
szFlag[nFlagIdx];
break
;
}
nSwitch
=
v20;
}
}
int
nSize
=
sizeof(byte_4B7080);
bool
bFlag
=
true;
for
(
int
i
=
0
; i < nSize; i
+
+
)
{
if
(byte_4B7080[i]
=
=
0
)
{
bFlag
=
false;
}
}
if
(bFlag
=
=
true)
{
printf(
"Good job!\r\n"
);
}
else
{
printf(
"Try again...\r\n"
);
}
system(
"pause"
);
return
0
;
}
char g_szStr[]
=
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
;
int
g_StrLen
=
0x24
;
char byte_4B7080[]
=
{
0x53
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x01
,
0x01
,
0x01
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x00
,
0x00
,
0x01
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x01
,
0x01
,
0x01
,
0x00
,
0x01
,
0x01
,
0x01
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x01
,
0x01
,
0x01
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x01
,
0x01
,
0x00
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x01
,
0x01
,
0x00
,
0x00
};
/
/
计算cFlag在g_szStr中的下标
bool
LuoCalcStrIndex(char cFlag,
int
& nStrIndex)
{
bool
bFlag
=
false;
for
(
int
i
=
0
; i < g_StrLen; i
+
+
)
{
if
(g_szStr[i]
=
=
cFlag)
{
bFlag
=
true;
nStrIndex
=
i;
}
}
return
bFlag;
}
int
main()
{
char szFlag[
80
]
=
{};
memset(szFlag,
0
, sizeof(szFlag));
printf(
"Input your code: \r\n"
);
scanf(
"%s"
, szFlag);
int
nStrIdx
=
0
;
int
nFlagIdx
=
0
;
char cFlag
=
szFlag[
0
];
int
nSwitch
=
0
;
int
v7
=
0
;
int
v8
=
0
;
int
v12
=
0
;
char
*
v13
=
NULL;
int
v17
=
0
;
int
v18
=
0
;
int
v19
=
0
;
int
v20
=
0
;
int
v22
=
0
;
unsigned
int
nCol
=
0
;
unsigned
int
nRow
=
0
;
int
nFlagLen
=
strlen(szFlag);
if
(nFlagLen >
0x30
)
{
printf(
"Try again...\r\n"
);
return
0
;
}
int
i
=
0
;
for
(nFlagIdx
=
0
; nFlagIdx < nFlagLen; )
{
/
/
计算cFlag在g_szStr中的下标
if
(!LuoCalcStrIndex(cFlag, nStrIdx))
{
printf(
"cFlag = %c 不在g_szStr数组中\r\n"
, cFlag);
system(
"pause"
);
return
0
;
}
v20
=
(nFlagIdx
+
nStrIdx
/
6
)
%
6
;
nCol
=
v22;
nSwitch
=
5
-
(nFlagIdx
+
nStrIdx)
%
6
;
for
(
int
i
=
0
; ;i
=
1
)
{
switch (nSwitch)
{
case
1
:
+
+
nCol;
/
/
列
+
+
break
;
case
2
:
v17
=
(nRow
+
+
&
1
)
=
=
0
;
/
/
偶数行, 行
+
+
列
+
+
nCol
+
=
v17;
/
/
奇数行, 行
+
+
列不变
break
;
case
3
:
v12
=
(nRow
+
+
&
1
) !
=
0
;
/
/
奇数行, 行
+
+
列
-
-
nCol
-
=
v12;
/
/
偶数行, 行
+
+
列不变
break
;
case
4
:
-
-
nCol;
/
/
列
-
-
break
;
case
5
:
v19
=
(nRow
-
-
&
1
) !
=
0
;
/
/
奇数行, 行
-
-
列
-
-
nCol
-
=
v19;
/
/
偶数行, 行
-
-
列不变
break
;
default:
v18
=
(nRow
-
-
&
1
)
=
=
0
;
/
/
偶数行, 行
-
-
列
+
+
nCol
+
=
v18;
/
/
奇数行, 行
-
-
列不变
break
;
}
if
(nCol >
9
)
{
printf(
"Try again...\r\n"
);
return
0
;
}
if
(nRow >
8
)
{
printf(
"Try again...\r\n"
);
return
0
;
}
v13
=
&byte_4B7080[
0xA
*
nRow
+
nCol];
if
(
*
v13)
{
printf(
"Try again...\r\n"
);
return
0
;
}
*
v13
=
1
;
if
(i
=
=
1
)
{
+
+
nFlagIdx;
v22
=
nCol;
cFlag
=
szFlag[nFlagIdx];
break
;
}
nSwitch
=
v20;
}
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2021-5-12 11:34
被夏洛魂编辑
,原因: