将python反汇编从dis.dis转换回codeobject

问题描述 投票:1回答:1

有什么方法可以通过用dis.dis获取的反汇编来创建代码对象?

例如,我使用co = compile('print("lol")', '<string>', 'exec')编译了一些代码,然后使用dis.dis(co)打印了反汇编,现在我想将反汇编“编译”回代码对象(因为它包含所有相同的数据并且没有丢失)。

python reverse-engineering bytecode
1个回答
0
投票

令人惊讶的是,是的。

但是您需要了解一些警告。第一个警告是Python字节码,因此可能的汇编指令可以在每个发行版中进行更改。

我写了一个bytecode assembler,它将与上面类似的文本文件汇编转换为python字节码。

在您的示例中,您有一个代码对象,而不是创建字节码文件所需的全部信息,但是xasm的内容当然会创建代码对象,然后再将它们与字节码文件中所需的其他信息一起写出来。 >

[要查看代码对象中的内容与如何适合Python字节码文件之间的区别,我将使用您的示例,然后结束如何创建字节码文件。

如果我在Python 3.6.10中运行您的示例,则会得到:

  1           0 LOAD_NAME                0 (print)
              2 LOAD_CONST               0 ('lol')
              4 CALL_FUNCTION            1
              6 POP_TOP
              8 LOAD_CONST               1 (None)
             10 RETURN_VALUE

但是如果我将其放入文件中,例如说foo.py,则使用py_compile.compile(source, bytecode, source)进行字节编译,并使用xdis的跨版本Python反汇编程序pydisasm进行编译:

  # pydisasm version 4.2.4
  # Python bytecode 3.6 (3379)
  # Disassembled from Python 3.6.10 (default, Jan 23 2020, 16:43:38) 
  # [GCC 7.4.0]
  # Timestamp in code: 1586703495 (2020-04-12 10:58:15)
  # Source code size mod 2**32: 13 bytes
  # Method Name:       <module>
  # Filename:          foo.py
  # Argument count:    0
  # Kw-only arguments: 0
  # Number of locals:  0
  # Stack size:        2
  # Flags:             0x00000040 (NOFREE)
  # First Line:        1
  # Constants:
  #    0: 'lol'
  #    1: None
  # Names:
  #    0: print
    1:           0 LOAD_NAME                 0 (print)
                 2 LOAD_CONST                0 ('lol')
                 4 CALL_FUNCTION             1
                 6 POP_TOP
                 8 LOAD_CONST                1 (None)
                10 RETURN_VALUE

请注意,在字节码文件中,还有一些严格不在代码对象中的附加信息:

  • 正在使用哪个字节码,(3.6的魔术数字3379),
  • 创建代码的时间戳,
  • 源代码的大小(mod 2 ** 32),
  • 方法名称,
  • 文件名,
  • 代码参数,
  • 方法标志和
  • 各种名称:常量,变量。
  • 现在将其放入foo2.pyasm之类的文件中。要将其写入字节码文件,只需运行pyc-xasm

  $ pyc-xasm foo2.pyasm
  Wrote foo2.pyc
  $ python foo2.pyc
  lol

我在2018 lighting talk at PyColumbia 2018中对此进行了演示

我应该注意,在xasmxdis的下一个发行版之前,Python 3.7及更高版本不起作用,但3.6及更早版本才起作用。

© www.soinside.com 2019 - 2024. All rights reserved.