跳转到主要内容

WebAssembly解码器与反汇编器

项目描述

wasm-tob

Python模块,能够根据WASM二进制格式的MVP规范解码和反汇编WebAssembly模块和字节码。

由于尚未定义官方文本格式,实现的文本格式不对应任何现有定义,是一个简单的mnemonic op1, op2, ...格式。函数的格式类似于Google Chrome在调试控制台中的格式。

❗ 重要

这是一个作者不再有时间投入的原始项目的分支:https://github.com/athre0z/wasm。这里所做的更改主要是为了支持Manticore项目。

新问题和pull请求将尽力审查。如果您认为修复问题将是复杂的,请首先提交一个问题;这样我们可以在审查前评估修复或功能是否在范围内。在打开问题时,请包括有关如何重现您所看到的情况的信息。如果您感到舒适,请提交一个我们可审查的精心制作的、最小化的pull请求。

安装

# From PyPi
pip install wasm-tob

# From GitHub
pip install git+https://github.com/trail-of-forks/wasm-tob.git

示例

解析WASM模块,打印找到的节类型。

from wasm_tob import decode_module

with open('input-samples/hello/hello.wasm', 'rb') as raw:
    raw = raw.read()

mod_iter = iter(decode_module(raw))
header, header_data = next(mod_iter)

for cur_sec, cur_sec_data in mod_iter:
    print(cur_sec_data.get_decoder_meta()['types']['payload'])

可能输出

<wasm_tob.modtypes.TypeSection object at 0x108249b90>
<wasm_tob.modtypes.ImportSection object at 0x108249bd0>
<wasm_tob.modtypes.FunctionSection object at 0x108249c10>
<wasm_tob.modtypes.GlobalSection object at 0x108249cd0>
<wasm_tob.modtypes.ExportSection object at 0x108249d10>
<wasm_tob.modtypes.ElementSection object at 0x108249d90>
<wasm_tob.modtypes.CodeSection object at 0x108249dd0>
<wasm_tob.modtypes.DataSection object at 0x108249e10>
<wasm_tob.types.BytesField object at 0x108249b10>

解析WASM模块中的特定部分(例如GlobalSection、ElementSection、DataSection),打印每个部分的内容

from wasm_tob import (
    decode_module,
    format_instruction,
    format_lang_type,
    format_mutability,
    SEC_DATA,
    SEC_ELEMENT,
    SEC_GLOBAL,
)

with open('input-samples/hello/hello.wasm', 'rb') as raw:
    raw = raw.read()

mod_iter = iter(decode_module(raw))
header, header_data = next(mod_iter)

for cur_sec, cur_sec_data in mod_iter:
    if cur_sec_data.id == SEC_GLOBAL:
        print("GlobalSection:")
        for idx, entry in enumerate(cur_sec_data.payload.globals):
            print(
                format_mutability(entry.type.mutability),
                format_lang_type(entry.type.content_type),
            )

            for cur_insn in entry.init:
                print(format_instruction(cur_insn))

    if cur_sec_data.id == SEC_ELEMENT:
        print("ElementSection:")
        for idx, entry in enumerate(cur_sec_data.payload.entries):
            print(entry.index, entry.num_elem, entry.elems)
            for cur_insn in entry.offset:
                print(format_instruction(cur_insn))

    if cur_sec_data.id == SEC_DATA:
        print("DataSection:")
        for idx, entry in enumerate(cur_sec_data.payload.entries):
            print(entry.index, entry.size, entry.data.tobytes())
            for cur_insn in entry.offset:
                print(format_instruction(cur_insn))

输出

GlobalSection:
mut i32
get_global 0
end
mut i32
get_global 1
end
[...]
mut f32
f32.const 0x0
end
mut f32
f32.const 0x0
end
ElementSection:
0 12576 [856, 856, 856, [...], 888]
i32.const 0
end
DataSection:
0 16256 b'\x98&\x00\x00\xfe4\x00\x00\x10\x04\x00\x00\x00...\x00N10__cxxabiv121__vmi_class_type_infoE'
get_global 8
end

手动反汇编WASM字节码,打印每条指令。

from wasm_tob import (
    decode_bytecode,
    format_instruction,
    INSN_ENTER_BLOCK,
    INSN_LEAVE_BLOCK,
)

raw = bytearray([2, 127, 65, 24, 16, 28, 65, 0, 15, 11])
indent = 0
for cur_insn in decode_bytecode(raw):
    if cur_insn.op.flags & INSN_LEAVE_BLOCK:
        indent -= 1
    print('  ' * indent + format_instruction(cur_insn))
    if cur_insn.op.flags & INSN_ENTER_BLOCK:
        indent += 1

输出

block -1
  i32.const 24
  call 28
  i32.const 0
  return
end

wasmdump 命令行工具

该模块还附带了一个简单的命令行工具,名为 wasmdump,以树状格式转储所有模块结构。可选地,它还可以在调用时使用 --disas 反汇编找到的所有函数(较慢)。

版本支持

本项目旨在支持所有仍在积极维护和更新的Python版本。如果您遇到特定Python版本的问题,请提交问题。

项目详情


下载文件

下载适用于您平台的应用程序。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源代码分发

wasm-tob-1.0.1.tar.gz (15.7 kB 查看哈希值)

上传时间 源代码

构建分发

wasm_tob-1.0.1-py3-none-any.whl (17.3 kB 查看哈希值)

上传时间 Python 3

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面