[安洵杯 2019]game WriteUp
考点:
控制流平坦化
反编译main函数
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
python代码还原逻辑:
1 | def check2(): |
解题的关键就是找到原来的数独,和填好的数独,提取填好的数字,然后做check1中的逆向操作就可以得到flag
最终是比较dog3和sudoku里的值,dog3是已知部分填充部分,sudoku需要动态调试得知填入的值
1 | .data:0000000000604300 public D0g3 |
逆向脚本1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16sudoku = [1, 4, 5, 3, 2, 7, 6, 9, 8, 8, 3, 9, 6, 5, 4, 1, 2, 7, 6, 7, 2, 8, 1, 9, 5, 4, 3, 4, 9, 6, 1, 8, 5, 3, 7, 2, 2, 1, 8, 4, 7, 3, 9, 5, 6, 7, 5, 3, 2, 9, 6, 4, 8, 1, 3, 6, 7, 5, 4, 2, 8, 1, 9, 9, 8, 4, 7, 6, 1, 2, 3, 5, 5, 2, 1, 9, 3, 8, 7, 6, 4]
dog3 = [1, 0, 5, 3, 2, 7, 0, 0, 8, 8, 0, 9, 0, 5, 0, 0, 2, 0, 0, 7, 0, 0, 1, 0, 5, 0, 3, 4, 9, 0, 1, 0, 0, 3, 0, 0, 0, 1, 0, 0, 7, 0, 9, 0, 6, 7, 0, 3, 2, 9, 0, 4, 8, 0, 0, 6, 0, 5, 4, 0, 8, 0, 9, 0, 0, 4, 0, 0, 1, 0, 3, 0, 0, 2, 1, 0, 3, 0, 7, 0, 4]
flag = []
for i in range(81):
if sudoku[i] != dog3[i]:
tmp = ord(str(sudoku[i])) + 20
flag.append( tmp&0xf3 | ~tmp&0xc )
print(flag)
for i in range(0,40,2):
(flag[i], flag[i+1]) = (flag[i+1], flag[i]) #两位操作
for i in range(20):
(flag[i],flag[i+20]) = (flag[i+20], flag[i])
for i in range(40):
print(chr(flag[i]),end='')
# 转自 https://www.cnblogs.com/jentleTao/p/12666415.html
flag{KDEEIFGKIJ@AFGEJAEF@FDKADFGIJFA@FDE@JG@J}
