Boron is a hobby project that implements an x86-64 assembler in Python.
Project description
BORON Assembler
UNDER DEVELOPMENT - TRY IT AT YOUR OWN RISK
STILL NEEDS TO DEVELOPED
What is Boron?
Boron is a hobby project that implements an x86-64 assembler in Python.
You can dynamically assemble instructions at runtime and execute them immediately.
Why Boron?
- Live machine code generation: Assemble instructions directly in Python and execute them on the fly.
- Full control: Every instruction, operand, and offset is manipulable from Python objects.
- Learn by doing: Experiment with instructions, syscalls, and memory layout without writing intermediate files.
- Transparent and hackable: More comments and documentation will be added soon to help you understand the inner workings.
Unlike NASM or GCC assemblers, Boron lets you experiment and run machine code directly in Python. Multi-file projects or libraries like libc still require the system linker, but single-file programs can be assembled and executed dynamically (soon).
Limitations
- No built-in runtime execution yet: You have to handle relocations manually.
- Relocatable ELF32/ELF64 files only: COFF format and other outputs are not supported yet.
- Under active development: Bugs and breaking changes are expected.
- Not commented yet: I will add comments to the code.
What's New
- Simple built-in runtime execution : An class added for it but I need to work on it more
- Simple disassembler : YAY!
Next steps
Current Goals
- Built-in runtime execution: I will add an class for it.
- More instructions: I will add more x64 instructions. Currently Boron have a few instructions (24)
- Documentation: I will fill the documentation folder and comment the code.
Future Goals
- Other architecthtures: I will add x16/x86 architecthure
- More file formats: Like coff
- Disassembler: From flat binary
- Improvement of the readme: I will add more examples.
- And others
How to use Boron?
Simple "Hello, World!"
import mmap, ctypes
from boron.assembler.x64.General import instructions, operands
from boron.assembler.x64.General.registers import GPRegisters
# Message
hello = b"Hello, world!\n"
hello_len = len(hello)
hello_buf = ctypes.create_string_buffer(hello) # buffer in memory
buf_addr = ctypes.addressof(hello_buf) # raw byte address
# Assembly program
program = [
# write(1, buf, len)
instructions.INSTRUCTIONS.MOV.R_IMM(GPRegisters.rax, operands.Immediate(1, 8)), # sys_write
instructions.INSTRUCTIONS.MOV.R_IMM(GPRegisters.rdi, operands.Immediate(1, 8)), # stdout
instructions.INSTRUCTIONS.MOV.R_IMM(GPRegisters.rsi, operands.Immediate(buf_addr, 8)),
instructions.INSTRUCTIONS.MOV.R_IMM(GPRegisters.rdx, operands.Immediate(hello_len, 8)),
instructions.INSTRUCTIONS.SYSCALL(),
# exit(0)
instructions.INSTRUCTIONS.MOV.R_IMM(GPRegisters.rax, operands.Immediate(60, 8)),
instructions.INSTRUCTIONS.XOR.R_R(GPRegisters.rdi, GPRegisters.rdi),
instructions.INSTRUCTIONS.SYSCALL(),
]
# Assemble to machine code
code = b""
for instr in program:
for i in instr.emit():
code += i.emit()
# Allocate executable memory and copy code
mem = mmap.mmap(-1, len(code), prot=mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC,
flags=mmap.MAP_PRIVATE | mmap.MAP_ANONYMOUS)
mem.write(code)
# Execute
addr = ctypes.c_void_p.from_buffer(mem)
entry = ctypes.CFUNCTYPE(None)(ctypes.addressof(addr))
entry()
Prints the string in
hellodirectly. No NASM or linker required. Works on Linux.
And yes that was for just a "Hello, World!"
simple "Hello, World!" but as a file
from boron.codegen.builder import Builder
from boron.assembler.assembler import x64,ASSEMBLER,SECTION,ARCH,FILE
from boron.codegen.file import elf
from boron.codegen.section import SectionKind, SectionFlags, SymbolBinding
#required modules in boron
builder = ASSEMBLER(ARCH.x64,True)
msg = b"Hello, World!\n"
# TEXT SECTION
text = builder.add_section(
SECTION(".text", SectionKind.CODE, SectionFlags.EXEC, alignment=0x1000)
)
a = text.add_label("_start", binding=SymbolBinding.GLOBAL)
# write syscall
# rax = 1 (sys_write)
text.add(x64.General.instructions.INSTRUCTIONS.MOV.R_IMM(
x64.General.registers.GPRegisters.eax,
x64.General.operands.Immediate(1,4)
))
# rdi = 1 (stdout)
text.add(x64.General.instructions.INSTRUCTIONS.MOV.R_IMM(
x64.General.registers.GPRegisters.edi,
x64.General.operands.Immediate(1,4)
))
# rsi = &msg
text.add(x64.General.instructions.INSTRUCTIONS.MOV.R_IMM(
x64.General.registers.GPRegisters.rsi,
x64.General.operands.SYMBOL("msg", 8, False, 0))
)
# rdx = len
text.add(x64.General.instructions.INSTRUCTIONS.MOV.R_IMM(
x64.General.registers.GPRegisters.edx,
x64.General.operands.Immediate(len(msg),4) # "Hello, world!\n"
))
b = text.add(x64.General.instructions.INSTRUCTIONS.SYSCALL())
# exit syscall
# rax = 60
text.add(x64.General.instructions.INSTRUCTIONS.MOV.R_IMM(
x64.General.registers.GPRegisters.rax,
x64.General.operands.Immediate(60,4)
))
# rdi = 0
text.add(x64.General.instructions.INSTRUCTIONS.MOV.R_IMM(
x64.General.registers.GPRegisters.rdi,
x64.General.operands.Immediate(0,4)
))
text.add(x64.General.instructions.INSTRUCTIONS.SYSCALL())
# DATA SECTION
data = builder.add_section(
SECTION(".data", SectionKind.DATA,
SectionFlags.READ | SectionFlags.WRITE,
alignment=0x10)
)
data.add_label("msg", binding=SymbolBinding.LOCAL)
data.db(msg)
# WRITE FILE
with open("out", "wb") as f:
out = builder.build(FILE.ELF)
f.write(out)
It may be require admin permissions (sudo) you need to link it with
ld out -o hello
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file boron_assembler-0.2.1.tar.gz.
File metadata
- Download URL: boron_assembler-0.2.1.tar.gz
- Upload date:
- Size: 37.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0ba2a1abf2d7dfc24aa20041c3a039f39d2ddd032c33df130e0dd96669cf555
|
|
| MD5 |
62f17fc5b16046f1aa4ef3dc44721603
|
|
| BLAKE2b-256 |
8608441b5de19c696ee3fd5cd96dc5f49e0316ddc0edf89cd646cf0014310871
|
Provenance
The following attestation bundles were made for boron_assembler-0.2.1.tar.gz:
Publisher:
python-package.yml on TAN-JANT/BORON
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
boron_assembler-0.2.1.tar.gz -
Subject digest:
a0ba2a1abf2d7dfc24aa20041c3a039f39d2ddd032c33df130e0dd96669cf555 - Sigstore transparency entry: 1429449669
- Sigstore integration time:
-
Permalink:
TAN-JANT/BORON@3f166aeabe1bda3cc307d1b7cb16b0f9a3fbcb0a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/TAN-JANT
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-package.yml@3f166aeabe1bda3cc307d1b7cb16b0f9a3fbcb0a -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file boron_assembler-0.2.1-py3-none-any.whl.
File metadata
- Download URL: boron_assembler-0.2.1-py3-none-any.whl
- Upload date:
- Size: 45.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d3d2786248e557e4af7e18614d3f3acd0dc2430a7ee4dcfae54452935924bca
|
|
| MD5 |
d7ee23a904079e9bc9451c2c53291edb
|
|
| BLAKE2b-256 |
44b05b6cca881864209abe52a6cb3295782a415beb2a0312e84219f764a249c6
|
Provenance
The following attestation bundles were made for boron_assembler-0.2.1-py3-none-any.whl:
Publisher:
python-package.yml on TAN-JANT/BORON
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
boron_assembler-0.2.1-py3-none-any.whl -
Subject digest:
5d3d2786248e557e4af7e18614d3f3acd0dc2430a7ee4dcfae54452935924bca - Sigstore transparency entry: 1429449675
- Sigstore integration time:
-
Permalink:
TAN-JANT/BORON@3f166aeabe1bda3cc307d1b7cb16b0f9a3fbcb0a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/TAN-JANT
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-package.yml@3f166aeabe1bda3cc307d1b7cb16b0f9a3fbcb0a -
Trigger Event:
workflow_dispatch
-
Statement type: