Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中Z3的位运算_Python_Bit Manipulation_Z3 - Fatal编程技术网

python中Z3的位运算

python中Z3的位运算,python,bit-manipulation,z3,Python,Bit Manipulation,Z3,我再一次在与Z3抗争。我正试图从我用IDA反汇编的二进制代码中构建代码: 此函数被调用0x80次。ecx初始化为0x40。[rdi+8]已用0xDEADFACEDEADBEEF初始化。rsi从我试图查找的向量“vec”中获取每个字节,它的值只能是0x30、0x31和0x32。我不确定我的逻辑是否正确,或者我没有使用正确的Z3函数。它不是SAT,应该是,因为我的问题中的向量“v1”最终应该包含值0x12345670134567。我的代码: from z3 import * def set_nu

我再一次在与Z3抗争。我正试图从我用IDA反汇编的二进制代码中构建代码:

此函数被调用0x80次。ecx初始化为0x40。[rdi+8]已用0xDEADFACEDEADBEEF初始化。rsi从我试图查找的向量“vec”中获取每个字节,它的值只能是0x30、0x31和0x32。我不确定我的逻辑是否正确,或者我没有使用正确的Z3函数。它不是SAT,应该是,因为我的问题中的向量“v1”最终应该包含值0x12345670134567。我的代码:

from z3 import *

def set_number(vec,size): #vec
    for i in range(0, size * 8 - 8, 8):
        val = Extract(i + 7, i, vec)
        val = BV2Int(val,False)
        return Or(val==0x30,val == 0x31, val == 0x32)

s = z3.Solver()

size = 0x80
ecx = 0x40
v1 = BitVecVal(0xDEADFACEDEADBEEF,64)
vec = BitVec("inf",size*8) # <content from d.d file>
s.add(set_number(vec,size)) #40 bytes of {0,1,2}

for i in range(0, size*8-8, 8):
    val = Extract(i + 7, i, vec)
    val = BV2Int(val,False)
    if(val == 0x30):
        v1 = RotateLeft(v1, ecx)
        v1 = v1 >> 1
        v1 *= 2
        v1 = RotateRight(v1, ecx)
        ecx = ecx - 1
        s.add(ecx>=0)
    elif(val == 0x31):
        s.add(ecx<40 and ecx>=0)
        ecx = ecx+1
        v1 = RotateLeft(v1,ecx)
        v1 = v1 >> 1
        v1 *= 2
        v1 = RotateRight(v1,ecx)
        ecx = ecx+1
    elif (val==0x32):
        s.add(ecx < 40 and ecx >= 0)
        ecx = ecx + 1
        v1 = RotateLeft(v1, ecx)
        v1 = v1 >> 1
        v1 *= 2
        v1 = v1 | 1
        v1 = RotateRight(v1, ecx)
        ecx = ecx+1
s.add(v1 == 0x123456701234567)
s.check()
从z3导入*
def设置_编号(vec,尺寸):#vec
对于范围内的i(0,大小*8-8,8):
val=提取(i+7,i,vec)
val=BV2Int(val,False)
返回或(val==0x30,val==0x31,val==0x32)
s=z3.Solver()
大小=0x80
ecx=0x40
v1=BitVecVal(0xDEADFACEDEADBEEF,64)
vec=BitVec(“inf”,大小*8)#
s、 add(set_number(vec,size))#40字节的{0,1,2}
对于范围内的i(0,尺寸*8-8,8):
val=提取(i+7,i,vec)
val=BV2Int(val,False)
如果(val==0x30):
v1=旋转英尺(v1,ecx)
v1=v1>>1
v1*=2
v1=旋转光(v1,ecx)
ecx=ecx-1
s、 添加(ecx>=0)
elif(val==0x31):
s、 添加(ecx=0)
ecx=ecx+1
v1=旋转英尺(v1,ecx)
v1=v1>>1
v1*=2
v1=旋转光(v1,ecx)
ecx=ecx+1
elif(val==0x32):
s、 添加(ecx<40且ecx>=0)
ecx=ecx+1
v1=旋转英尺(v1,ecx)
v1=v1>>1
v1*=2
v1=v1 | 1
v1=旋转光(v1,ecx)
ecx=ecx+1
s、 添加(v1==0x123456701234567)
s、 检查()

