Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.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 SUBSPROCESS.run在参数中嵌入空字节_Python - Fatal编程技术网

Python SUBSPROCESS.run在参数中嵌入空字节

Python SUBSPROCESS.run在参数中嵌入空字节,python,Python,我正在分析一个带有符号执行器的程序,并为输出编写Python助手脚本。KLEE为输入值生成测试值,我现在想将其与子流程一起使用。运行以在启用地址消毒器的二进制文件中执行 不幸的是,我收到了一封信 ValueError:嵌入的空字节 执行以下代码时: def使用参数运行(目录:str,可执行文件:str): 路径=路径(目录) 对于path.glob(“*.ktest”)中的测试路径: 打印(f“检查ktest文件{test_path.absolute()}”) ktest=ktest.fromf

我正在分析一个带有符号执行器的程序,并为输出编写Python助手脚本。KLEE为输入值生成测试值,我现在想将其与
子流程一起使用。运行
以在启用地址消毒器的二进制文件中执行

不幸的是,我收到了一封信

ValueError:嵌入的空字节

执行以下代码时:

def使用参数运行(目录:str,可执行文件:str):
路径=路径(目录)
对于path.glob(“*.ktest”)中的测试路径:
打印(f“检查ktest文件{test_path.absolute()}”)
ktest=ktest.fromfile(test\u path.absolute())
args=[arg[1]表示ktest.objects中的arg,如果arg[0]。startswith(“arg”)]
stdin=next((如果arg[0]=“stdin”),则ktest.objects中的arg为arg[1],无)
command=[executable.encode(“utf-8”)]
command.extend(args)
打印(f“正在执行命令{command},stdin={stdin}…”)
subprocess.run(命令,输入=stdin,检查=True)
使用此测试数据:

Checking ktest file /home/klee/project/klee-out-31/test000014.ktest
Executing command [b'myapp.asan', b'--\x00\xff\xff\xff'], stdin=b'\n\n\n\n\n\n\n\n\n\n'...
是否有任何方法可以传递带有嵌入空字节的字节对象?在外壳上,我可以执行

./myapp.asan $(cat klee-out-31/test000014.ktest.arg00)

但是,我必须将所有嵌入的参数从ktest文件保存到外部文件,这是我想要避免的。

NUL用于终止C字符串。从这个简单的观察结果来看,有两个后果:

  • 您不可能在单个C字符串中传递NUL(因此Python解释器会向您传递来自底层操作系统的限制的警告)
  • 如果要在C字符串数组中重现给定的字节序列,请将该数组中的每个字符串结束在NUL应该出现的位置
因此:


注意
.encode(“utf-8”)
有点代码味道;如果你做得对,你的
可执行文件
首先将是一个bytestring,而不是一个多字节字符字符串;因此根本不需要对其进行编码。

您根本无法在程序的参数列表上传递NUL字节:UNIX系统调用接口使用C字符串。C字符串以NUL结尾。因此,它们的内容中不可能包含NUL….当您运行
/myapp.asan$(cat klee-out-31/test000014.ktest.arg00)
时,假设文件确实包含NUL文本,它要么删除NUL并在没有NUL的情况下运行命令,要么在第一行结束命令行,具体取决于您使用的shell版本。在足够新的bash版本中,它将删除NUL并向stderr发出警告,告诉您它是这样做的……不能在C字符串中传递NUL是为什么生成外壳代码很棘手的一部分(尽管现在有很多工具可以自动完成这一过程)。顺便说一句,有趣的是运行
set-x/myapp.asan$(cat klee-out-31/test000014.ktest.arg00)
——它将以明确的形式发出它正在使用的实际参数列表,因此我们可以看到它实际上是什么。(它的引用形式基本上是从bash版本的Python
repr()
builtin中输出的,但是从bash文本到Python文本非常容易)。顺便问一下,您考虑过
command=[executable.encode(“utf-8”).split(b'\x00')]
?这可能正是您想要的,因为--记住--NUL用作C字符串的终止符,所以在每个NUL上结束一个C字符串,您将得到一个与原始代码等效的字节序列。(我不确定UTF-8是否合适——您可能首先应该将数据作为bytestring而不是多字节字符串输入到代码中——但这是一个完全不同的讨论)。
command = [executable.encode("utf-8").split(b'\x00')]