什么是Z3约束器
Z3约束器是python里的一个库,最常用来求解复杂的线性方程,这种线性方程在逆向题中会出现
在逆向题目中的识别
关键特征:
上面说到Z3约束器适用于解决复杂的线性方程,所谓线性方程,简单的理解就是n元一次方程组,比如要求一串字符串的每个字符分别满足一个线性方程,同时联立所有方程构成方程组。
下面通过例题来看:
可以发现,这一大串方程组只是关于a1一个字符串,但是每个方程里的未知数是组成a1的字符,而这里的意图也很明显,就是要求出a1对应的值
再看一个题
很明显,这道题没有上面那么明显,但是也能看得出来,都是关于byte_14000A668的方程,而这个方程组中的未知量也是由byte_14000A668中的字节组成,联立这个方程组求解也可以求出byte_14000A668
利用python中的z3-solver来解决
这里提供一个脚本,在面对这类型的问题时,普遍可以用这个脚本来实现
from z3 import *
# 初始化
s = Solver()
# 定义变量数组
a1 = [Int(f'a1_{i}') for i in range(10)]
# 添加字节范围约束 (0-255) (ASCII码编码范围)
for x in a1:
s.add(x >= 0, x <= 255)
# 添加方程约束(已合并同类项)
s.add(202*a1[8] + 216*a1[5] -17*a1[4] -330*a1[9] -268*a1[6] == -14982)
s.add(325*a1[8] + 195*a1[0] + (229 - 128)*a1[1] -530*a1[6] == 22606)
s.add(489*a1[1] + 480*a1[6] +105*a1[2] +367*a1[3] -135*a1[4] -482*a1[9] == 63236)
s.add(493*a1[1] -80*a1[4] -253*a1[8] -121*a1[2] -177*a1[0] -243*a1[9] == -39664)
s.add(275*a1[4] +271*a1[6] +473*a1[7] -72*a1[5] -260*a1[4] -367*a1[4] == 14255)
s.add(286*a1[0] +196*a1[7] +483*a1[2] +442*a1[1] -495*a1[8] -351*a1[4] == 41171)
s.add(212*a1[2] +283*a1[7] -329*a1[8] -429*a1[9] -362*a1[2] -261*a1[6] == -90284)
s.add(456*a1[5] +244*a1[7] +92*a1[4] +348*a1[7] -225*a1[1] -31*a1[2] == 88447)
s.add(238*a1[9] +278*a1[7] +216*a1[6] +237*a1[0] +8*a1[2] -17*a1[9] == 83838)
s.add(323*a1[9] +121*a1[1] +370*a1[7] -64*a1[4] -196*a1[9] -422*a1[0] == 26467)
s.add(166*a1[9] +90*a1[1] +499*a1[2] +301*a1[8] -31*a1[2] -206*a1[2] == 88247)
s.add(355*a1[0] +282*a1[4] +44*a1[9] +359*a1[8] -167*a1[5] -62*a1[3] == 76658)
s.add(488*a1[6] +379*a1[9] +318*a1[2] -85*a1[1] -357*a1[2] -277*a1[5] == 35398)
s.add(40*a1[0] +281*a1[4] +217*a1[5] -241*a1[1] -407*a1[7] -309*a1[7] == -35436)
s.add((429+441)*a1[3] +115*a1[1] +96*a1[8] +464*a1[1] -133*a1[7] == 157448)
if s.check() == sat:
m = s.model()
solution = [m[a1[i]].as_long() for i in range(10)]
print("Solution found:")
print("a1 =", solution)
# 转换为ASCII字符
answer = ''.join([chr(x) if 32 <= x <= 126 else '?' for x in solution])
print("解出的明文为:", answer)
else:
print("No solution found")
注意事项:
在从IDA搬运到脚本中时只需要将&&换为s.add,其余照搬即可,在运算过程中也可以通过合并同类项来减少计算负担
总结
利用Z3约束器求解线性方程组这种加密方式比较公式化,特征也比较明显,所以不会作为主要加密逻辑在题目中出现,一般是用来求解密钥。
总之,用Z3约束器求解方程组只是一个利用python中的库来解决复杂线性方程组的方法,在面对题目时注意识别关键特征即可