一如既往,非常感谢

这里有一些问题,但最重要的是使用
if-then-else
。使用符号值时,不能使用Python的if-then-else。相反,您必须使用z3的
If
构造

在您的程序中,您的if-then-else被具体地评估,因此您最终得到了一个虚假的断言。您可以通过在调用
检查
之前放置
打印s.sexpr()
来验证这一点

首先用调用
if
函数替换所有
if-then-else的
。在每个步骤中,查看
s.sexpr()
(让我们在每个
add
之后)并确保它包含正确的表达式。这将引导您对问题进行正确的编码。从这里开始阅读:

z3编码风格 下面是我如何用z3py编码你的问题。请注意,我只是对您的python代码进行了音译,因此,如果您的代码中有任何错误,它们将被保留。请注意,所有符号“if-then-else”计算是如何分别完成的,并通过调用z3py的
if
合并的

从z3导入*
大小=0x80
vec=BitVec(“inf”,大小*8)
s=解算器()
#vec中的每个字节都是0x30、0x31或0x32
对于范围内的i(0,大小*8,8):
b=提取(i+7,i,vec)
s、 添加(或(b==0x30,b==0x31,b==0x32))
def setLastBit(v):
返回Concat(摘录(63,1,v),位向量(1,1))
def clearLastBit(v):
返回Concat(Extract(63,1,v),BitVecVal(0,1));
def if30(inp、ecx):
inp=旋转英尺(inp,ecx)
inp=clearLastBit(inp)
inp=旋转光(inp,ecx)
ecx=ecx-1
返回inp,ecx
def if31(inp、ecx):
ecx=ecx+1
inp=旋转英尺(inp,ecx)
inp=clearLastBit(inp)
inp=旋转光(inp,ecx)
ecx=ecx+1
返回inp,ecx
def if32(inp、ecx):
ecx=ecx+1
inp=旋转英尺(inp,ecx)
inp=setLastBit(inp)
inp=旋转光(inp,ecx)
ecx=ecx+1
返回inp,ecx
v1=BitVecVal(0xDEADFACEDEADBEEF,64)
ecx=BitVecVal(0x40,64)
对于范围内的i(0,大小*8,8):
val=提取(i+7,i,vec)
val30=if30(v1,ecx)
val31=if31(v1,ecx)
val32=if32(v1,ecx)
v1=If(val==0x30,val30[0],If(val==0x31,val31[0],val32[0]))
ecx=If(val==0x30,val30[1],If(val==0x31,val31[1],val32[1]))
s、 添加(v1==0x123456701234567)
打印(s.sexpr())
打印(s.check())
不幸的是,当我运行此程序时,z3会打印内部生成的程序(您可以检查它以了解引擎盖下的工作方式),但它不会很快返回到sat
或unsat
。这可能有多种原因:

  • 您编写的算法可能不太正确。我建议在编写程序时研究它,并确保它符合您的意图。查看您是否可以遵循生成的程序(您可以在战略位置添加
    print(s.sexpr())
    ,以查看每个步骤生成的代码

  • 如果编码不正确,那么希望你能用这种方式修复它,让z3找到你的
    vec
    值。如果编码正确,但z3没有在合理的时间内回答你的查询,那么这就意味着z3很难处理这个问题。我建议保持你的
    vec
    简短:而不是当前的64字节大小,从小得多的地方开始,看看z3是否可以处理它。(比如说从几个字节开始。)如果你对算法的理解是正确的,这也可以进行进一步的调试


祝你好运!

这里有一些问题,但最重要的是使用
if-then-else
。当使用符号值时,不能使用Python的if-then-else。相反,必须使用z3的
if
构造

在你的程序中,你的if-then-else被具体地评估,因此你在最后得到一个虚假的断言。你可以通过在调用
check
之前放置一个
print s.sexpr()
来验证这一点

首先用调用
if
函数替换所有
if-then-else的
。在每一步中,查看
s.sexpr()
(比如在每次
添加
之后),确保它包含正确的表达式。这将导致