此题是个console程序,运行情况如下,有错误提示。就是那个提问
不知道有什么特殊含义没有。再看阁下的数学成绩堪忧,请回吧。
这个错误提示,莫非此题需要深厚的数学功底?
静态加载程序,发现全屏的花指令,没见到一个正常的函数,翻了半天没了看到比较正常
的指令,看来真实指令被淹没在代码海中了,又是体力活。看到基本都是call pop xor
的样式,于是尝试去花,把这段代码直接改成了jmp
,如下图:
但是去完后发现,还有嵌套的这种模式,地址计算除了xor
,还有add
之类的指令,这可不好去花了。而且还有更复杂的情况:有好几个地址会跳到一小段代码的不同位置。于是放弃继续去花,别寻他法。
想着如果能从中找到什么规律或能大概了解程序的业务流程结构就好了。考虑到既然有校验,那肯定比较,看了下导入函数,有strcmp
和strncmp
,在访问这两个函数的地方下断,运行后随便输入,有调用strcmp
,比较对象竟然是1764
,那个提问
的答案,又尝试了几次,没什么用。既然函数方面下断没有帮助,那就考虑指令方面吧。试想如果找到跳转的地方,大概结构就可以慢慢动态出来了。于是一计浮上心头:代码搜索+断点大法。
先看有多少跳转,还要筛选出有用的,但是跳转的地方代码看不到数据,不知道因为校验或比较什么而跳转了。为了解决此问题,稍微改变下着手点,把搜索跳转代码改成搜索cmp
指令。搜索了下,大概100出头的cmp,直接导入到调试器动态调试,动态过程中去掉无用的断点。慢慢地能看出了一部分的流程。
再然后只能看到嵌套循环了,不知道计算了什么。于是再来搜索指令,先把所有用到的指令列出来,挑了数目比较少感觉可能用到的,比如sub
、idiv
、imul
,再来下数据大法,多跟了几次,就把算法跟出来了,如下的模拟计算:
42个数两两计算,abcd分别为两个数的42进制低位和高位,结果唯一。
综合来看,这应该是一个42*42的矩阵,上面放置42个点,行列唯一,列的出现顺序还要有要求,有点像N皇后问题,但是应该是变形的。要求两两连线不平行。空间有点大,而且可能有多解,比较难算。后来注意到还有个疑似42进制的字串,在strncmp
处断下与输入前28个字符比较,这样空间就小多了。解算代码如下:
结果为:02152S3X4Z5Q6C7T819/ADB%CDLEIFUG3HRIHJ6K7L0MBNKOJPPQ=RNS+TEUOVWWGXYYMZ9+4-8F/-%V=A
def
get_dis(a,b,c,d):
dx
=
c
-
d
dy
=
a
-
b
if
dx <
0
:
dy
=
-
dy
dx
=
-
dx
dy
+
=
0x29
return
dy
*
42
+
dx
def
get_dis(a,b,c,d):
dx
=
c
-
d
dy
=
a
-
b
if
dx <
0
:
dy
=
-
dy
dx
=
-
dx
dy
+
=
0x29
return
dy
*
42
+
dx
import
copy
ts
=
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-*/%='
mat
=
[
2
,
5
,
28
,
33
,
35
,
26
,
12
,
29
,
1
,
39
,
13
,
40
,
38
,
21
]
dis
=
{}
def
get_dis(a,b,c,d):
dx
=
c
-
d
dy
=
a
-
b
if
dx <
0
:
dy
=
-
dy
dx
=
-
dx
dy
+
=
0x29
return
dy
*
42
+
dx
def
get_dis_all(p):
dis
=
[]
for
i
in
range
(
len
(p)
-
1
):
for
j
in
range
(i
+
1
,
len
(p)):
dis.append(get_dis(i,j,p[i],p[j]))
return
dis
def
search(cur):
global
count,mat,dis
if
cur
=
=
42
:
out
=
''
for
i
in
range
(
42
):
out
+
=
'{}{}'
.
format
(ts[i],ts[mat[i]])
print
out
prettyprint(mat)
exit()
for
i
in
range
(cur,
42
):
flag
=
True
for
j
in
range
(cur):
if
get_dis(j,cur,mat[j],mat[i])
in
dis:
flag
=
False
break
if
flag:
for
k
in
range
(cur):
dis[get_dis(k,cur,mat[k],mat[i])]
=
1
mat[i],mat[cur]
=
mat[cur],mat[i]
search(cur
+
1
)
mat[i],mat[cur]
=
mat[cur],mat[i]
for
k
in
range
(cur):
dis.pop(get_dis(k,cur,mat[k],mat[i]))
def
prettyprint(solution):
def
line(pos, length
=
len
(solution)):
return
' . '
*
(pos)
+
' x '
+
' . '
*
(length
-
pos
-
1
)
for
pos
in
solution:
print
(line(pos))
def
main():
global
dis
for
i
in
get_dis_all(mat[:
14
]):
dis[i]
=
1
for
i
in
range
(
42
):
if
i
not
in
mat:
mat.append(i)
search(
14
)
print
'end.'
if
__name__
=
=
'__main__'
:
main()
import
copy
ts
=
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-*/%='
mat
=
[
2
,
5
,
28
,
33
,
35
,
26
,
12
,
29
,
1
,
39
,
13
,
40
,
38
,
21
]
dis
=
{}
def
get_dis(a,b,c,d):
dx
=
c
-
d
dy
=
a
-
b
if
dx <
0
:
dy
=
-
dy
dx
=
-
dx
dy
+
=
0x29
return
dy
*
42
+
dx
def
get_dis_all(p):
dis
=
[]
for
i
in
range
(
len
(p)
-
1
):
for
j
in
range
(i
+
1
,
len
(p)):
dis.append(get_dis(i,j,p[i],p[j]))
return
dis
def
search(cur):
global
count,mat,dis
if
cur
=
=
42
:
out
=
''
for
i
in
range
(
42
):
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)