先贴一下 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
大佬!
|