先贴一下 README
Pyasmer 是一个 Python 字节码编辑库。它可以用来修改现有的二进制代码(例如, func.code)。
Pyasmer 可以帮助开发者在 python 代码中执行一些动态地在已有代码中插桩、代理、指令生成,
使用它需要你具备一定的 Python 字节码和 CPython 虚拟机执行机制,你可以从官方文档获取这些知识: https://docs.python.org/3/library/dis.html。Pyasmer 也会提供一些易于使用的接口,降低使用难度。
举个例子:
import sys from pyasmer.asm_instruction import asm_global_var, asm_fast_var from pyasmer.code_writer import CodeWriter if __name__ == '__main__': _frozen_importlib = sys.modules['_frozen_importlib'] # _find_and_load_unlocked 函数会在 import 模块的时候被调用 _find_and_load_unlocked = getattr(_frozen_importlib, '_find_and_load_unlocked') cw = CodeWriter(_find_and_load_unlocked.__code__)() # 在_find_and_load_unlocked 函数开头添加一个 print ,将要被 import 的模块名称打印出来 # # 更新插入位置到函数开头(第 0 条指令) cw.update_position(offset=0) # None: 忽略返回值 # asm_global_var('print'): 调用的函数为 print # asm_fast_var('name'): 将局部变量`name`传给 print cw.call_function(None, asm_global_var('print'), asm_fast_var('name')) cw.gen_code() # 执行 import 命令 import ast
输出显示有两个模块在 import 命令过程中被引用。
output: ast _ast
目前功能还比较简单,支持插入函数调用、获取属性等功能。
此外支持通过表达式匹配定位要修改的位置,比如:
@asm_viewer def binary_ops(a, b): return [a + b, a - b, a * b, a / b, a + b] def test_match_binary_op(): cv: CodeViewer = binary_ops.viewer # 匹配到两处 a + b 的位置 binary_add = [x for x in cv.find_snippet_by_expression("a + b", local_vars=["a", "b"])] assert len(binary_add) == 2 # 第 0-2 条指令和第 12-14 条指令 # LOAD_FAST a # LOAD_FAST b # BINARY_ADD assert binary_add == [(0, 2), (12, 14)]
总之,想要更多的功能欢迎来手搓,使用场景请各自脑补,over~~~
![]() | 1 penguinWWY OP 已发布到 pypi https://pypi.org/project/pyasmer |
![]() | 2 penguinWWY OP |
3 yyzq007 2022-08-01 17:15:11 +08:00 支持支持 |
4 joApioVVx4M4X6Rf 2022-08-01 17:53:04 +08:00 大佬! |