TSCTF-J 2024
TSCTF-J 2024
iPlayIDA
直接解码发现不对,函数很少,查看其它函数发现隐藏逻辑在初始化里
1 | import base64 |
TSCTF-J{We1come_t0_R3verse_Wor1d!}
iPlayPython
pyinstxtractor.py 解python包
反编译pyc文件出现
1 | #!/usr/bin/env python |
这是模仿的一道NewStarCTF的一道题
用网上下的不行会出现Magic错误
我自己用源码编译了一份
可以看出来有某些移位操作
1 | # 解题脚本:根据题目字节表 c 逆向还原原始输入 |
TSCTF-J{I_U$E_PYTH0N}
可以看
NewStar PangBai 过家家(3) | Matriy’s blog和pycdc工具编译使用(纯小白篇,大师傅自动略过) - 吾爱破解 - 52pojie.cn
iPlayPinball
没啥头绪一开始,查了下
对于一般的文件结构,都会有一个后缀为_Data
的文件夹,并且里面有一个名为Managed
的文件夹,而那个文件夹里的Assembly-CSharp.dll
文件正是我们需要的东西,里面包含了作者的代码
发现相应逻辑
通过分析 question.txt 中的代码,我发现这是一个使用Microsoft Z3约束求解器的Unity游戏。主要逻辑在 Win 类的 DisplayWinMessage 方法中:
- 创建了一个长度为37的整数数组 array ,每个元素都是Z3的整数变量
- 定义了37个布尔表达式(方程),每个表达式都是一个线性方程,形式为:系数1×变量1 + 系数2×变量2 + … = 常数
- 将所有方程组合成一个大的约束条件
- 使用Z3求解器求解这个约束系统
- 如果有解,将解转换为字符,拼接成字符串显示为胜利信息(即flag)
手动复制太麻烦可以写代码:
1 | import re |
1 | import re |
效果如下:
1 | from z3 import * |
Flag: TSCTF-J{N0w_L3t’s_7ry_T4ble_Tenni5^^}
iPlayCalc
查到upx壳
懒得用动调脱壳了,直接上工具XVolkolak
脱壳成功
IDA打开发现一大堆base64串,和码表
应该是做了个base64解码,动调跟进去发现
仿射加密
1 | E(x) = (ax + b) mod 26 |
解密:
1 | D(y) = a^(-1) * (y - b) mod 26 |
1 | def mod_inverse(a, m): |
解密后的flag: TSCTF-J{Hat3_C0urse_Des1gn}
iPlayTarot
c# ,dnspy打开
发现click里的主逻辑
1 | # 打开文件并读取每行内容 |
靠上面的dict理解
1 | string[] array6 = new string[16]; |
输入的应该记录在了selectedcards里了,16张牌,如”000”
比如输入[‘000’],那么array6[0]=’101’根据上面的关系
之后再来看check方法
首先不能有000,以下肯定不能选
1 | 006,013,018,020,021,101,104,105,107,201,202,204,205,206,209,211,213,301,302,310,402,408,410,412, |
1 | {'000': '101', '001': '202', '002': '209', '003': '109', '004': '204', '005': '109', '007': '307', '008': '304', '009': '004', '010': '303', '011': '304', '012': '005', '014': '203', '015': '003', '016': '305', '017': '208', '019': '206', '102': '006', '103': '208', '106': '007', '108': '002', '109': '209', '110': '003', '111': '308', '112': '307', '113': '301', '114': '301', '203': '205', '207': '201', '208': '306', '210': '206', '212': '204', '214': '007', '303': '306', '304': '101', '305': '302', '306': '006', '307': '309', '308': '295', '309': '203', '311': '201', '312': '004', '313': '207', '314': '308', '401': '395', '403': '303', '404': '207', '405': '202', '406': '005', '407': '002', '409': '309', '411': '001', '413': '302', '414': '001'} |
1 | public CheckClass(string[] m0) |
check000,check201,check004至少达成一种
大致看了下终于看懂了,fold的值要>13或者其他的一些情况才能输出flag
1 | private void CheckDora2() |
两张dora里有一个004fold++
1 | 109,312,009 |
1 | private void CheckDora1() |
如果中间为9则替换成0,同时fold++
同时计算m中字符串出现的次数
1 | 295,395 |
check000做了什么,问了gpt
这完全像麻将里的“胡牌检查”算法:
- 先找“雀头”(对子)
- 再检查剩下牌能否组成刻子或顺子
- 如果可以,全组合有效,返回
true
- 这三个必须满足一个才能胡牌
1 | 001-001 // 对子 |
check201找是不是有7个对子
fold+2
check004
当执行 Check004()
方法时,hashSet
和 hashSet2
都包含相同的元素,满足 hashSet.IsSubsetOf(hashSet2)
和 hashSet2.IsSubsetOf(hashSet)
条件,因此返回 true
。
1 | private void Check101() |
1 | this.SCounts = new List<string> { "001-002-003", "004-005-006", "001-002-003" }; |
出现次数为 2
的元素有 1 个 → 条件满足 → fold+1 → 打印 "101"
Check101()
是在判断 SCounts 里是否正好有一个对子(出现两次的组合),如果有就增加 fold
并打印 "101"
。
check102
1 | private void Check102() |
只要有一个start为0或end为1或9的就fold++
check103:
1 | private void Check103() |
判断当前元素是否以 “0” 开头,并且当前元素与下一个和下下一个元素相同
check202
1 | ^:表示匹配字符串的开始位置。 |
check203
1 | private void Check203() |
1 | 遍历 hashSet 中的每个卡片组合。例如,"101-102-103 104-105-106 107-108-109"。 |
check204,check205,check208, Check006都与203类似
check206
正则表达式的作用是检查字符串是否符合以下两种格式之一:
- **
^(\\d{3})-(\\1)-(\\1)$
**:表示一个字符串是形如"xxx-xxx-xxx"
的格式,其中xxx
为三位数字,并且第二和第三部分的数字必须和第一部分相同。- 例如:
"001-001-001"
,"123-123-123"
,"555-555-555"
。
- 例如:
- **
^(\\d{3})-(\\2)$
**:表示字符串是形如"xxx-yyy"
的格式,其中xxx
是三位数字,而yyy
是第二部分(\\2
)与第一部分相同。- 例如:
"123-123"
,"001-001"
,"009-009"
。
- 例如:
check207
1 | private void Check207() |
先查看是否start=0,如果所有元素都以 “0” 开头,且要么以 “1” 结尾,要么以 “9” 结尾 fold+=2
看到这心态略崩…
1 | private void Check301() |
check302
1 | \\d01-\\d01:形如 01-01 的格式。 |
check303:// 检查 m 数组中的首字母是否有两个不同的字符
1 | 经过 .Select((string s) => s[0]) 后,我们提取的首字母数组是 ['0', '0', '1', '1', '2']。 |
check601:// 检查 m 数组中的首字母是否只有一个不同的字符
剩下的缓缓
出题人说了是日本麻将牌,那么先读懂规则把…
日本麻将的牌由三门数牌(万/饼/索,1~9)和字牌(东南西北中白发)组成,常见基本和牌结构是“4个面子+1雀头”(面子为刻子或顺子),另有七对子、十三幺等特殊手型。计分依赖役种与宝牌(Dora)等加成。
16张牌经映射后进入校验类的构造函数:前14张是主体牌,后2张是“dora”牌。
入口:若任何一张是“000”(非法/空)直接失败并弹窗“百事无成,功亏一篑。”。然后处理两段 dora(见上),更新 fold 与 Counts。
基础门槛:若不满足“基本四面子一雀头”(Check000)、“七对子”(Check201)、“十三幺”(Check004)三者之一,则直接失败。也就是说,和牌必须是基本形或两大特殊形其一。
看了规则之后发现
这种役都能对上那些话,如水天一色,绿意盎然和清一色
在日本麻将中,宝牌是用于计算额外得分的牌,它通常与某些特定的牌(如“宝牌”或者“翻数”)相关。例如,如果一个玩家的胡牌包括宝牌,那么这个玩家的得分就会增加
宝牌数量 * 2
的分数。如果玩家在胡牌时能够“碰”或“杠”宝牌,那么这些宝牌的数量会被纳入最终得分计算中。例如,宝牌(Dora)增加得分的规则是每一张宝牌为玩家增加一番。假设玩家的手牌是一个平和(没有任何番型的基本胡牌)且有一张宝牌。例如玩家胡牌时有一张
"5"
,并且系统选择的宝牌也是"5"
,那么该玩家的得分会因宝牌的加入而增加番数。
Dora 加成与折算分 fold
CheckDora1:若主体牌中存在“第二位字符为‘9’”的牌就 fold++,且把该位改成‘0’后重算 Counts(相当于以某种指示器把牌当成另一值,具体机制不按规则书而是题目特设)。
随后 CheckDora2:若两张 dora 中存在“004”则 fold++。这些都是在加“额外分数”。(这部分是出题人自定义的“Dora 加番”,不完全等价于标准立直麻将 Dora 机制。)引用位置见构造与方法区域。
基础和牌结构(四面子一雀头)的判定
核心在三个方法:尝试所有可能的雀头(对子)后,余牌是否能被拆成“刻子/顺子”。这正是日麻“4面子+1雀头”的基本结构。 Check000
Check00
Check0
1
- Check000:枚举 Counts 里所有张数≥2的牌作为雀头,拷贝一份计数减去这对,调用 Check00 尝试把余牌拆完;若成功记录拆分列表 SCounts 并返回 true。
- Check00:循环用“优先刻子(3张相同)否则顺子(x,x+1,x+2,同花色)”的策略清空计数;顺子只允许数牌
这些拆分产生的面子字符串被放进 SCounts,后面的番种判定会基于它。
特殊和型(不走四面子一雀头)基础判定
- 七对子(Check201):所有牌都成对(Counts 值全为2),且先前并未生成 SCounts(即未按面子拆分),则判定为七对子成立。
Check201
- 十三幺(Check004):检查14张牌的“集合”恰好等于固定的13种幺九/字牌集合(1/9万饼索 + 东南西北中白发中的组合),等价于14张由13种各1张加任意其中1张作将。
番种/役种的具体判定(都建立在“已经是可和型”基础上)
通过基础门槛后,会用一系列 Check1xx/2xx/3xx/6xx 给 fold 加分,或直接判定为某个“特殊役”并弹窗返回,fold>13或者通过那些特殊役
Check001:绿一色(“水天一色,绿意盎然。”)。要求 SCounts 里每个面子都只能是 202/203/204/206/208/006(即发/索中若干绿牌)的对/刻/顺之一,对应日麻“绿一色”。
面子:顺子、刻子、杠子的统称。
Check002:清老头(“老练清和,智胜难关。”)。要求无字牌且每张都是1或9(末位为1或9),对应“清老头”。 清老头指的是玩家的胡牌全部由“1”和“9”组成,且没有其他任何数字牌。
Check003:字一色(“天机独运,字字生辉。”)。要求至少有字牌,且所有牌第一位字符相同且为‘0’,即全是字牌。对应“字一色”。
Check004:十三幺(“运筹帷幄,国士之风。”),已在上面解释。
Check005:九莲宝灯(“华灯璀璨,九运亨通。”)。要求清一色且张数分布恰为 1112345678999x(x任意同门一张),代码里根据门别分别要求 1和9至少3张,2~8各至少1张。对应“九莲宝灯”。
Check006:四喜(“吉星高照,喜从天降。”)。枚举了四风(001~004)中“3副刻子+1对”或“四副刻子”的模式(小四喜/大四喜)。
Check007:大三元(“三元及第,一品当朝。”)。要求 005/006/007 各一副刻子(白/发/中三元)。
其他“加分役”示例:
- Check101:若 SCounts 中某个面子字符串恰好出现两次(同面子重复一次)则 fold++,相当于“一杯口”风味。
- Check102:所有牌都不是字牌且不含1/9,即“断幺九”风味(全是中张),fold++。
- Check103:存在字牌的刻子(连续三张相同的字牌),fold++。
- Check202:混全带幺九风味(每个面子都带幺九或字牌,且手牌里含有字牌),fold+=2。
- Check203:一气通贯(同门 123/456/789 三顺齐全),fold+=2。
- 还有 Check204~Check303、Check601 等,分别给不同条件加分或清一色加高分等。
最后反正是满足得输入做了md5加密为最终答案,我们需要由最终的True反推可行的输入去做MD5
烦就烦在不一定所有的役可行,而且判定复杂头大….,外部的ID和内部ID容易搞混,真实屎完了
1 | {'000': '101', '001': '202', '002': '209', '003': '109', '004': '204', '005': '109', '007': '307', '008': '304', '009': '004', '010': '303', '011': '304', '012': '005', '014': '203', '015': '003', '016': '305', '017': '208', '019': '206', '102': '006', '103': '208', '106': '007', '108': '002', '109': '209', '110': '003', '111': '308', '112': '307', '113': '301', '114': '301', '203': '205', '207': '201', '208': '306', '210': '206', '212': '204', '214': '007', '303': '306', '304': '101', '305': '302', '306': '006', '307': '309', '308': '295', '309': '203', '311': '201', '312': '004', '313': '207', '314': '308', '401': '395', '403': '303', '404': '207', '405': '202', '406': '005', '407': '002', '409': '309', '411': '001', '413': '302', '414': '001'} |
我们发现10x只有101和109,少了7张牌,其它的2xx和3xx都是各有两张,东南西北中发也是各有两张
需要刻字的我们直接pass,check007,006,005,002,001都不行,还要注意之前True的两个012,406是被禁用的(也就是005)
1 | {'000': '101', '001': '202', '002': '209', '003': '109', '004': '204', '005': '109', '007': '307', '008': '304', '009': '004', '010': '303', '011': '304', '014': '203', '015': '003', '016': '305', '017': '208', '019': '206', '102': '006', '103': '208', '106': '007', '108': '002', '109': '209', '110': '003', '111': '308', '112': '307', '113': '301', '114': '301', '203': '205', '207': '201', '208': '306', '210': '206', '212': '204', '214': '007', '303': '306', '304': '101', '305': '302', '306': '006', '307': '309', '308': '295', '309': '203', '311': '201', '312': '004', '313': '207', '314': '308', '401': '395', '403': '303', '404': '207', '405': '202', '407': '002', '409': '309', '411': '001', '413': '302', '414': '001'} |
十三幺也不行了check004,字一色也不行check003,
我们发现符合的场景最简单的就是7对子,但是发现了题目的BUG
就是说当7对子情况下,拆面子失败check000会return false,scounts为空,去执行check201,这时check001可以直接返回true,因为scounts是空的
接下来就是算分
1 | if (new CheckClass(array6).Check()) |
是按值进行排序,
TSCTF-J{ba5c5c1e0ff96f0485d5fd00ddc31077}
照理说这个flag能出,但是错误了
询问出题人,才发现这是一个bug,没有在check001之前做校验
正确的思路应该是算分来获得flag
首先验证了下7对子是无法到达13分的,最多能到12分
高分叠加方案:
check102不以0开头,19结尾,1分
check301(7对子,但是可以拆出面子) 3分
check601,6分
此时还有dora没算
仔细阅读规则发现有部分牌如295(其实就是205)
可以加1分
两个004可以加2分
这样刚好13分
1 | # 打开文件并读取每行内容 |
勉强做出来了花费了5+个小时时间,中间学了下日本麻将….有点搞心态的
iPlayApple
苹果逆向题
解压,看到一个reverse,IDA点进去看看
果然发现了相关信息
sub_100007584
的逻辑是:
- 获取用户在
textField
和finField
两个输入框的内容。 - 把这两个字符串传给验证函数
sub_1000040EC
(内部可能用CryptoHelper
对比/解密)。 - 根据结果决定弹出成功提示还是失败提示。
- 用
UIAlertController
显示在界面上。
有个16b6aa2468414776d9168777f9ea281ee79e5f60a06278319dde7661d912e3a6
和amazing_ios_rev! (16字节)可能是密钥
简化伪代码:
- s1 = textField.text
- s2 = finField.text
- ctx = get_flag() // 栈对象
- ctx.crypto = CryptoHelper()
- ctx.salt = “amazing_ios_rev!”
- ctx.targetHex = “16b6aa2468414776d9168777f9ea281e…” // 看起来是 SHA256 的十六进制
- ok = runCheck(ctx, s1, s2) // 由下游函数组合
- if ok: 弹成功提示(可能还拼装显示flag)
- else: 弹失败提示
jinrush40EC后比较重要的6C63这个方法,里面包含所用的加密方法
1 | v30 = type metadata accessor for AES.GCM.SealedBox |
这里取 Swift Crypto 库里的类型元数据:AES.GCM.SealedBox
、SymmetricKey
、String.Encoding
。
说明这个函数会用到 AES-GCM 来处理数据。
1 | v33 = a3; |
参数 (a3,a4) 是一个 Swift String(也就是调用 sub_1000040EC 时传入的 内部常量 “amazing_ios_rev!” 或者 big hex 串)。
这里把它转成 UTF-8 的 Data,作为 SymmetricKey 的原始 key material。
1 | sub_100006C30(a1,a2); |
首先发现这个12字节的的有效信息
Nonce/IV – GCM 的初始向量,通常是 12 字节(96bit)。
可能就是这个头部
tag是16字节
想到之前的iv是拼接的,tag可能也是拼接的,简单试了下是505c588ff6f4d5f1a76d20e20c9606ec
最后爆破即可,因为是一个SHA256,且16b6aa2468414776d9168777f9ea281ee79e5f60a06278319dde7661d912e3a6没用上
1 | import hashlib |
[!] Found match: i0S}
TSCTF-J{GCMmode_A3S_in_i0S}
iPlayBingo
WASM文件是WebAssembly的二进制格式文件,旨在通过高效的二进制指令在现代浏览器中运行。它是由高级语言(如C、C++、Rust等)编译生成的低级字节码格式,具有高性能、可移植性和安全性。
githhub用这个工具搞出来c的代码
1 | ./wasm2c answerChecker.wasm -o main.c |
随便看看就发现了类似tea的算法
根据这个文章
可以用gcc 编译c代码,然后把生成的.o文件拖进去分析,并且网页可以动调
可以发现密文
enc {0x5D8FE6E0,0xBB42A5B1,0xFA761D81,0x32CC9FCB,0xFD9BE445,0x23935C4,0xEAF80FBE,0xE52E36D3}
这段就是把32 字节输入当成 **4 个块(每块 8 字节=2×u32)处理,并且**对每个块做三段 ARX(加/减、异或、移位)轮变换**。每段都是 TEA/XTEA 的双字加密,只是换了点细节和常量。跑完三段以后,把结果写回内存。
1 | n31 = 31; |
key = [0x01234567, 0x89abcdef, 0xdeadbeef, 0xbabec0de]
来自
1 | n33 = 0; |
1 | for (i = 0; i != 32; ++i) { |
1 |
|
TSCTF-J{Wh4t_@_R3verse_Ma5ter!!}
这里最大的坑在于第一个do_while是v28–;后缀自减,别看错了,看错浪费我很长时间
iPlayMaze
迷宫题
迷宫在off_405200,指向unk_405000,每8位1个有效值
1 | enc = [0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0] |
1 | 512 |
结果是错的
起点是0,终点是409
然后发现TLS中藏东西了
1 | void *__stdcall TlsCallback_0(int a1, int a2, int a3) |
这是TLS回调在进程初始化时对一段代码做XOR解密/修补。a2==1时(进程附加)先VirtualProtect把sub_401A60附近改成可写,再用v6[0..140]依次与(sub_401A60+176+i)当前字节做异或,回填到同一地址,等于把那141字节“解密”为真正要执行的代码。静态反编译看到的是“密文”,运行后才是“明文”。若某些逻辑(含迷宫判定/校验)在这段区域里
这块地址是我们所需关注的
其实还有反调试,我直接用ScyllHide过了
程序存在双迷宫块:0x405000与0x405238,并非固定使用单块;每当读入一个新按键(索引自增)时,相位翻转,off_405200随之在两块之间切换
因此求解时状态应为(位置,相位)的二维状态机而不是仅512格:相位每处理一字符翻转一次;或静态打补丁固定off_405200始终指向0x405000(或0x405238)即可退化为单块迷宫
不能只看512个格子,要看1024个复合状态
写脚本的时候发现了原题是dasctf上的一个,找到脚本直接开抄了,别跟最短路径搞错了,这个是迷宫题
1 | maze = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] |
这是求单迷宫的,如果双迷宫就是
1 | map1 = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] |
1 | maze = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] |
1 | from sys import setrecursionlimit |
这个迷宫感觉不大对….