Loading... # SmileyCTF 2025 wp 比赛前面一度打到3rd,但后面实在干不动了,web队友他们爆了,听说和国内很不一样。我这边re也是巨离谱,简单的前3题队友直接秒了,后面我做了俩中等难度,剩下三道题,一道8解,两道0解,也是离谱,完全没搞懂咋做的 先写下做出来的两道题wp,还是挺有可以学习的点 ## DNA 看到给的vm.dna我就知道是个虚拟机题目,反编译出pyc果然如此 需要做的很清楚,就是把每个指令打印出来,看输入的数据到底去做了什么,直接喂给gemini让他先帮我分析一波,然后我手动print大法把每个指令和值打印出来(跑代码时要注意python3.10,不然marshal.loads出来的不对) ~~~python import marshal import sys # 初始化虚拟机状态 s = [] # 栈 m = {} # 内存 nm = {'A': 0, 'T': 1, 'G': 2, 'C': 3} # DNA 碱基到整数的映射 # 包含混淆代码的列表 unlucky = [b'\x8coooooooooooonooolooo,ooo\x9cSooo\x06o\x12o\x1bo\x0bnvo\x13o\x0bmSo\x1bo\x0blvo\x13o\x0bnSo\x1bo\x0bkvo\x13o\x0blSo\x1bo\x0bmvo\x13o\x0bkSo\x13o\x0eo\x0bo<oFj!\xb5n;\xb5n.\xb5n(\xb5n,\xc6n\xb5m\x01\x02\xc6n\xb5l\x1b\x02\x1f\xc6o\x1deooo\x95fS\x1a\x01\x03\x1a\x0c\x04\x16Q\xb5h\x1a\x01\x03\x1a\x0c\x04\x16booo\x9ccoookmcncncncngn', b'\x96uuuuuuuuuuuuruuu}uuu6uuu\x86\x11uuu\x11t\x08u\x11w\x08t\x11v\x08w\x11q\x11p\xf1u\tu1u\xf6t\x08v\tu\tt\tw\x13v1u(n\x08q\x01u\x01t\x01w\xd5v\xd4u\xf6t\xf6t1u(e)w\x08p\x08s\tv\tspulu\x01w\tq\tpluluMuvuIu\x04i\x04g\tv\x14w\x11u&u\\s;\xafq426!\xafq!642\xafq6!24\x16tuuuuuuuuuuuwuuusuuu&uuu\x86ouuu\x1cu\tu(|\x08t\tt\x01u\x01t\xd5w\xd4u\xf6t\xe6w\x04w&u\\u\xdcv\xafv\x06\x00\x18\xafw\x1b\x18\xafs\x03\x14\x19\x00\x10\x06\xdcw\xafw[E\xaft\x16\xdcu\x07xuuu\x8f|I\x00\x1b\x19\x00\x16\x1e\x0cK\xafr\x00\x1b\x19\x00\x16\x1e\x0cnuuu\x86wuuuou\x8fh\x00\x1b\x19\x00\x16\x1e\x0c*G[I\x19\x1a\x16\x14\x19\x06K[I\x11\x1c\x16\x01\x16\x1a\x18\x05K\xdcq\xaf|\x10\x1b\x00\x18\x10\x07\x14\x01\x10\xafs\x06\x1a\x07\x01\x10\x11\x07}uuu\xafq\x1e\x10\x0c\x06\xdcr\xafw\x06D\xafw\x06G\xafw\x06F\xafv\x01\x18\x05\xaft\x06\xaft\x1c\x07yuuu\x07xuuu\x07xuuu\x07{uuu\x07zuuucuuu\x86guuuqwqtqt{t{tmtotw\x8a}w', b"\x8aiiiiiiiiiiiihiiiniiijiii\x9a/iii\x1di\rh\xeah\xe0i\xe1i\xc9h\x1di\rk\xeah\xc9k\rj\rm\xedi\x1dj\xc9m\xc8i\xc8k\xc8hhi.i\xeei\x0fh\rl\ro\xeda\ro\x1dl\xeaj\x14i\x15i\x1dj\xeah\x08j\ri:i@n'\xb3o\x1b\x08\x07\r\x06\x04\xb3`\x0f\x1c\x07\n\x1d\x06\x06\x05\x1a\nkiiiiiiiiiiikiiikiii:iii\x9aaiii\x15i\x15h(i:i@h'\xc0i\xc0k\xb3h\x11\xb3h\x10\x1bliii\x1bliii\x93`U\x1c\x07\x05\x1c\n\x02\x10W\xb3n\x1c\x07\x05\x1c\n\x02\x10Miii\x9akiiiai\x93r\x1c\x07\x05\x1c\n\x02\x106ZGU\x05\x06\n\x08\x05\x1aWGU\x05\x08\x04\x0b\r\x08W\niiiiiiiiiiiiiiiijiiiiiii\x9aCiii\x0ci3h\ri3k\xeei\xeeh\x0fk\rh\rk\xeda3j\xeei\x0fh\rj\rm\xeda3m\xeeimi3l:i@l\x93s\x1c\x07\x05\x1c\n\x02\x106ZGU\x05\x06\n\x08\x05\x1aWG\x1c\x07\x05\x1c\n\x02\x10\nkiiiiiiiiiiimiiiliiiziii\x9a-iii\x1di\xeai\xc9h\x15h\xc8hhi\x1dk\rh\xeah\x14k\xe1h\xc9j\x15k\xc8hhi\x1dm\rk\xeah-i4e\x14j\x15h\x15k\x15jpipi\x15i\rh\x15jpiUi\x18z\ri:i@j'\xb3m(*.=\x80miii\xc0l\xb3l\x1a\x1c\x19\x0c\x1b\xb3a66\x00\x07\x00\x1d66\xb3m\x05\x00\x1a\x1d\xb3n\x1a\x01\x1c\x0f\x0f\x05\x0c\xb3l\x1b\x08\x07\x0e\x0c\xc0m\xb3m\x1a\x0c\x05\x0f\xb3n\x04\x08\x19\x19\x00\x07\x0e\xb3m\x02\x0c\x10\x1a\xb3h\x00\xc0k\xb3`66\n\x05\x08\x1a\x1a66\xb3h\x1b\x1bliii\x1b`iii\x1bciiiOiii\x9aeiiiehahcheh\x7fhm\x96\x93J\x1c\x07\x05\x1c\n\x02\x106ZGU\x05\x06\n\x08\x05\x1aWG\x1c\x07\x05\x1c\n\x02\x10G66\x00\x07\x00\x1d66\nkiiiiiiiiiiiliiiliiiziii\x9a;iii\x1di\rh\xeah\x14k\x1di\rk\xeah\x14j`i\x15k\xc9h\rm\xc8h\x14m\x1dk\xeei\x0fh\rl\ro\xeda\x15j\xc9j\x15m\xc8h\xc9m\xc8i\ri\rn\xeckpi-i\xeah\xeah\x1bA\x1dl\xeai\xc9o\xe1i\xc8h:i\x18`@a'\x1bkiii\xb3n\x01\x08\x1a\x01\x05\x00\x0b=\x80Iiii\nhiiiiiiiiiiikiiimiiiZiii\x9auiii\xe8i\x15i4`\x14h\x15h\x1di\xe1i\xeah\x02k?ihi\x18k\ri:i@h'\xc0h\xb3j\x06\x1b\r\xc0k\xb3kGY\x1bniii\xc0h\xb3j\x02\x0c\x10\x1bliii\x1b`iii\x1bciii[iii\x9amiiik\xe9si\x93P\x1c\x07\x05\x1c\n\x02\x106ZGU\x05\x06\n\x08\x05\x1aWG\x1c\x07\x05\x1c\n\x02\x10G66\x0e\x0c\x1d\x00\x1d\x0c\x0466GU\x05\x06\n\x08\x05\x1aWGU\x0e\x0c\x07\x0c\x11\x19\x1bW\x80hiii\xc0n\xb3c66\x00\x04\x19\x06\x1b\x1d66\xb3`\x1b\x08\x07\r\x0b\x10\x1d\x0c\x1a\xb3j\x08\x05\x05\xb3o\x1a\x01\x08[\\_\xb3o\r\x00\x0e\x0c\x1a\x1d\x1bziii\xb3b66\x0e\x0c\x1d\x00\x1d\x0c\x0466\xc0l\x1bpiii\x1bBiii\xb3m\x01\x05\x00\x0b\xb3m\x1b\x05\x00\x0b\xb3h\x0b\xc0h\x1bwiii\x1bCiii\x1b`iii\x1bciiiDiii\x9agiiiahahkhchAhehk\x94\x93O\x1c\x07\x05\x1c\n\x02\x106ZGU\x05\x06\n\x08\x05\x1aWG\x1c\x07\x05\x1c\n\x02\x10G66\x0e\x0c\x1d\x00\x1d\x0c\x0466\xc0o\xb3a66\x07\x08\x04\x0c66\xb3c66\x04\x06\r\x1c\x05\x0c66\xb3e66\x18\x1c\x08\x05\x07\x08\x04\x0c66\x1b}iii\x1b\\iii\xb3d66\n\x05\x08\x1a\x1a\n\x0c\x05\x0566\x1bliii\xc0h\x1bviii\x1bSiii\x1b`iii\x1bciiiLiii\x9aoiiiaigh}n\x1bciii\xc0o\x1bYiii\xb3m\x1a\x0c\x0c\r\xb3o\x1b\x0c\r\x1c\n\x0c\xb3k\x07\x04\xb3o\x1f\x08\x05\x1c\x0c\x1a\xb3m\r\x00\n\x1d\xc0h\x1bciii\x1bliii\x1b+iii\x1b`iii\x1bciiiHiii\x9aaiiiakwh}hey", b'\x82aaaaaaaaaaaacaaagaaa"aaa\x92]aaa&a\x05`\x05c\xe5a\x05c\x15a\xe2b\x1ca&a\x05b\x05e\xe5a\x05e\x15`\x1da\x05d\xece\x1c`\x15c\x05g\x15`\x15b\xe2`\xfaa\x05f\xfcb\xe2``a\x05a2aHi/\x02aaaaaaaaaaaaaaaabaaaaaaa\x92Iaaa\x04a;`\x05a;c\xe6a\x07`\x05`\x05c\xe5i;b\xe6a\x07`\x05b\x05e\xe5i;e\xe6aea;d2aHd\x9bt\x14\x0f\r\x14\x02\n\x18>UO]\r\x0e\x02\x00\r\x12_O,,\x02eaaaaaaaaaaaeaaagaaaraaa\x92saaa\x15a\xe2a\xc1`\x1da\x1d`\x1dc\x1db\xc0e2aH`/\xc8c\xbbd\x12\x14\x11\x04\x13\xbbf>>\x0f\x04\x16>>\xc8e\xbbb\x02\r\x12\xbbe\x0f\x00\x0c\x04\xbbd\x03\x00\x12\x04\x12\xbbb\x05\x02\x15\xc8`\xbbh>>\x02\r\x00\x12\x12>>\xc8a\x9bh]\x14\x0f\r\x14\x02\n\x18_\xbbf\x14\x0f\r\x14\x02\n\x18Zaaa\x92caaas`\x9b|\x14\x0f\r\x14\x02\n\x18>UO]\r\x0e\x02\x00\r\x12_O,,O>>\x0f\x04\x16>>\x02`aaaaaaaaaaafaaadaaa~aaa\x92\x05aaa\x15a\xe2a\x0b`\x1d`\x08a\x1dc\xc5`\xef`\x1cb\x15c\x1db\xc1b\xc0a\xe2`\x1ce\x1de\x05a\x05a\x05`\xe4bxa\x1de\x05c\x05a\x05`\xe4bxava\x1ce\x15e\x15d\x1db\xc1g\xc0a\xe2`\xe2`%a<k=c\x1cd\x1cg\x1de\x1ddxa\x1db\x1dg]a\x10D\x1db2aHb/\x88caaa\x88`aaa\xc8f\x13gaaa\xbbi>>\x02\x00\r\r>>\xbbe\r\x08\x12\x15\xbbg\x17\x00\r\x14\x04\x12\xbbh\x04\x0f\x14\x0c\x04\x13\x00\x15\x04\xbbg\x12\x0e\x13\x15\x04\x05\xbbe\n\x04\x18\x12\xc8f\x13haaa\xbbe\x00\x13\x06\x12\xbbg\n\x16\x00\x13\x06\x12\xbbi\x08\x0f\x12\x15\x00\x0f\x02\x04\xbbe\x17\x00\r\x12\xbb`\x08\xbb`\n\x13laaa\x13naaa\x13qaaa\x13paaa_aaa\x92maaas`m`}`y`o`e`\x9b\x7f\x14\x0f\r\x14\x02\n\x18>UO]\r\x0e\x02\x00\r\x12_O,,O>>\x02\x00\r\r>>\xc8g\xbbi>>\x0f\x00\x0c\x04>>\xbbk>>\x0c\x0e\x05\x14\r\x04>>\xbbm>>\x10\x14\x00\r\x0f\x00\x0c\x04>>\x13faaa\x13yaaa\xbbl>>\x02\r\x00\x12\x12\x02\x04\r\r>>\x13naaa\x13naaa\x13laaa\x13qaaa\x13paaa[aaa\x92gaaaiam`ub\xbbc,,\x02aaaaaaaaaaaaaaaa`aaa!aaa\x92maaa\x04a;`\x05a;c\x05`2aHc\x9bt\x14\x0f\r\x14\x02\n\x18>UO]\r\x0e\x02\x00\r\x12_O,%/\xc8b\x13Iaaa\x13Haaa\x13Kaaa\x13naaa\x13naaa\x13naaa\x13qaaa\x13paaa\'aaa\x92eaaaiae`\xbbc,%\xc8`\xbbh\x0c\x04\x15\x00\x02\r\x00\x12\x12\x9b@\x06\r\x0e\x03\x00\r\x12IH:F\x0f\x14\x02\r\x04\x0e\x15\x08\x05\x04>\x0c\x00\x11F<A\\A,%I\x9b`H\xc8e\xbbe\x15\x18\x11\x04\xbbe\x05\x08\x02\x15\xbbe\x04\x19\x04\x02\xbbc\x0f\x0c\xc8c\x13Laaa\x13Saaa\x13naaa\x13naaa\x13qaaa\x13paaaVaaa\x92gaaaqbumyb'] # 将 DNA 序列转换为整数。这等效于将一个四进制数转换为十进制数。 trans = lambda dna_seq: sum(nm[c] << (2 * i) for i, c in enumerate(dna_seq)) # --- 主程序开始 --- # 检查命令行参数 if len(sys.argv) != 2: print(f"Usage: {sys.argv[0]} <dna_file>") sys.exit(1) # 读取 DNA 代码文件 try: with open(sys.argv[1], 'r') as f: code = f.read().strip() except FileNotFoundError: print(f"Error: File '{sys.argv[1]}' not found.") sys.exit(1) # 获取并验证用户输入的 flag flag = input("> ").encode() if len(flag) != 56: print("WRONG!") exit() if flag[:6] != b'.;,;.{': print("WRONG!") exit() if flag[-1] != 125: # ord('}') print("WRONG!") exit() # 提取 flag 的核心部分并加载到内存 flag_core = flag[6:-1] for i in range(len(flag_core)): m[640 + i] = flag_core[i] # 初始化程序计数器 (Program Counter) pc = 0 mul_list = [] cmp_list = [] # 虚拟机主循环 while pc < len(code): # 解码指令和操作数 # pri 是操作码 (opcode), pro 是操作数 (operand) op_slice = code[pc: pc + 2] arg_slice = code[pc + 2: pc + 12] pri = trans(op_slice) pro = trans(arg_slice) # --- 指令分派 --- if pri == 0: # PUSH: 将操作数压入栈 s.append(pro) print(f"push {pro}") pc += 12 elif pri == 1: # POP: 弹出一个值 if not s: raise Exception("Stack underflow") print(f"pop {s[-1]}") s.pop() pc += 2 elif pri == 2: # LOAD: 从内存加载值到栈 if pro not in m: raise Exception(f"Uninitialized memory access at {pro}") print(f"push {m[pro]} ({pro})") s.append(m[pro]) pc += 12 elif pri == 3: # STORE: 将栈顶值存入内存 if not s: raise Exception("Stack underflow") print(f"mov m[{pro}], {s[-1]}") m[pro] = s.pop() pc += 12 elif pri == 4: # ADD: 加法 if len(s) < 2: raise Exception("Stack underflow") b, a = s.pop(), s.pop() print(f"pop {b} + pop {a} + push {a+b} (add)") s.append(a + b) pc += 2 elif pri == 5: # SUB: 减法 if len(s) < 2: raise Exception("Stack underflow") print(f"pop {b} + pop {a} + push {a - b} (sub)") b, a = s.pop(), s.pop() s.append(a - b) pc += 2 elif pri == 6: # MUL: 乘法 if len(s) < 2: raise Exception("Stack underflow") b, a = s.pop(), s.pop() print(f"pop {b} + pop {a} + push {a * b} (mul)") mul_list.append(b) s.append(a * b) pc += 2 elif pri == 7: # MOD: 取模 if len(s) < 2: raise Exception("Stack underflow") b, a = s.pop(), s.pop() print(f"pop {b} + pop {a} + push {a % b} (mod)") if a == 0: raise Exception("Division by zero") s.append(a % b) pc += 2 elif pri == 8: # EQ: 比较是否相等 if len(s) < 2: raise Exception("Stack underflow") b, a = s.pop(), s.pop() print(f"pop {b} + pop {a} + push {a==b} (cmp)") cmp_list.append(b) s.append(1 if a == b else 0) pc += 2 elif pri == 9: # JMP: 无条件跳转 pc = pro print(f"jmp {pc}") elif pri == 10: # JIF: 如果栈顶为 1 则跳转 if not s: raise Exception("Stack underflow") print(f"jmp {pro} if {s[-1]}==1 else pc+=12") if s.pop() == 1: pc = pro else: pc += 12 elif pri == 11: # JIN: 如果栈顶不为 1 则跳转 if not s: raise Exception("Stack underflow") print(f"jmp {pro} if {s[-1]}!=1 else pc+=12") if s.pop() != 1: pc = pro else: pc += 12 elif pri == 12: # OUT: 输出字符 if not s: raise Exception("Stack underflow") print(chr(s.pop()), end='') pc += 2 elif pri == 13: # 动态代码执行 if not s: raise Exception("Stack underflow") key = s.pop() def f(): return print("marshal xor", key) # 解密并加载字节码 decrypted_code = bytes([b ^ key for b in unlucky.pop(0)]) f.__code__ = marshal.loads(decrypted_code) f() # 执行动态生成的代码 pc += 2 elif pri == 14: # SWAP: 交换碱基映射 if len(s) < 2: raise Exception("Stack underflow") b, a = chr(s.pop()), chr(s.pop()) # 注意,这里应该是字符 print(b, a) if a not in nm or b not in nm: raise Exception(f"Invalid characters for nm swap: {a}, {b}") nm[a], nm[b] = nm[b], nm[a] pc += 2 elif pri == 15: # HALT: 停止执行 break else: raise Exception(f"Unknown instruction: {pri}") print(mul_list) print(cmp_list) ~~~ 需要关注的点是opcode为13时做了一个异或,然后marshal.loads转为codetype类,因此该key可以爆破 ~~~python import marshal import types unlucky = [b'\x8coooooooooooonooolooo,ooo\x9cSooo\x06o\x12o\x1bo\x0bnvo\x13o\x0bmSo\x1bo\x0blvo\x13o\x0bnSo\x1bo\x0bkvo\x13o\x0blSo\x1bo\x0bmvo\x13o\x0bkSo\x13o\x0eo\x0bo<oFj!\xb5n;\xb5n.\xb5n(\xb5n,\xc6n\xb5m\x01\x02\xc6n\xb5l\x1b\x02\x1f\xc6o\x1deooo\x95fS\x1a\x01\x03\x1a\x0c\x04\x16Q\xb5h\x1a\x01\x03\x1a\x0c\x04\x16booo\x9ccoookmcncncncngn', b'\x96uuuuuuuuuuuuruuu}uuu6uuu\x86\x11uuu\x11t\x08u\x11w\x08t\x11v\x08w\x11q\x11p\xf1u\tu1u\xf6t\x08v\tu\tt\tw\x13v1u(n\x08q\x01u\x01t\x01w\xd5v\xd4u\xf6t\xf6t1u(e)w\x08p\x08s\tv\tspulu\x01w\tq\tpluluMuvuIu\x04i\x04g\tv\x14w\x11u&u\\s;\xafq426!\xafq!642\xafq6!24\x16tuuuuuuuuuuuwuuusuuu&uuu\x86ouuu\x1cu\tu(|\x08t\tt\x01u\x01t\xd5w\xd4u\xf6t\xe6w\x04w&u\\u\xdcv\xafv\x06\x00\x18\xafw\x1b\x18\xafs\x03\x14\x19\x00\x10\x06\xdcw\xafw[E\xaft\x16\xdcu\x07xuuu\x8f|I\x00\x1b\x19\x00\x16\x1e\x0cK\xafr\x00\x1b\x19\x00\x16\x1e\x0cnuuu\x86wuuuou\x8fh\x00\x1b\x19\x00\x16\x1e\x0c*G[I\x19\x1a\x16\x14\x19\x06K[I\x11\x1c\x16\x01\x16\x1a\x18\x05K\xdcq\xaf|\x10\x1b\x00\x18\x10\x07\x14\x01\x10\xafs\x06\x1a\x07\x01\x10\x11\x07}uuu\xafq\x1e\x10\x0c\x06\xdcr\xafw\x06D\xafw\x06G\xafw\x06F\xafv\x01\x18\x05\xaft\x06\xaft\x1c\x07yuuu\x07xuuu\x07xuuu\x07{uuu\x07zuuucuuu\x86guuuqwqtqt{t{tmtotw\x8a}w', b"\x8aiiiiiiiiiiiihiiiniiijiii\x9a/iii\x1di\rh\xeah\xe0i\xe1i\xc9h\x1di\rk\xeah\xc9k\rj\rm\xedi\x1dj\xc9m\xc8i\xc8k\xc8hhi.i\xeei\x0fh\rl\ro\xeda\ro\x1dl\xeaj\x14i\x15i\x1dj\xeah\x08j\ri:i@n'\xb3o\x1b\x08\x07\r\x06\x04\xb3`\x0f\x1c\x07\n\x1d\x06\x06\x05\x1a\nkiiiiiiiiiiikiiikiii:iii\x9aaiii\x15i\x15h(i:i@h'\xc0i\xc0k\xb3h\x11\xb3h\x10\x1bliii\x1bliii\x93`U\x1c\x07\x05\x1c\n\x02\x10W\xb3n\x1c\x07\x05\x1c\n\x02\x10Miii\x9akiiiai\x93r\x1c\x07\x05\x1c\n\x02\x106ZGU\x05\x06\n\x08\x05\x1aWGU\x05\x08\x04\x0b\r\x08W\niiiiiiiiiiiiiiiijiiiiiii\x9aCiii\x0ci3h\ri3k\xeei\xeeh\x0fk\rh\rk\xeda3j\xeei\x0fh\rj\rm\xeda3m\xeeimi3l:i@l\x93s\x1c\x07\x05\x1c\n\x02\x106ZGU\x05\x06\n\x08\x05\x1aWG\x1c\x07\x05\x1c\n\x02\x10\nkiiiiiiiiiiimiiiliiiziii\x9a-iii\x1di\xeai\xc9h\x15h\xc8hhi\x1dk\rh\xeah\x14k\xe1h\xc9j\x15k\xc8hhi\x1dm\rk\xeah-i4e\x14j\x15h\x15k\x15jpipi\x15i\rh\x15jpiUi\x18z\ri:i@j'\xb3m(*.=\x80miii\xc0l\xb3l\x1a\x1c\x19\x0c\x1b\xb3a66\x00\x07\x00\x1d66\xb3m\x05\x00\x1a\x1d\xb3n\x1a\x01\x1c\x0f\x0f\x05\x0c\xb3l\x1b\x08\x07\x0e\x0c\xc0m\xb3m\x1a\x0c\x05\x0f\xb3n\x04\x08\x19\x19\x00\x07\x0e\xb3m\x02\x0c\x10\x1a\xb3h\x00\xc0k\xb3`66\n\x05\x08\x1a\x1a66\xb3h\x1b\x1bliii\x1b`iii\x1bciiiOiii\x9aeiiiehahcheh\x7fhm\x96\x93J\x1c\x07\x05\x1c\n\x02\x106ZGU\x05\x06\n\x08\x05\x1aWG\x1c\x07\x05\x1c\n\x02\x10G66\x00\x07\x00\x1d66\nkiiiiiiiiiiiliiiliiiziii\x9a;iii\x1di\rh\xeah\x14k\x1di\rk\xeah\x14j`i\x15k\xc9h\rm\xc8h\x14m\x1dk\xeei\x0fh\rl\ro\xeda\x15j\xc9j\x15m\xc8h\xc9m\xc8i\ri\rn\xeckpi-i\xeah\xeah\x1bA\x1dl\xeai\xc9o\xe1i\xc8h:i\x18`@a'\x1bkiii\xb3n\x01\x08\x1a\x01\x05\x00\x0b=\x80Iiii\nhiiiiiiiiiiikiiimiiiZiii\x9auiii\xe8i\x15i4`\x14h\x15h\x1di\xe1i\xeah\x02k?ihi\x18k\ri:i@h'\xc0h\xb3j\x06\x1b\r\xc0k\xb3kGY\x1bniii\xc0h\xb3j\x02\x0c\x10\x1bliii\x1b`iii\x1bciii[iii\x9amiiik\xe9si\x93P\x1c\x07\x05\x1c\n\x02\x106ZGU\x05\x06\n\x08\x05\x1aWG\x1c\x07\x05\x1c\n\x02\x10G66\x0e\x0c\x1d\x00\x1d\x0c\x0466GU\x05\x06\n\x08\x05\x1aWGU\x0e\x0c\x07\x0c\x11\x19\x1bW\x80hiii\xc0n\xb3c66\x00\x04\x19\x06\x1b\x1d66\xb3`\x1b\x08\x07\r\x0b\x10\x1d\x0c\x1a\xb3j\x08\x05\x05\xb3o\x1a\x01\x08[\\_\xb3o\r\x00\x0e\x0c\x1a\x1d\x1bziii\xb3b66\x0e\x0c\x1d\x00\x1d\x0c\x0466\xc0l\x1bpiii\x1bBiii\xb3m\x01\x05\x00\x0b\xb3m\x1b\x05\x00\x0b\xb3h\x0b\xc0h\x1bwiii\x1bCiii\x1b`iii\x1bciiiDiii\x9agiiiahahkhchAhehk\x94\x93O\x1c\x07\x05\x1c\n\x02\x106ZGU\x05\x06\n\x08\x05\x1aWG\x1c\x07\x05\x1c\n\x02\x10G66\x0e\x0c\x1d\x00\x1d\x0c\x0466\xc0o\xb3a66\x07\x08\x04\x0c66\xb3c66\x04\x06\r\x1c\x05\x0c66\xb3e66\x18\x1c\x08\x05\x07\x08\x04\x0c66\x1b}iii\x1b\\iii\xb3d66\n\x05\x08\x1a\x1a\n\x0c\x05\x0566\x1bliii\xc0h\x1bviii\x1bSiii\x1b`iii\x1bciiiLiii\x9aoiiiaigh}n\x1bciii\xc0o\x1bYiii\xb3m\x1a\x0c\x0c\r\xb3o\x1b\x0c\r\x1c\n\x0c\xb3k\x07\x04\xb3o\x1f\x08\x05\x1c\x0c\x1a\xb3m\r\x00\n\x1d\xc0h\x1bciii\x1bliii\x1b+iii\x1b`iii\x1bciiiHiii\x9aaiiiakwh}hey", b'\x82aaaaaaaaaaaacaaagaaa"aaa\x92]aaa&a\x05`\x05c\xe5a\x05c\x15a\xe2b\x1ca&a\x05b\x05e\xe5a\x05e\x15`\x1da\x05d\xece\x1c`\x15c\x05g\x15`\x15b\xe2`\xfaa\x05f\xfcb\xe2``a\x05a2aHi/\x02aaaaaaaaaaaaaaaabaaaaaaa\x92Iaaa\x04a;`\x05a;c\xe6a\x07`\x05`\x05c\xe5i;b\xe6a\x07`\x05b\x05e\xe5i;e\xe6aea;d2aHd\x9bt\x14\x0f\r\x14\x02\n\x18>UO]\r\x0e\x02\x00\r\x12_O,,\x02eaaaaaaaaaaaeaaagaaaraaa\x92saaa\x15a\xe2a\xc1`\x1da\x1d`\x1dc\x1db\xc0e2aH`/\xc8c\xbbd\x12\x14\x11\x04\x13\xbbf>>\x0f\x04\x16>>\xc8e\xbbb\x02\r\x12\xbbe\x0f\x00\x0c\x04\xbbd\x03\x00\x12\x04\x12\xbbb\x05\x02\x15\xc8`\xbbh>>\x02\r\x00\x12\x12>>\xc8a\x9bh]\x14\x0f\r\x14\x02\n\x18_\xbbf\x14\x0f\r\x14\x02\n\x18Zaaa\x92caaas`\x9b|\x14\x0f\r\x14\x02\n\x18>UO]\r\x0e\x02\x00\r\x12_O,,O>>\x0f\x04\x16>>\x02`aaaaaaaaaaafaaadaaa~aaa\x92\x05aaa\x15a\xe2a\x0b`\x1d`\x08a\x1dc\xc5`\xef`\x1cb\x15c\x1db\xc1b\xc0a\xe2`\x1ce\x1de\x05a\x05a\x05`\xe4bxa\x1de\x05c\x05a\x05`\xe4bxava\x1ce\x15e\x15d\x1db\xc1g\xc0a\xe2`\xe2`%a<k=c\x1cd\x1cg\x1de\x1ddxa\x1db\x1dg]a\x10D\x1db2aHb/\x88caaa\x88`aaa\xc8f\x13gaaa\xbbi>>\x02\x00\r\r>>\xbbe\r\x08\x12\x15\xbbg\x17\x00\r\x14\x04\x12\xbbh\x04\x0f\x14\x0c\x04\x13\x00\x15\x04\xbbg\x12\x0e\x13\x15\x04\x05\xbbe\n\x04\x18\x12\xc8f\x13haaa\xbbe\x00\x13\x06\x12\xbbg\n\x16\x00\x13\x06\x12\xbbi\x08\x0f\x12\x15\x00\x0f\x02\x04\xbbe\x17\x00\r\x12\xbb`\x08\xbb`\n\x13laaa\x13naaa\x13qaaa\x13paaa_aaa\x92maaas`m`}`y`o`e`\x9b\x7f\x14\x0f\r\x14\x02\n\x18>UO]\r\x0e\x02\x00\r\x12_O,,O>>\x02\x00\r\r>>\xc8g\xbbi>>\x0f\x00\x0c\x04>>\xbbk>>\x0c\x0e\x05\x14\r\x04>>\xbbm>>\x10\x14\x00\r\x0f\x00\x0c\x04>>\x13faaa\x13yaaa\xbbl>>\x02\r\x00\x12\x12\x02\x04\r\r>>\x13naaa\x13naaa\x13laaa\x13qaaa\x13paaa[aaa\x92gaaaiam`ub\xbbc,,\x02aaaaaaaaaaaaaaaa`aaa!aaa\x92maaa\x04a;`\x05a;c\x05`2aHc\x9bt\x14\x0f\r\x14\x02\n\x18>UO]\r\x0e\x02\x00\r\x12_O,%/\xc8b\x13Iaaa\x13Haaa\x13Kaaa\x13naaa\x13naaa\x13naaa\x13qaaa\x13paaa\'aaa\x92eaaaiae`\xbbc,%\xc8`\xbbh\x0c\x04\x15\x00\x02\r\x00\x12\x12\x9b@\x06\r\x0e\x03\x00\r\x12IH:F\x0f\x14\x02\r\x04\x0e\x15\x08\x05\x04>\x0c\x00\x11F<A\\A,%I\x9b`H\xc8e\xbbe\x15\x18\x11\x04\xbbe\x05\x08\x02\x15\xbbe\x04\x19\x04\x02\xbbc\x0f\x0c\xc8c\x13Laaa\x13Saaa\x13naaa\x13naaa\x13qaaa\x13paaaVaaa\x92gaaaqbumyb'] for j in range(4): for i in range(0xff): try: decrypted_code = bytes([b ^ i for b in unlucky[j]]) code = marshal.loads(decrypted_code) print(code) if isinstance(code, types.CodeType): print(j, chr(i), code) except: continue ~~~ 提前得到了key ~~~python 0 o <code object unlucky at 0x000001DE8FE57030, file "<unlucky>", line 13> 1 u <code object unlucky at 0x000001DE8FE57190, file "<unlucky>", line 22> 2 i <code object unlucky at 0x000001DE8FE57EA0, file "<unlucky>", line 33> 3 a <code object unlucky at 0x000001DE8FE577C0, file "<unlucky>", line 55> ~~~ 然后是分析输入日志(已知flag头和flag长度为56),输入`.;,;.{aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}`测试 观察到很有规律,先是每个flag里每个位置上的字母乘以常数然后求和 ~~~ > .;,;.{aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} push 97 (640) push 106 pop 106 + pop 97 + push 10282 (mul) push 97 (641) push 27 pop 27 + pop 97 + push 2619 (mul) push 97 (642) push 140 pop 140 + pop 97 + push 13580 (mul) push 97 (643) push 138 pop 138 + pop 97 + push 13386 (mul) push 97 (644) push 108 pop 108 + pop 97 + push 10476 (mul) push 97 (645) push 91 pop 91 + pop 97 + push 8827 (mul) push 97 (646) push 131 pop 131 + pop 97 + push 12707 (mul) push 97 (647) push 138 pop 138 + pop 97 + push 13386 (mul) push 97 (648) push 106 pop 106 + pop 97 + push 10282 (mul) push 97 (649) push 127 pop 127 + pop 97 + push 12319 (mul) push 97 (650) push 161 pop 161 + pop 97 + push 15617 (mul) push 97 (651) push 115 pop 115 + pop 97 + push 11155 (mul) push 97 (652) push 177 pop 177 + pop 97 + push 17169 (mul) push 97 (653) push 152 pop 152 + pop 97 + push 14744 (mul) push 97 (654) push 15 pop 15 + pop 97 + push 1455 (mul) push 97 (655) push 55 pop 55 + pop 97 + push 5335 (mul) push 97 (656) push 230 pop 230 + pop 97 + push 22310 (mul) push 97 (657) push 131 pop 131 + pop 97 + push 12707 (mul) push 97 (658) push 147 pop 147 + pop 97 + push 14259 (mul) push 97 (659) push 183 pop 183 + pop 97 + push 17751 (mul) push 97 (660) push 235 pop 235 + pop 97 + push 22795 (mul) push 97 (661) push 197 pop 197 + pop 97 + push 19109 (mul) push 97 (662) push 200 pop 200 + pop 97 + push 19400 (mul) push 97 (663) push 104 pop 104 + pop 97 + push 10088 (mul) push 97 (664) push 188 pop 188 + pop 97 + push 18236 (mul) push 97 (665) push 196 pop 196 + pop 97 + push 19012 (mul) push 97 (666) push 118 pop 118 + pop 97 + push 11446 (mul) push 97 (667) push 28 pop 28 + pop 97 + push 2716 (mul) push 97 (668) push 21 pop 21 + pop 97 + push 2037 (mul) push 97 (669) push 97 pop 97 + pop 97 + push 9409 (mul) push 97 (670) push 151 pop 151 + pop 97 + push 14647 (mul) push 97 (671) push 217 pop 217 + pop 97 + push 21049 (mul) push 97 (672) push 118 pop 118 + pop 97 + push 11446 (mul) push 97 (673) push 22 pop 22 + pop 97 + push 2134 (mul) push 97 (674) push 212 pop 212 + pop 97 + push 20564 (mul) push 97 (675) push 31 pop 31 + pop 97 + push 3007 (mul) push 97 (676) push 101 pop 101 + pop 97 + push 9797 (mul) push 97 (677) push 227 pop 227 + pop 97 + push 22019 (mul) push 97 (678) push 155 pop 155 + pop 97 + push 15035 (mul) push 97 (679) push 237 pop 237 + pop 97 + push 22989 (mul) push 97 (680) push 146 pop 146 + pop 97 + push 14162 (mul) push 97 (681) push 68 pop 68 + pop 97 + push 6596 (mul) push 97 (682) push 75 pop 75 + pop 97 + push 7275 (mul) push 97 (683) push 71 pop 71 + pop 97 + push 6887 (mul) push 97 (684) push 218 pop 218 + pop 97 + push 21146 (mul) push 97 (685) push 173 pop 173 + pop 97 + push 16781 (mul) push 97 (686) push 41 pop 41 + pop 97 + push 3977 (mul) push 97 (687) push 220 pop 220 + pop 97 + push 21340 (mul) push 97 (688) push 161 pop 161 + pop 97 + push 15617 (mul) pop 15617 + pop 21340 + push 36957 (add) pop 36957 + pop 3977 + push 40934 (add) pop 40934 + pop 16781 + push 57715 (add) pop 57715 + pop 21146 + push 78861 (add) pop 78861 + pop 6887 + push 85748 (add) pop 85748 + pop 7275 + push 93023 (add) pop 93023 + pop 6596 + push 99619 (add) pop 99619 + pop 14162 + push 113781 (add) pop 113781 + pop 22989 + push 136770 (add) pop 136770 + pop 15035 + push 151805 (add) pop 151805 + pop 22019 + push 173824 (add) pop 173824 + pop 9797 + push 183621 (add) pop 183621 + pop 3007 + push 186628 (add) pop 186628 + pop 20564 + push 207192 (add) pop 207192 + pop 2134 + push 209326 (add) pop 209326 + pop 11446 + push 220772 (add) pop 220772 + pop 21049 + push 241821 (add) pop 241821 + pop 14647 + push 256468 (add) pop 256468 + pop 9409 + push 265877 (add) pop 265877 + pop 2037 + push 267914 (add) pop 267914 + pop 2716 + push 270630 (add) pop 270630 + pop 11446 + push 282076 (add) pop 282076 + pop 19012 + push 301088 (add) pop 301088 + pop 18236 + push 319324 (add) pop 319324 + pop 10088 + push 329412 (add) pop 329412 + pop 19400 + push 348812 (add) pop 348812 + pop 19109 + push 367921 (add) pop 367921 + pop 22795 + push 390716 (add) pop 390716 + pop 17751 + push 408467 (add) pop 408467 + pop 14259 + push 422726 (add) pop 422726 + pop 12707 + push 435433 (add) pop 435433 + pop 22310 + push 457743 (add) pop 457743 + pop 5335 + push 463078 (add) pop 463078 + pop 1455 + push 464533 (add) pop 464533 + pop 14744 + push 479277 (add) pop 479277 + pop 17169 + push 496446 (add) pop 496446 + pop 11155 + push 507601 (add) pop 507601 + pop 15617 + push 523218 (add) pop 523218 + pop 12319 + push 535537 (add) pop 535537 + pop 10282 + push 545819 (add) pop 545819 + pop 13386 + push 559205 (add) pop 559205 + pop 12707 + push 571912 (add) pop 571912 + pop 8827 + push 580739 (add) pop 580739 + pop 10476 + push 591215 (add) pop 591215 + pop 13386 + push 604601 (add) pop 604601 + pop 13580 + push 618181 (add) pop 618181 + pop 2619 + push 620800 (add) pop 620800 + pop 10282 + push 631082 (add) mov m[4096], 631082 push 97 (640) push 56 pop 56 + pop 97 + push 5432 (mul) push 97 (641) push 249 pop 249 + pop 97 + push 24153 (mul) push 97 (642) push 152 pop 152 + pop 97 + push 14744 (mul) push 97 (643) push 225 pop 225 + pop 97 + push 21825 (mul) push 97 (644) push 66 pop 66 + pop 97 + push 6402 (mul) push 97 (645) push 136 pop 136 + pop 97 + push 13192 (mul) push 97 (646) push 113 pop 113 + pop 97 + push 10961 (mul) push 97 (647) push 243 pop 243 + pop 97 + push 23571 (mul) push 97 (648) push 63 pop 63 + pop 97 + push 6111 (mul) push 97 (649) push 233 pop 233 + pop 97 + push 22601 (mul) push 97 (650) push 254 pop 254 + pop 97 + push 24638 (mul) push 97 (651) push 69 pop 69 + pop 97 + push 6693 (mul) push 97 (652) push 191 pop 191 + pop 97 + push 18527 (mul) push 97 (653) push 1 pop 1 + pop 97 + push 97 (mul) push 97 (654) push 147 pop 147 + pop 97 + push 14259 (mul) push 97 (655) push 169 pop 169 + pop 97 + push 16393 (mul) push 97 (656) push 118 pop 118 + pop 97 + push 11446 (mul) push 97 (657) push 97 pop 97 + pop 97 + push 9409 (mul) push 97 (658) push 193 pop 193 + pop 97 + push 18721 (mul) push 97 (659) push 175 pop 175 + pop 97 + push 16975 (mul) push 97 (660) push 25 pop 25 + pop 97 + push 2425 (mul) push 97 (661) push 141 pop 141 + pop 97 + push 13677 (mul) push 97 (662) push 234 pop 234 + pop 97 + push 22698 (mul) push 97 (663) push 105 pop 105 + pop 97 + push 10185 (mul) push 97 (664) push 9 pop 9 + pop 97 + push 873 (mul) push 97 (665) push 53 pop 53 + pop 97 + push 5141 (mul) push 97 (666) push 115 pop 115 + pop 97 + push 11155 (mul) push 97 (667) push 162 pop 162 + pop 97 + push 15714 (mul) push 97 (668) push 104 pop 104 + pop 97 + push 10088 (mul) push 97 (669) push 104 pop 104 + pop 97 + push 10088 (mul) push 97 (670) push 153 pop 153 + pop 97 + push 14841 (mul) push 97 (671) push 57 pop 57 + pop 97 + push 5529 (mul) push 97 (672) push 11 pop 11 + pop 97 + push 1067 (mul) push 97 (673) push 28 pop 28 + pop 97 + push 2716 (mul) push 97 (674) push 3 pop 3 + pop 97 + push 291 (mul) push 97 (675) push 146 pop 146 + pop 97 + push 14162 (mul) push 97 (676) push 14 pop 14 + pop 97 + push 1358 (mul) push 97 (677) push 70 pop 70 + pop 97 + push 6790 (mul) push 97 (678) push 154 pop 154 + pop 97 + push 14938 (mul) push 97 (679) push 102 pop 102 + pop 97 + push 9894 (mul) push 97 (680) push 169 pop 169 + pop 97 + push 16393 (mul) push 97 (681) push 66 pop 66 + pop 97 + push 6402 (mul) push 97 (682) push 133 pop 133 + pop 97 + push 12901 (mul) push 97 (683) push 29 pop 29 + pop 97 + push 2813 (mul) push 97 (684) push 107 pop 107 + pop 97 + push 10379 (mul) push 97 (685) push 155 pop 155 + pop 97 + push 15035 (mul) push 97 (686) push 22 pop 22 + pop 97 + push 2134 (mul) push 97 (687) push 231 pop 231 + pop 97 + push 22407 (mul) push 97 (688) push 61 pop 61 + pop 97 + push 5917 (mul) pop 5917 + pop 22407 + push 28324 (add) pop 28324 + pop 2134 + push 30458 (add) pop 30458 + pop 15035 + push 45493 (add) pop 45493 + pop 10379 + push 55872 (add) pop 55872 + pop 2813 + push 58685 (add) pop 58685 + pop 12901 + push 71586 (add) pop 71586 + pop 6402 + push 77988 (add) pop 77988 + pop 16393 + push 94381 (add) pop 94381 + pop 9894 + push 104275 (add) pop 104275 + pop 14938 + push 119213 (add) pop 119213 + pop 6790 + push 126003 (add) pop 126003 + pop 1358 + push 127361 (add) pop 127361 + pop 14162 + push 141523 (add) pop 141523 + pop 291 + push 141814 (add) pop 141814 + pop 2716 + push 144530 (add) pop 144530 + pop 1067 + push 145597 (add) pop 145597 + pop 5529 + push 151126 (add) pop 151126 + pop 14841 + push 165967 (add) pop 165967 + pop 10088 + push 176055 (add) pop 176055 + pop 10088 + push 186143 (add) pop 186143 + pop 15714 + push 201857 (add) pop 201857 + pop 11155 + push 213012 (add) pop 213012 + pop 5141 + push 218153 (add) pop 218153 + pop 873 + push 219026 (add) pop 219026 + pop 10185 + push 229211 (add) pop 229211 + pop 22698 + push 251909 (add) pop 251909 + pop 13677 + push 265586 (add) pop 265586 + pop 2425 + push 268011 (add) pop 268011 + pop 16975 + push 284986 (add) pop 284986 + pop 18721 + push 303707 (add) pop 303707 + pop 9409 + push 313116 (add) pop 313116 + pop 11446 + push 324562 (add) pop 324562 + pop 16393 + push 340955 (add) pop 340955 + pop 14259 + push 355214 (add) pop 355214 + pop 97 + push 355311 (add) pop 355311 + pop 18527 + push 373838 (add) pop 373838 + pop 6693 + push 380531 (add) pop 380531 + pop 24638 + push 405169 (add) pop 405169 + pop 22601 + push 427770 (add) pop 427770 + pop 6111 + push 433881 (add) pop 433881 + pop 23571 + push 457452 (add) pop 457452 + pop 10961 + push 468413 (add) pop 468413 + pop 13192 + push 481605 (add) pop 481605 + pop 6402 + push 488007 (add) pop 488007 + pop 21825 + push 509832 (add) pop 509832 + pop 14744 + push 524576 (add) pop 524576 + pop 24153 + push 548729 (add) pop 548729 + pop 5432 + push 554161 (add) mov m[4100], 554161 push 97 (640) ... pop 647184 + pop 20952 + push 668136 (add) pop 668136 + pop 5432 + push 673568 (add) pop 673568 + pop 3007 + push 676575 (add) mov m[4136], 676575 push 97 (666) marshal xor 97 Traceback (most recent call last): File "xxxx\smileyCTF2025\dna\main.py", line 146, in <module> f.__code__ = marshal.loads(decrypted_code) ValueError: bad marshal data (unknown type code) ~~~ 发现最后marshal.loads报错,说明之前异或key不对,要满足条件,结合`push 97 (666)`和以下代码可知读取的是第26位的字符 ~~~python # 提取 flag 的核心部分并加载到内存 flag_core = flag[6:-1] for i in range(len(flag_core)): m[640 + i] = flag_core[i] ~~~ 那么我需要确保正确的key,才能不报错,跑几次就知道固定位是哪些了 ~~~python flag = ["a"] * 49 flag[26] = "o" flag[27] = "u" flag[22] = "i" flag[33] = "a" print(".;,;.{"+"".join(flag)+"}") ~~~ 此时完整的跑完了所有代码,日志最后如下,可以看到做了cmp并打印了`WRONG!` ~~~ push 692012 pop 692012 + pop 634894 + push False (cmp) push 560883 (4100) push 611030 pop 611030 + pop 560883 + push False (cmp) push 611342 (4104) push 658676 pop 658676 + pop 611342 + push False (cmp) push 509003 (4108) push 556679 pop 556679 + pop 509003 + push False (cmp) push 546430 (4112) push 588728 pop 588728 + pop 546430 + push False (cmp) push 579826 (4116) push 628470 pop 628470 + pop 579826 + push False (cmp) push 602413 (4120) push 659130 pop 659130 + pop 602413 + push False (cmp) push 577942 (4124) push 623012 pop 623012 + pop 577942 + push False (cmp) push 550513 (4128) push 590356 pop 590356 + pop 550513 + push False (cmp) push 613384 (4132) push 670831 pop 670831 + pop 613384 + push False (cmp) push 680525 (4136) push 734960 pop 734960 + pop 680525 + push False (cmp) push 644669 (4140) push 694096 pop 694096 + pop 644669 + push False (cmp) push 629106 (4144) push 673431 pop 673431 + pop 629106 + push False (cmp) push 617752 (4148) push 676517 pop 676517 + pop 617752 + push False (cmp) push 587496 (4152) push 638313 pop 638313 + pop 587496 + push False (cmp) push 669877 (4156) push 730305 pop 730305 + pop 669877 + push False (cmp) push 596543 (4160) push 651347 pop 651347 + pop 596543 + push False (cmp) push 570569 (4164) push 612947 pop 612947 + pop 570569 + push False (cmp) push 563354 (4168) push 614037 pop 614037 + pop 563354 + push False (cmp) push 663445 (4172) push 722768 pop 722768 + pop 663445 + push False (cmp) push 600977 (4176) push 662232 pop 662232 + pop 600977 + push False (cmp) push 562147 (4180) push 608720 pop 608720 + pop 562147 + push False (cmp) push 549327 (4184) push 598699 pop 598699 + pop 549327 + push False (cmp) push 574252 (4188) push 626932 pop 626932 + pop 574252 + push False (cmp) push 606902 (4192) push 659018 pop 659018 + pop 606902 + push False (cmp) push 509219 (4196) push 554138 pop 554138 + pop 509219 + push False (cmp) push 577055 (4200) push 627484 pop 627484 + pop 577055 + push False (cmp) push 563062 (4204) push 620929 pop 620929 + pop 563062 + push False (cmp) push 604593 (4208) push 655810 pop 655810 + pop 604593 + push False (cmp) push 549613 (4212) push 598103 pop 598103 + pop 549613 + push False (cmp) push 612597 (4216) push 664749 pop 664749 + pop 612597 + push False (cmp) push 715765 (4220) push 772833 pop 772833 + pop 715765 + push False (cmp) push 653362 (4224) push 710796 pop 710796 + pop 653362 + push False (cmp) push 613421 (4228) push 669747 pop 669747 + pop 613421 + push False (cmp) push 533243 (4232) push 576742 pop 576742 + pop 533243 + push False (cmp) push 654872 (4236) push 715958 pop 715958 + pop 654872 + push False (cmp) push 628632 (4240) push 682073 pop 682073 + pop 628632 + push False (cmp) push 634846 (4244) push 687276 pop 687276 + pop 634846 + push False (cmp) push 737893 (4248) push 806029 pop 806029 + pop 737893 + push False (cmp) push 608557 (4252) push 660519 pop 660519 + pop 608557 + push False (cmp) push 669695 (4256) push 728567 pop 728567 + pop 669695 + push False (cmp) push 634701 (4260) push 689664 pop 689664 + pop 634701 + push False (cmp) push 686508 (4264) push 746796 pop 746796 + pop 686508 + push False (cmp) push 549765 (4268) push 597800 pop 597800 + pop 549765 + push False (cmp) push 570832 (4272) push 629625 pop 629625 + pop 570832 + push False (cmp) push 541830 (4276) push 585142 pop 585142 + pop 541830 + push False (cmp) push 620926 (4280) push 678960 pop 678960 + pop 620926 + push False (cmp) push 609713 (4284) push 665322 pop 665322 + pop 609713 + push False (cmp) push 655189 (4288) push 710793 pop 710793 + pop 655189 + push False (cmp) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) pop 0 + pop 0 + push 0 (add) push 49 pop 49 + pop 0 + push False (cmp) jmp 69308 if 0!=1 else pc+=12 push 87 Wpush 82 Rpush 79 Opush 78 Npush 71 Gpush 33 !push 10 ~~~ 观察cmp值正是之前求和,此时就清楚了要用z3求解,把乘的常数和cmp的常数全部打印下来 ~~~python from z3 import * mul = [106, 27, 140, 138, 108, 91, 131, 138, 106, 127, 161, 115, 177, 152, 15, 55, 230, 131, 147, 183, 235, 197, 200, 104, 188, 196, 118, 28, 21, 97, 151, 217, 118, 22, 212, 31, 101, 227, 155, 237, 146, 68, 75, 71, 218, 173, 41, 220, 161, 56, 249, 152, 225, 66, 136, 113, 243, 63, 233, 254, 69, 191, 1, 147, 169, 118, 97, 193, 175, 25, 141, 234, 105, 9, 53, 115, 162, 104, 104, 153, 57, 11, 28, 3, 146, 14, 70, 154, 102, 169, 66, 133, 29, 107, 155, 22, 231, 61, 149, 104, 66, 72, 140, 134, 140, 174, 236, 10, 209, 162, 15, 223, 191, 183, 77, 137, 106, 69, 54, 1, 122, 195, 62, 99, 155, 10, 18, 117, 164, 216, 231, 150, 255, 127, 193, 145, 190, 34, 46, 64, 189, 182, 27, 163, 156, 156, 150, 67, 113, 188, 13, 173, 1, 115, 188, 151, 10, 188, 30, 74, 224, 175, 170, 60, 43, 188, 162, 85, 16, 28, 80, 4, 32, 83, 156, 173, 222, 92, 105, 251, 218, 180, 75, 122, 7, 11, 68, 26, 140, 122, 201, 116, 65, 5, 101, 84, 105, 219, 67, 72, 186, 183, 69, 249, 212, 86, 31, 81, 27, 207, 68, 16, 188, 133, 25, 94, 132, 72, 83, 9, 154, 87, 12, 149, 255, 225, 199, 114, 138, 200, 131, 175, 62, 39, 7, 21, 135, 83, 25, 47, 58, 72, 235, 230, 127, 198, 192, 176, 56, 51, 114, 132, 115, 180, 236, 17, 23, 145, 148, 54, 152, 33, 78, 191, 203, 193, 236, 77, 7, 196, 202, 134, 145, 61, 50, 244, 0, 37, 103, 162, 172, 246, 250, 147, 114, 45, 196, 24, 150, 13, 21, 64, 115, 24, 29, 45, 240, 12, 189, 166, 2, 253, 204, 91, 7, 70, 163, 182, 166, 31, 139, 1, 229, 118, 218, 229, 40, 169, 59, 97, 224, 67, 195, 95, 13, 72, 186, 53, 122, 229, 42, 113, 117, 246, 182, 69, 90, 135, 192, 156, 122, 181, 111, 114, 134, 171, 106, 59, 64, 227, 11, 105, 240, 221, 87, 76, 80, 204, 240, 26, 196, 170, 24, 140, 68, 48, 64, 238, 238, 141, 106, 221, 82, 151, 24, 233, 67, 216, 197, 4, 22, 82, 235, 152, 195, 53, 12, 27, 134, 42, 163, 2, 127, 63, 220, 64, 42, 237, 19, 182, 58, 14, 15, 176, 7, 57, 158, 119, 231, 97, 35, 167, 21, 40, 238, 111, 119, 116, 99, 12, 8, 77, 120, 201, 101, 218, 27, 109, 24, 109, 234, 245, 230, 138, 154, 174, 159, 184, 56, 146, 81, 253, 185, 175, 59, 219, 231, 246, 46, 101, 95, 237, 171, 242, 134, 95, 152, 121, 232, 43, 50, 135, 70, 144, 122, 118, 75, 138, 57, 120, 120, 198, 38, 202, 51, 17, 142, 190, 122, 111, 110, 16, 60, 130, 147, 180, 70, 200, 71, 39, 31, 56, 216, 186, 8, 162, 252, 157, 136, 117, 254, 188, 72, 113, 153, 135, 218, 103, 228, 91, 99, 234, 249, 144, 235, 70, 17, 86, 161, 143, 241, 234, 87, 152, 247, 109, 154, 231, 193, 48, 174, 41, 118, 139, 244, 43, 115, 41, 50, 60, 107, 224, 167, 53, 64, 187, 212, 249, 64, 32, 237, 18, 155, 194, 215, 15, 1, 30, 239, 163, 225, 161, 87, 228, 113, 71, 153, 183, 62, 146, 54, 231, 201, 56, 252, 112, 130, 208, 205, 11, 255, 91, 7, 114, 91, 175, 246, 37, 135, 96, 194, 108, 97, 191, 20, 140, 113, 63, 145, 97, 221, 100, 89, 38, 8, 31, 47, 68, 225, 54, 124, 140, 215, 189, 167, 210, 93, 149, 172, 5, 14, 207, 186, 124, 188, 247, 161, 238, 215, 226, 48, 26, 185, 170, 84, 253, 92, 221, 229, 12, 122, 30, 173, 171, 188, 64, 199, 16, 209, 221, 139, 5, 249, 240, 118, 37, 126, 252, 253, 95, 92, 73, 241, 156, 69, 44, 229, 224, 8, 58, 35, 146, 47, 177, 142, 100, 156, 37, 0, 97, 227, 100, 53, 12, 220, 212, 95, 87, 172, 60, 150, 10, 71, 141, 50, 204, 201, 212, 248, 235, 115, 76, 56, 32, 82, 169, 83, 206, 175, 83, 223, 100, 244, 34, 127, 24, 76, 136, 128, 226, 146, 187, 51, 232, 236, 53, 60, 38, 54, 51, 0, 228, 114, 34, 185, 251, 59, 207, 64, 175, 77, 94, 243, 222, 81, 138, 176, 175, 83, 74, 160, 243, 128, 222, 56, 7, 160, 112, 141, 64, 237, 21, 110, 83, 217, 222, 54, 194, 201, 227, 149, 242, 10, 78, 254, 196, 130, 232, 115, 62, 159, 164, 30, 72, 110, 186, 42, 142, 162, 231, 238, 121, 109, 214, 64, 222, 178, 67, 114, 193, 78, 90, 39, 35, 181, 182, 99, 7, 177, 20, 131, 106, 249, 101, 153, 43, 237, 17, 54, 97, 173, 63, 193, 115, 17, 192, 11, 252, 75, 7, 214, 163, 137, 157, 175, 119, 133, 215, 235, 223, 6, 195, 165, 156, 63, 72, 2, 193, 184, 39, 231, 155, 98, 79, 183, 185, 146, 62, 84, 216, 246, 91, 217, 82, 93, 52, 161, 74, 13, 36, 50, 34, 86, 102, 38, 21, 122, 67, 28, 186, 24, 191, 166, 92, 195, 65, 177, 193, 150, 153, 235, 164, 177, 52, 39, 143, 24, 85, 197, 41, 84, 78, 36, 18, 232, 243, 57, 110, 145, 18, 75, 55, 164, 81, 116, 21, 122, 122, 181, 171, 57, 20, 63, 147, 66, 226, 188, 141, 104, 194, 81, 250, 180, 121, 157, 28, 204, 8, 242, 114, 156, 5, 240, 115, 129, 142, 194, 160, 36, 136, 193, 181, 241, 63, 253, 254, 211, 57, 35, 89, 66, 63, 73, 59, 171, 217, 209, 126, 155, 247, 43, 150, 99, 153, 215, 132, 103, 16, 86, 242, 176, 180, 114, 217, 233, 76, 158, 79, 35, 127, 167, 46, 119, 222, 128, 169, 191, 253, 120, 190, 123, 236, 110, 163, 65, 94, 22, 31, 35, 231, 16, 174, 168, 106, 95, 93, 160, 29, 179, 53, 183, 7, 60, 162, 189, 74, 110, 106, 103, 248, 69, 173, 169, 88, 169, 73, 188, 107, 110, 150, 138, 26, 123, 0, 127, 113, 245, 44, 14, 67, 52, 165, 224, 252, 82, 28, 110, 54, 122, 1, 30, 183, 104, 206, 46, 8, 207, 183, 138, 182, 117, 156, 110, 128, 157, 171, 7, 91, 8, 156, 69, 25, 236, 68, 60, 213, 4, 172, 95, 27, 5, 124, 203, 55, 111, 229, 133, 98, 107, 120, 40, 156, 95, 115, 180, 208, 106, 59, 47, 57, 104, 29, 53, 166, 204, 120, 186, 112, 86, 85, 154, 77, 166, 211, 120, 219, 118, 226, 143, 174, 202, 237, 226, 42, 101, 79, 81, 213, 110, 180, 81, 38, 104, 24, 89, 112, 177, 161, 121, 81, 34, 81, 196, 75, 3, 110, 134, 218, 104, 242, 130, 140, 38, 49, 75, 139, 62, 110, 172, 106, 86, 142, 77, 167, 105, 105, 80, 17, 66, 212, 94, 125, 6, 41, 160, 157, 182, 200, 154, 66, 212, 231, 77, 42, 249, 125, 129, 208, 128, 20, 192, 243, 33, 162, 17, 164, 94, 246, 186, 143, 50, 185, 248, 186, 123, 60, 80, 66, 62, 33, 247, 129, 8, 239, 31, 81, 139, 25, 57, 233, 229, 185, 96, 173, 22, 47, 37, 104, 128, 20, 133, 176, 50, 37, 250, 84, 13, 246, 72, 102, 23, 30, 204, 231, 98, 17, 106, 39, 1, 7, 253, 94, 230, 87, 32, 191, 23, 167, 150, 140, 55, 80, 67, 119, 105, 196, 90, 196, 124, 253, 35, 0, 91, 143, 122, 176, 71, 215, 5, 108, 122, 252, 188, 219, 200, 159, 159, 241, 232, 83, 79, 17, 194, 208, 15, 62, 67, 80, 123, 29, 47, 168, 234, 68, 56, 24, 46, 45, 89, 46, 132, 221, 86, 69, 12, 13, 225, 71, 76, 254, 169, 78, 135, 82, 5, 193, 231, 141, 149, 251, 25, 132, 26, 57, 222, 26, 210, 42, 138, 145, 47, 201, 59, 135, 71, 160, 129, 127, 45, 47, 151, 54, 241, 57, 219, 71, 248, 77, 91, 44, 145, 176, 240, 164, 45, 125, 101, 228, 50, 221, 161, 175, 235, 92, 65, 229, 128, 14, 254, 144, 9, 147, 4, 6, 152, 66, 147, 157, 193, 85, 253, 174, 112, 181, 86, 158, 90, 42, 94, 244, 58, 125, 199, 111, 8, 89, 37, 218, 9, 200, 50, 178, 247, 234, 21, 251, 76, 5, 175, 105, 22, 51, 139, 244, 146, 22, 202, 54, 65, 76, 43, 205, 86, 158, 124, 71, 178, 67, 2, 64, 121, 13, 76, 108, 29, 193, 114, 48, 103, 219, 111, 131, 122, 124, 167, 83, 217, 11, 110, 232, 131, 235, 213, 78, 227, 127, 52, 163, 62, 234, 203, 174, 73, 12, 61, 208, 167, 214, 4, 132, 152, 31, 115, 211, 189, 158, 201, 87, 121, 228, 246, 15, 236, 9, 96, 222, 112, 108, 104, 139, 89, 56, 48, 132, 111, 20, 7, 72, 174, 235, 34, 250, 173, 179, 188, 218, 123, 30, 226, 40, 228, 207, 17, 141, 21, 172, 128, 23, 26, 117, 175, 128, 202, 44, 239, 161, 166, 253, 191, 107, 183, 138, 127, 213, 50, 133, 75, 184, 199, 199, 255, 67, 180, 159, 152, 232, 84, 239, 155, 61, 154, 162, 51, 85, 204, 216, 23, 125, 151, 251, 116, 139, 196, 231, 180, 54, 24, 111, 13, 90, 158, 61, 118, 133, 150, 228, 195, 38, 121, 224, 156, 179, 162, 0, 241, 91, 38, 162, 115, 63, 188, 196, 70, 239, 131, 241, 164, 158, 107, 181, 167, 146, 147, 68, 213, 184, 252, 52, 167, 10, 23, 35, 2, 182, 150, 103, 196, 58, 132, 146, 243, 222, 104, 27, 63, 212, 76, 195, 92, 188, 107, 92, 96, 145, 141, 177, 108, 174, 23, 17, 229, 178, 64, 209, 44, 190, 223, 69, 65, 108, 111, 229, 104, 201, 105, 188, 81, 192, 56, 53, 82, 83, 241, 15, 97, 166, 194, 23, 241, 86, 72, 141, 116, 86, 21, 68, 54, 237, 96, 66, 240, 11, 53, 119, 39, 63, 139, 180, 19, 202, 23, 15, 195, 123, 52, 157, 177, 129, 30, 248, 141, 245, 255, 19, 91, 249, 52, 3, 211, 225, 82, 142, 212, 72, 223, 175, 219, 22, 211, 250, 121, 209, 45, 70, 128, 208, 70, 128, 124, 6, 247, 52, 156, 1, 137, 79, 174, 69, 170, 98, 230, 213, 102, 33, 44, 246, 209, 236, 70, 70, 180, 71, 155, 207, 228, 14, 137, 43, 94, 45, 53, 176, 121, 255, 206, 56, 61, 140, 191, 87, 197, 142, 155, 55, 67, 19, 139, 155, 21, 106, 88, 239, 224, 208, 203, 45, 212, 62, 173, 174, 58, 227, 54, 6, 179, 3, 126, 149, 167, 108, 150, 33, 219, 198, 233, 251, 168, 115, 36, 55, 160, 235, 16, 76, 142, 228, 123, 184, 221, 116, 74, 85, 147, 59, 113, 61, 166, 245, 23, 172, 132, 10, 24, 199, 47, 199, 66, 203, 197, 253, 129, 193, 113, 238, 10, 19, 231, 203, 51, 138, 219, 210, 176, 236, 182, 147, 23, 25, 251, 52, 161, 213, 230, 194, 61, 229, 224, 19, 243, 233, 43, 26, 77, 198, 245, 153, 232, 122, 253, 150, 121, 206, 176, 248, 177, 99, 98, 198, 130, 57, 179, 156, 111, 253, 204, 184, 159, 220, 72, 176, 156, 79, 160, 40, 201, 95, 63, 240, 9, 140, 44, 36, 92, 17, 251, 178, 81, 226, 91, 66, 50, 241, 73, 84, 24, 64, 187, 27, 52, 61, 241, 181, 155, 135, 47, 113, 191, 232, 207, 56, 58, 179, 252, 193, 242, 85, 168, 251, 47, 196, 147, 166, 223, 251, 42, 55, 28, 185, 38, 23, 230, 239, 105, 238, 217, 197, 238, 107, 178, 212, 27, 95, 77, 134, 159, 61, 229, 7, 85, 96, 87, 232, 125, 89, 44, 152, 66, 61, 223, 181, 77, 50, 127, 215, 247, 134, 13, 30, 98, 64, 199, 77, 161, 210, 128, 124, 91, 239, 20, 186, 222, 151, 186, 92, 172, 13, 223, 215, 65, 161, 108, 172, 64, 40, 117, 189, 227, 135, 81, 174, 204, 183, 45, 61, 83, 195, 51, 183, 203, 42, 52, 215, 162, 208, 149, 221, 184, 64, 219, 6, 155, 196, 206, 240, 226, 168, 94, 189, 28, 146, 209, 84, 250, 204, 204, 246, 112, 223, 29, 30, 69, 244, 100, 37, 250, 20, 255, 174, 193, 91, 65, 126, 75, 7, 114, 141, 55, 232, 108, 24, 251, 61, 153, 121, 90, 58, 27, 45, 142, 3, 88, 54, 29, 122, 145, 160, 70, 146, 125, 187, 40, 78, 91, 155, 111, 153, 33, 106, 232, 210, 198, 47, 122, 223, 154, 4, 155, 60, 81, 255, 225, 22, 92, 56, 93, 170, 52, 165, 34, 229, 99, 90, 18, 232, 42, 19, 180, 144, 219, 231, 114, 6, 186, 245, 172, 151, 112, 252, 168, 232, 127, 113, 221, 83, 250, 60, 74, 88, 163, 23, 47, 120, 226, 13, 10, 34, 60, 26, 255, 3, 165, 0, 57, 96, 116, 77, 227, 18, 191, 216, 169, 246, 185, 113, 45, 118, 0, 8, 144, 142, 29, 145, 171, 42, 224, 138, 39, 154, 53, 119, 154, 232, 47, 128, 43, 175, 200, 50, 100, 215, 98, 202, 98, 137, 17, 66, 64, 21, 208, 5, 31, 0, 192, 34, 0, 106, 198, 153, 63, 224, 94, 25, 27, 181, 44, 170, 243, 237, 126, 249, 108, 196, 100, 241, 164, 136, 38, 103, 123, 131, 35, 83, 182, 252, 16, 54, 209, 223, 2, 62, 199, 158, 39, 122, 118, 145, 30, 65, 212, 199, 70, 205, 216, 97, 227, 167, 124, 20, 193, 221, 116, 101, 164, 158, 33, 116, 181, 150, 215, 123, 248, 30, 214, 155, 77, 105, 188, 139, 162, 95, 118, 219, 66, 246, 136, 92, 197, 7, 199, 216, 112, 29, 200, 22, 80, 64, 7, 203, 100, 80, 26, 1, 10, 177, 31, 35, 108, 132, 53, 119, 122, 72, 51, 62, 160, 167, 251, 191, 245, 142, 79, 235, 184, 142, 194, 218, 240, 66, 226, 179, 125, 18, 246, 234, 25, 56, 4, 240, 215, 214, 42, 143, 32, 87, 5, 215, 62, 231, 179, 186, 219] cmp = [692012, 611030, 658676, 556679, 588728, 628470, 659130, 623012, 590356, 670831, 734960, 694096, 673431, 676517, 638313, 730305, 651347, 612947, 614037, 722768, 662232, 608720, 598699, 626932, 659018, 554138, 627484, 620929, 655810, 598103, 664749, 772833, 710796, 669747, 576742, 715958, 682073, 687276, 806029, 660519, 728567, 689664, 746796, 597800, 629625, 585142, 678960, 665322, 710793] flag = [BitVec(f'flag{i}', 8) for i in range(49)] s = Solver() for i in range(0, len(mul), 49): sum = 0 for j in range(49): sum += flag[j] * mul[i+j] s.add(sum == cmp[i//49]) s.add(flag[26] == ord("o")) s.add(flag[27] == ord("u")) s.add(flag[22] == ord("i")) s.add(flag[33] == ord("a")) if s.check() == sat: m = s.model() for i in flag: print(chr(m[i].as_long()), end='') ~~~ 稍等一小会就得到flag为`we_ought_to_start_storing_our_data_as_dna_instead` ## liqUID glASS 挺有创新性的,结合最近苹果他们新出的液态玻璃特效出了个图像处理技术 他们部署了一个[在线网站](https://liquid-glass.surge.sh/),可以尝试转换下,在网站源代码里找到了liquidglass.wasm,用wasm2c得到c代码然后转为链接文件o就可以ida反编译分析代码 结合源代码下的liquidglass.js可知_applyLiquidGlass调用了wasm里的f函数 ~~~js var _create_buffer, _destroy_buffer, _applyLiquidGlass, __emscripten_stack_restore, __emscripten_stack_alloc, _emscripten_stack_get_current; function assignWasmExports(wasmExports) { Module["_create_buffer"] = _create_buffer = wasmExports["d"]; Module["_destroy_buffer"] = _destroy_buffer = wasmExports["e"]; Module["_applyLiquidGlass"] = _applyLiquidGlass = wasmExports["f"]; __emscripten_stack_restore = wasmExports["g"]; __emscripten_stack_alloc = wasmExports["h"]; _emscripten_stack_get_current = wasmExports["i"] } ~~~ 在ida里找到带有liquidglass和f的函数 ~~~c++ __int64 __fastcall w2c_liquidglass_f(__int64 a1, unsigned int a2, unsigned int a3, unsigned int a4, unsigned int a5) { return w2c_liquidglass_f_0(a1, a2, a3, a4, a5); } _BOOL8 __fastcall w2c_liquidglass_f_0(__int64 a1, int a2, int a3, int a4, int a5) { // [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND] v120 = 0; result = a5 <= 0; if ( a5 > 0 ) { result = a4 <= 0; if ( a4 > 0 ) { v94 = a5 - 1; v71 = (float)(a5 - 1); v93 = a4 - 1; v70 = (float)(a4 - 1); v69 = (float)a5; v68 = (float)a4; do { v92 = v120 * a4; v73 = (float)v120 / v69; v72 = v73 + -0.5; v121 = 0; do { v102 = *(_DWORD *)(a1 + 8) - 16; *(_DWORD *)(a1 + 8) = v102; v81 = (float)v121 / v68; v116 = (float)(v81 * 25.0) + (float)(v73 * 20.0); v105 = i32_reinterpret_f32(*(double *)_mm_cvtsi32_si128(LODWORD(v116)).m128i_i64); v110 = v105 & 0x7FFFFFFF; if ( (v105 & 0x7FFFFFFFu) > 0x3F490FDA ) { if ( v110 > 0x407B53D1 ) { if ( v110 > 0x40E231D5 ) { if ( v110 >= 0x7F800000 ) { v116 = v116 - v116; goto LABEL_36; } v111 = w2c_liquidglass_f5(a1, v102 + 8, *(double *)_mm_cvtsi32_si128(LODWORD(v116)).m128i_i64); v65 = f64_load(a1 + 16, v102 + 8LL); if ( (v111 & 3) == 3 ) { v18 = (__m128i)*(unsigned __int64 *)&v65; *(double *)v18.m128i_i64 = w2c_liquidglass_f2(a1, v65); v116 = -COERCE_FLOAT(_mm_cvtsi128_si32(v18)); } else { if ( (v111 & 3u) - 1 > 2 ) goto LABEL_32; if ( (v111 & 3) == 1 ) { v16 = (__m128i)*(unsigned __int64 *)&v65; *(double *)v16.m128i_i64 = w2c_liquidglass_f2(a1, v65); v116 = COERCE_FLOAT(_mm_cvtsi128_si32(v16)); } else { if ( (v111 & 3) != 2 ) { LABEL_32: v15 = (__m128i)*(unsigned __int64 *)&v65; *(double *)v15.m128i_i64 = w2c_liquidglass_f1(a1, v65); v116 = COERCE_FLOAT(_mm_cvtsi128_si32(v15)); goto LABEL_36; } v17 = (__m128i)(*(_QWORD *)&v65 ^ 0x8000000000000000LL); *(double *)v17.m128i_i64 = w2c_liquidglass_f1(a1, *(double *)v17.m128i_i64); v116 = COERCE_FLOAT(_mm_cvtsi128_si32(v17)); } } } else if ( v110 > 0x40AFEDDF ) { if ( v105 >= 0 ) v13 = -6.283185307179586; else v13 = 6.283185307179586; v55 = v13 + wasm_quietf(*(double *)_mm_cvtsi32_si128(LODWORD(v116)).m128i_i64); v14 = (__m128i)*(unsigned __int64 *)&v55; *(double *)v14.m128i_i64 = w2c_liquidglass_f1(a1, v55); v116 = COERCE_FLOAT(_mm_cvtsi128_si32(v14)); } else { v64 = wasm_quietf(*(double *)_mm_cvtsi32_si128(LODWORD(v116)).m128i_i64); if ( v105 >= 0 ) { v12 = (__m128i)COERCE_UNSIGNED_INT64(v64 + -4.71238898038469); *(double *)v12.m128i_i64 = w2c_liquidglass_f2(a1, *(double *)v12.m128i_i64); v116 = -COERCE_FLOAT(_mm_cvtsi128_si32(v12)); } else { v11 = (__m128i)COERCE_UNSIGNED_INT64(v64 + 4.71238898038469); *(double *)v11.m128i_i64 = w2c_liquidglass_f2(a1, *(double *)v11.m128i_i64); v116 = COERCE_FLOAT(_mm_cvtsi128_si32(v11)); } } } else { v63 = wasm_quietf(*(double *)_mm_cvtsi32_si128(LODWORD(v116)).m128i_i64); if ( v110 > 0x4016CBE3 ) { if ( v105 < 0 ) v9 = 3.141592653589793; else v9 = -3.141592653589793; v10 = (__m128i)COERCE_UNSIGNED_INT64(-(v9 + v63)); *(double *)v10.m128i_i64 = w2c_liquidglass_f1(a1, *(double *)v10.m128i_i64); v116 = COERCE_FLOAT(_mm_cvtsi128_si32(v10)); } else if ( v105 >= 0 ) { v8 = (__m128i)COERCE_UNSIGNED_INT64(v63 + -1.570796326794897); *(double *)v8.m128i_i64 = w2c_liquidglass_f2(a1, *(double *)v8.m128i_i64); v116 = COERCE_FLOAT(_mm_cvtsi128_si32(v8)); } else { v7 = (__m128i)COERCE_UNSIGNED_INT64(v63 + 1.570796326794897); *(double *)v7.m128i_i64 = w2c_liquidglass_f2(a1, *(double *)v7.m128i_i64); v116 = -COERCE_FLOAT(_mm_cvtsi128_si32(v7)); } } } else if ( v110 >= 0x39800000 ) { v6 = (__m128i)COERCE_UNSIGNED_INT64(wasm_quietf(*(double *)_mm_cvtsi32_si128(LODWORD(v116)).m128i_i64)); *(double *)v6.m128i_i64 = w2c_liquidglass_f1(a1, *(double *)v6.m128i_i64); v116 = COERCE_FLOAT(_mm_cvtsi128_si32(v6)); } LABEL_36: *(_DWORD *)(a1 + 8) = v102 + 16; v76 = v116; v103 = *(_DWORD *)(a1 + 8) - 16; *(_DWORD *)(a1 + 8) = v103; v117 = (float)(v81 * 20.0) + (float)(v73 * 25.0); v106 = i32_reinterpret_f32(*(double *)_mm_cvtsi32_si128(LODWORD(v117)).m128i_i64); v112 = v106 & 0x7FFFFFFF; if ( (v106 & 0x7FFFFFFFu) > 0x3F490FDA ) { if ( v112 > 0x407B53D1 ) { if ( v112 > 0x40E231D5 ) { v115 = v117 - v117; if ( v112 >= 0x7F800000 ) goto LABEL_68; v113 = w2c_liquidglass_f5(a1, v103 + 8, *(double *)_mm_cvtsi32_si128(LODWORD(v117)).m128i_i64); v67 = f64_load(a1 + 16, v103 + 8LL); if ( (v113 & 3) == 3 ) { v29 = (__m128i)*(unsigned __int64 *)&v67; *(double *)v29.m128i_i64 = w2c_liquidglass_f1(a1, v67); v115 = COERCE_FLOAT(_mm_cvtsi128_si32(v29)); } else { if ( (v113 & 3u) - 1 > 2 ) goto LABEL_64; if ( (v113 & 3) == 1 ) { v27 = (__m128i)(*(_QWORD *)&v67 ^ 0x8000000000000000LL); *(double *)v27.m128i_i64 = w2c_liquidglass_f1(a1, *(double *)v27.m128i_i64); v115 = COERCE_FLOAT(_mm_cvtsi128_si32(v27)); } else { if ( (v113 & 3) != 2 ) { LABEL_64: v26 = (__m128i)*(unsigned __int64 *)&v67; *(double *)v26.m128i_i64 = w2c_liquidglass_f2(a1, v67); v115 = COERCE_FLOAT(_mm_cvtsi128_si32(v26)); goto LABEL_68; } v28 = (__m128i)*(unsigned __int64 *)&v67; *(double *)v28.m128i_i64 = w2c_liquidglass_f2(a1, v67); v115 = -COERCE_FLOAT(_mm_cvtsi128_si32(v28)); } } } else if ( v112 < 0x40AFEDE0 ) { if ( v106 >= 0 ) { v25 = (__m128i)COERCE_UNSIGNED_INT64( wasm_quietf(*(double *)_mm_cvtsi32_si128(LODWORD(v117)).m128i_i64) + -4.71238898038469); *(double *)v25.m128i_i64 = w2c_liquidglass_f1(a1, *(double *)v25.m128i_i64); } else { v58 = -4.71238898038469 - wasm_quietf(*(double *)_mm_cvtsi32_si128(LODWORD(v117)).m128i_i64); v25 = (__m128i)*(unsigned __int64 *)&v58; *(double *)v25.m128i_i64 = w2c_liquidglass_f1(a1, v58); } v115 = COERCE_FLOAT(_mm_cvtsi128_si32(v25)); } else { if ( v106 >= 0 ) v23 = -6.283185307179586; else v23 = 6.283185307179586; v57 = v23 + wasm_quietf(*(double *)_mm_cvtsi32_si128(LODWORD(v117)).m128i_i64); v24 = (__m128i)*(unsigned __int64 *)&v57; *(double *)v24.m128i_i64 = w2c_liquidglass_f2(a1, v57); v115 = COERCE_FLOAT(_mm_cvtsi128_si32(v24)); } } else if ( v112 < 0x4016CBE4 ) { v66 = wasm_quietf(*(double *)_mm_cvtsi32_si128(LODWORD(v117)).m128i_i64); if ( v106 >= 0 ) v22 = (__m128i)COERCE_UNSIGNED_INT64(1.570796326794897 - v66); else v22 = (__m128i)COERCE_UNSIGNED_INT64(v66 + 1.570796326794897); *(double *)v22.m128i_i64 = w2c_liquidglass_f1(a1, *(double *)v22.m128i_i64); v115 = COERCE_FLOAT(_mm_cvtsi128_si32(v22)); } else { if ( v106 >= 0 ) v20 = -3.141592653589793; else v20 = 3.141592653589793; v56 = v20 + wasm_quietf(*(double *)_mm_cvtsi32_si128(LODWORD(v117)).m128i_i64); v21 = (__m128i)*(unsigned __int64 *)&v56; *(double *)v21.m128i_i64 = w2c_liquidglass_f2(a1, v56); v115 = -COERCE_FLOAT(_mm_cvtsi128_si32(v21)); } } else { v115 = 1.0; if ( v112 >= 0x39800000 ) { v19 = (__m128i)COERCE_UNSIGNED_INT64(wasm_quietf(*(double *)_mm_cvtsi32_si128(LODWORD(v117)).m128i_i64)); *(double *)v19.m128i_i64 = w2c_liquidglass_f2(a1, *(double *)v19.m128i_i64); v115 = COERCE_FLOAT(_mm_cvtsi128_si32(v19)); } } LABEL_68: *(_DWORD *)(a1 + 8) = v103 + 16; v78 = v81 + -0.5; v30 = _mm_cvtsi32_si128( COERCE_UNSIGNED_INT( (float)((float)(v81 + -0.5) * (float)(v81 + -0.5)) + (float)((float)(v73 + -0.5) * (float)(v73 + -0.5)))); *(double *)v30.m128i_i64 = wasm_sqrtf(*(double *)v30.m128i_i64); v118 = COERCE_FLOAT(_mm_cvtsi128_si32(v30)); if ( (float)((float)(v115 * 0.1) + (float)(v73 + (float)((float)(v72 * v118) * 0.5))) >= 1.0 ) v31 = 1.0; else v31 = (float)(v115 * 0.1) + (float)(v73 + (float)((float)(v72 * v118) * 0.5)); if ( v31 <= 0.0 ) v31 = 0.0; if ( v31 >= 1.0 ) v31 = 1.0; if ( v31 <= 0.0 ) v31 = 0.0; v51 = v31 * v71; v74 = v31 * v71; if ( (float)(v31 * v71) < -2147483600.0 ) { v32 = 0x80000000; } else if ( v51 >= 2147483600.0 ) { v32 = 0x7FFFFFFF; } else { v32 = (int)v51; } v104 = v32; if ( v32 + 1 <= v94 ) v33 = v32 + 1; else v33 = v94; v62 = a4 * v33; v99 = a4 * v33; if ( (float)((float)(v76 * 0.1) + (float)(v81 + (float)((float)(v78 * v118) * 0.5))) >= 1.0 ) v34 = 1.0; else v34 = (float)(v76 * 0.1) + (float)(v81 + (float)((float)(v78 * v118) * 0.5)); if ( v34 <= 0.0 ) v34 = 0.0; if ( v34 >= 1.0 ) v34 = 1.0; if ( v34 <= 0.0 ) v34 = 0.0; v50 = v34 * v70; if ( (float)(v34 * v70) < -2147483600.0 ) { v35 = 0x80000000; } else if ( v50 >= 2147483600.0 ) { v35 = 0x7FFFFFFF; } else { v35 = (int)v50; } v114 = v35; if ( v35 + 1 <= v93 ) v36 = v35 + 1; else v36 = v93; v96 = v36; v107 = 4 * (v36 + v62) + a2; v91 = i32_load8_u(a1 + 16, v107 + 1LL); v90 = i32_load8_u(a1 + 16, v107 + 2LL); v89 = i32_load8_u(a1 + 16, v107); v108 = 4 * (v99 + v114) + a2; v88 = i32_load8_u(a1 + 16, v108 + 1LL); v100 = 4 * (v104 * a4 + v96) + a2; v87 = i32_load8_u(a1 + 16, v100 + 1LL); v97 = 4 * (v104 * a4 + v114) + a2; v95 = i32_load8_u(a1 + 16, v97 + 1LL); v86 = i32_load8_u(a1 + 16, v108 + 2LL); v85 = i32_load8_u(a1 + 16, v100 + 2LL); v84 = i32_load8_u(a1 + 16, v97 + 2LL); v83 = i32_load8_u(a1 + 16, v108); v101 = i32_load8_u(a1 + 16, v100); v98 = i32_load8_u(a1 + 16, v97); v109 = 4 * (v92 + v121) + a3; v59 = (float)((float)((float)(1.0 - (float)(v118 * 0.30000001)) * 0.80000001) + (float)((float)(v118 * 0.30000001) * 0.94999999)) * 255.0; if ( v59 <= -1.0 ) { v37 = 0; } else if ( v59 >= 4294967300.0 ) { v37 = -1; } else { v37 = (int)v59; } i32_store8(a1 + 16, (unsigned int)(4 * (v92 + v121) + a3) + 3LL, v37); v79 = v118 * 0.5; v80 = 1.0 - (float)(v118 * 0.5); v60 = (float)(v80 * 0.89999998) + (float)((float)(v118 * 0.5) * 0.80000001); v119 = (float)(v34 * v70) - (float)v114; v82 = 1.0 - v119; v77 = v74 - (float)v104; v75 = 1.0 - v77; v52 = (float)((float)((float)((float)v98 * v82) + (float)(v119 * (float)v101)) * (float)(1.0 - v77)) + (float)(v77 * (float)((float)((float)v83 * v82) + (float)(v119 * (float)v89))); if ( v52 <= -1.0 ) { v38 = 0; } else if ( v52 >= 4294967300.0 ) { v38 = -1; } else { v38 = (int)v52; } v61 = v60 * (float)v38; if ( v61 >= 255.0 ) v39 = 255.0; else v39 = v61; if ( v39 <= 0.0 ) v39 = 0.0; if ( v39 <= -1.0 ) { v40 = 0; } else if ( v39 >= 4294967300.0 ) { v40 = -1; } else { v40 = (int)v39; } i32_store8(a1 + 16, v109, v40); v53 = (float)((float)((float)((float)v84 * v82) + (float)(v119 * (float)v85)) * v75) + (float)(v77 * (float)((float)((float)v86 * v82) + (float)(v119 * (float)v90))); if ( v53 <= -1.0 ) { v41 = 0; } else if ( v53 >= 4294967300.0 ) { v41 = -1; } else { v41 = (int)v53; } if ( (float)((float)(v80 + (float)(v79 * 0.94999999)) * (float)v41) >= 255.0 ) v42 = 255.0; else v42 = (float)(v80 + (float)(v79 * 0.94999999)) * (float)v41; if ( v42 <= 0.0 ) v42 = 0.0; if ( v42 <= -1.0 ) { v43 = 0; } else if ( v42 >= 4294967300.0 ) { v43 = -1; } else { v43 = (int)v42; } i32_store8(a1 + 16, v109 + 2LL, v43); v54 = (float)((float)((float)((float)v95 * v82) + (float)(v119 * (float)v87)) * v75) + (float)(v77 * (float)((float)((float)v88 * v82) + (float)(v119 * (float)v91))); if ( v54 <= -1.0 ) { v44 = 0; } else if ( v54 >= 4294967300.0 ) { v44 = -1; } else { v44 = (int)v54; } if ( (float)((float)((float)(v80 * 0.94999999) + (float)(v79 * 0.85000002)) * (float)v44) >= 255.0 ) v45 = 255.0; else v45 = (float)((float)(v80 * 0.94999999) + (float)(v79 * 0.85000002)) * (float)v44; if ( v45 <= 0.0 ) v45 = 0.0; if ( v45 <= -1.0 ) { v46 = 0; } else if ( v45 >= 4294967300.0 ) { v46 = -1; } else { v46 = (int)v45; } i32_store8(a1 + 16, v109 + 1LL, v46); ++v121; } while ( v121 != a4 ); result = ++v120 != a5; } while ( v120 != a5 ); } } return result; } ~~~ 发现做了很多运算处理,还包含了Π,直接把所有函数喂给gemini就能分析出加密原理 其中w2c_liquidglass_f1实现了sinx的泰勒级数多项式逼近,w2c_liquidglass_f2实现了cosx的泰勒级数多项式逼近,死去的微积分记忆又回来了  然后让gemini直接给出逆向脚本 ~~~python import numpy as np from PIL import Image def liquid_glass_forward(input_image: np.ndarray) -> np.ndarray: """ 用 Python 和 Numpy 精确地重新实现 liquidglass 正向算法。 这个函数接收一个图像(作为numpy数组),并返回经过特效处理后的图像。 注释中的 C 变量名对应您提供的伪代码。 """ height, width, _ = input_image.shape # C 伪代码中的 v68, v69, v70, v71 f_width, f_height = float(width), float(height) f_width_m1, f_height_m1 = float(width - 1), float(height - 1) # 创建输出图像的坐标网格 (对应 C 中的 v121, v120 循环) x_coords = np.arange(width) y_coords = np.arange(height) xx, yy = np.meshgrid(x_coords, y_coords) # 1. 坐标归一化 # C: v81 = (float)v121 / v68; v73 = (float)v120 / v69; nx = xx / f_width ny = yy / f_height # 2. 生成三角函数的输入值 # C: v116 = (float)(v81 * 25.0) + (float)(v73 * 20.0); # C: v117 = (float)(v81 * 20.0) + (float)(v73 * 25.0); p1 = nx * 25.0 + ny * 20.0 p2 = nx * 20.0 + ny * 25.0 # 3. 计算三角函数 # C 伪代码中庞大的 if/else 链和 f1, f2, f5 函数共同实现了 sin 和 cos # 我们可以直接用 numpy 的函数代替,结果一致 # C: v76 = sin(v116), v115 = cos(v117) sin_val = np.sin(p1) cos_val = np.cos(p2) # 4. 计算位移后的采样坐标 # C: v78 = v81 + -0.5; v72 = v73 + -0.5; nx_m05 = nx - 0.5 ny_m05 = ny - 0.5 # C: v118 = sqrt((nx_m05*nx_m05) + (ny_m05*ny_m05)); dist_from_center = np.sqrt(nx_m05**2 + ny_m05**2) # C: v35 = (v115 * 0.1) + (v73 + ((v72 * v118) * 0.5)); new_ny_norm = (cos_val * 0.1) + (ny + (ny_m05 * dist_from_center) * 0.5) # C: v38 = (v76 * 0.1) + (v81 + ((v78 * v118) * 0.5)); new_nx_norm = (sin_val * 0.1) + (nx + (nx_m05 * dist_from_center) * 0.5) # 将归一化坐标变回像素坐标 source_x = new_nx_norm * f_width_m1 source_y = new_ny_norm * f_height_m1 # 5. 双线性插值采样 x0 = np.floor(source_x).astype(np.int32) y0 = np.floor(source_y).astype(np.int32) x1 = x0 + 1 y1 = y0 + 1 # 计算插值权重 wa = source_x - x0 wb = source_y - y0 # 边界处理 (Clipping) x0 = np.clip(x0, 0, width - 1) y0 = np.clip(y0, 0, height - 1) x1 = np.clip(x1, 0, width - 1) y1 = np.clip(y1, 0, height - 1) # 从输入图像中获取四个角点的颜色值 c00 = input_image[y0, x0] c10 = input_image[y0, x1] c01 = input_image[y1, x0] c11 = input_image[y1, x1] # 执行插值 top = c00 * (1 - wa[..., np.newaxis]) + c10 * wa[..., np.newaxis] bottom = c01 * (1 - wa[..., np.newaxis]) + c11 * wa[..., np.newaxis] interpolated_color = top * (1 - wb[..., np.newaxis]) + bottom * wb[..., np.newaxis] # C 伪代码中还有一些额外的颜色混合步骤,但它们不影响几何映射 # 为了精确还原,我们只关心坐标映射,所以直接返回插值结果即可 return interpolated_color def restore_image(distorted_image_path: str, restored_image_path: str): """ 执行逆向还原过程 """ print(f"[*] 正在加载扭曲的图片: {distorted_image_path}") distorted_img = Image.open(distorted_image_path).convert("RGB") distorted_arr = np.array(distorted_img) height, width, _ = distorted_arr.shape print(f"[*] 正在创建 {width}x{height} 的坐标格网图...") x_coords = np.arange(width, dtype=np.float32) y_coords = np.arange(height, dtype=np.float32) xx, yy = np.meshgrid(x_coords, y_coords) coord_grid = np.zeros((height, width, 3), dtype=np.float32) coord_grid[..., 0] = xx coord_grid[..., 1] = yy print("[*] 正在应用正向 liquidglass 算法以生成位移图...") # 这里的 displacement_map 的颜色值(R,G) 代表了源坐标(x,y) displacement_map = liquid_glass_forward(coord_grid) print("[*] 正在根据位移图重构原始图像...") restored_arr = np.full((height, width, 3), 255, dtype=np.uint8) # 从位移图中提取源坐标 (sx, sy) source_x = np.clip(displacement_map[..., 0], 0, width - 1).astype(int) source_y = np.clip(displacement_map[..., 1], 0, height - 1).astype(int) # 获取目标图像的原始坐标网格,用于索引 dest_xx, dest_yy = np.meshgrid(np.arange(width), np.arange(height)) # 核心逆向映射步骤: # restored_image[sy, sx] = distorted_image[y, x] # 我们将扭曲图像在 (y,x) 的像素,放回它应该在的原始位置 (sy,sx) restored_arr[source_y, source_x] = distorted_arr[dest_yy, dest_xx] restored_img = Image.fromarray(restored_arr) print(f"[+] 还原成功!已保存为: {restored_image_path}") print("[!] 注意:还原的图像可能存在空洞,这是正常的。") restored_img.save(restored_image_path) restored_img.show() if __name__ == '__main__': # 替换为你的输入文件名 input_file = 'liquidglass.png' output_file = 'restored_qr.png' try: restore_image(input_file, output_file) except FileNotFoundError: print(f"\n错误:找不到文件 '{input_file}'。请确保它和脚本在同一目录下。") ~~~ 上面所做的代码实际上是将像素坐标还原回去,所以可以精确得到原来的图(但是原来的图还做了个颜色混合步骤,导致出来的二维码存在白色噪声) 输入前  输入后  基本能看出二维码,但是黑框存在很多白点噪声,因此我用了最笨的法手动画图(ps一点不会)  扫描二维码就能得到flag `.;,;.{Do_You_Prefer_Liquid_Glass_Or_Ass?}`?好变态 ## others 后面还没出的3道题等复现完补充回来 最后修改:2025 年 06 月 17 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