Z3でcrackmeを解いてみたい。 crackmeはかなり大きいですが、次のように単純化することができます::z3pyでcrackmeを解く
#! /usr/bin/python
import sys
T='Fguad2x-GP5_QqNi'
key=sys.argv[1]
if len(key) != 3:
print "Bad key length"
exit(1)
out=[]
for c in key:
out.append(T[ord(c)>>4 ])
out.append(T[ord(c) & 0xf])
if ''.join(out)=='--xPxN':
print "You win"
解決策は「勝ち」です。
このようなことは、私が推測するz3で解決できます。私はZ3のスタイルでcrackmeから翻訳すべてのロジックで始まる:
- s.check()と言うので、私は少なくとも一つの解決策を持っている「座っ」:
#! /usr/bin/python from z3 import * #Preparing data map_array='Fguad2x-GP5_QqNi' T=Array('T',IntSort(),IntSort()) for i,j in enumerate(map_array): T = Store(T, ord(j), i) sol='--xPxN' #We know input has 3 characters a=BitVec('a',8) b=BitVec('b',8) c=BitVec('c',8) #Ignite s=Solver() #String key is printable s.add(BV2Int(a)>=65,BV2Int(a)<=122) s.add(BV2Int(b)>=65,BV2Int(b)<=122) s.add(BV2Int(c)>=65,BV2Int(c)<=122) #Adding constraints s.add(Select(T,BV2Int(a>>4))==ord(sol[0])) s.add(Select(T,BV2Int(a&0xf))==ord(sol[1])) s.add(Select(T,BV2Int(b>>4))==ord(sol[2])) s.add(Select(T,BV2Int(b&0xf))==ord(sol[3])) s.add(Select(T,BV2Int(c>>4))==ord(sol[4])) s.add(Select(T,BV2Int(c&0xf))==ord(sol[5])) #Verify solving print s.check() print s.model()
は今、私はいくつかの質問がありますか?
- 配列を定義するより良い方法はありますか?
- 文字を直接使用する方法はありますか?
ソリューションの後にa、b、cのみを取得するにはどうすればよいですか? - > 78
$ ./stovlfw.py
座っ[B = 1、 = 136、 C = 0、 T = [3:s.model()は、非常に奇妙な出力を示しています> 120、 - 、 65 - > 120、 2 - > 80、 1 - > 45、 0 - > 45、他 - > 45]、 K 0 = [3 - !> 78、 65 2 - > 80、 1 - > 45、 0 - > 45、 else - > 45]]
これは制約と矛盾しているようです(??)私は何か間違っていますが、どこですか?
ありがとう