int3.compilation

class int3.compilation.compiler.Compiler(arch: Architecture, platform: Platform, platform_spec: str, entry: str = 'main', bad_bytes: bytes = b'', load_addr: int | None = None, _start_entry_stub_padded_len: int = 256)

The core program compiler and main interface into int3.

This class should typically be created via one of its static factory methods:

add(one: PyIntArgType, two: PyIntArgType) IntVariable

Add two variables or constants together.

property args: list[IntVariable | Pointer]

Interface into the current function’s arguments.

b(value: bytes | None = None, len_: int | None = None) BytesPointer

Create a bytes pointer from a value or specified length.

breakpoint()

Emit an architecture-aware assembly breakpoint.

clean_slate() Compiler

Create a fresh compiler targeting the same platform.

coerce(one: PyIntArgType, two: PyIntArgType) TypeCoercion

Coerce two values into the same type.

>>> from int3 import Compiler
>>> cc = Compiler.from_host()
>>> cc.coerce(0xDEAD, cc.u32(0xBEEF0000)).result_type
<IntType [u32]>
coerce_to_type(value: IntConstant, type: IntType) IntConstant
coerce_to_type(value: int, type: IntType) IntConstant
coerce_to_type(value: IntVariable, type: IntType) IntVariable
coerce_to_type(value: bytes, type: IntType) IntVariable
coerce_to_type(value: BytesPointer, type: IntType) IntVariable
coerce_to_type(value: Pointer, type: IntType) IntVariable

Coerce a value into the specified type.

>>> from int3 import Compiler
>>> cc = Compiler.from_host()
>>> cc.coerce_to_type(value=123, type=cc.types.i64)
<IntConstant [123 (i64)]>
>>> cc.coerce_to_type(value=123, type=cc.types.i8)
<IntConstant [123 (i8)]>
compile() bytes

Compile the current program definition into assembled bytes.

compile_funcs() dict[str, bytes]

Compile each defined function into its assembled bytes.

static from_host(bad_bytes: bytes = b'') Compiler

Create a compiler from the current host’s platform and architecture.

static from_str(platform_spec: Literal['linux/x86_64', 'linux/x86', 'linux/mips'], bad_bytes: bytes = b'', load_addr: int | None = None) LinuxCompiler
static from_str(platform_spec: str, bad_bytes: bytes = b'', load_addr: int | None = None) Compiler

Create a compiler from a string specifying the platform and architecture.

>>> from int3 import Compiler
>>> cc = Compiler.from_str("linux/x86")
>>> cc.triple
<Triple [i386-pc-linux-unknown]>
i(value: int) IntConstant

Create a signed integer constant of the architecture’s native width.

i16(value: int) IntConstant

Create a 16-bit signed integer constant.

i32(value: int) IntConstant

Create a 32-bit signed integer constant.

i64(value: int) IntConstant

Create a 64-bit signed integer constant.

i8(value: int) IntConstant

Create an 8-bit signed integer constant.

icmp(op: ComparisonOp, one: PyIntArgType, two: PyIntArgType) Predicate

Emit a comparison operation.

Generally, it’s easier to use the overloaded Python dunder methods on the integer variable and constant wrapper classes.

if_else(predicate: Predicate) Iterator[tuple[ContextManager[None, bool | None], ContextManager[None, bool | None]]]

Helper for defining if-else blocks.

This a very thin wrapper around llvmlite’s builder method of the same name. The respective if/else block should be acquired as a context manager, like:

llvm_ir() str

Produce the LLVM IR for the current program definition.

make_int(value: int, type: IntType) IntConstant

Create an int constant.

This method should seldom be used. Instead, reach for one of the i/i8/ i16/etc helper methods.

>>> from int3 import Compiler
>>> cc = Compiler.from_str("linux/x86_64")
make_name(hint: str | None = None) str

Make an identifier for the current function.

reserve_symbol_index() int

Reserve an index to store a pointer in the symbol table.

ret(value: PyIntArgType | None = None) None

Return from the current function, optionally specifying a return value.

u(value: int) IntConstant

Create an unsigned integer constant of the architecture’s native width.

u16(value: int) IntConstant

Create a 16-bit unsigned integer constant.

u32(value: int) IntConstant

Create a 32-bit unsigned integer constant.

u64(value: int) IntConstant

Create a 64-bit unsigned integer constant.

u8(value: int) IntConstant

Create an 8-bit unsigned integer constant.

class int3.compilation.high_level_compiler.HighLevelCompilerInterface(*args, **kwargs)

Protocol definition for the high-level, platform-independent interface.

puts(s: PyBytesArgType) IntVariable

Write a string to stdout.

See: https://man7.org/linux/man-pages/man3/puts.3.html

class int3.compilation.linux_compiler.LinuxCompiler(arch: Architecture, platform: Platform, platform_spec: str, entry: str = 'main', bad_bytes: bytes = b'', load_addr: int | None = None, _start_entry_stub_padded_len: int = 256)

A compiler that targets Linux platforms.

puts(s: PyBytesArgType) IntVariable

Write a string to stdout.

See: https://man7.org/linux/man-pages/man3/puts.3.html

sys_dup2(oldfd: PyIntArgType, newfd: PyIntArgType) IntVariable

Linux dup2 syscall.

See: https://man7.org/linux/man-pages/man2/dup.2.html

sys_exit(status: PyIntArgType) IntVariable

Linux exit syscall.

See: https://man7.org/linux/man-pages/man3/exit.3.html

sys_write(fd: PyIntArgType, buf: PyArgType, count: PyIntArgType | None = None) IntVariable

Linux write syscall.

See: https://man7.org/linux/man-pages/man2/write.2.html

syscall(sys_num: PyIntArgType, *args: PyArgType, hint: str = '') IntVariable

Emit a syscall instruction for the specified set of arguments.

class int3.compilation.types.BytesPointer(compiler: Compiler, len_: int)

A pointer to an array of bytes.

property aligned_len: int

Length of this bytes view aligned to the compiler’s native width.

compiler: Compiler
len_: int
symtab_index: int
property wrapped_llvm_node: <object object at 0x751129d45cd0>
class int3.compilation.types.IntConstant(compiler: Compiler, type: IntType, wrapped_llvm_node: llvmir.Constant | llvmir.Instruction, value: int)

An integer constant value.

value: int
class int3.compilation.types.IntType(bit_size: int, is_signed: bool)

Wrapper around an LLVM integer type.

For a good overview of LLVM IR int types, see: https://stackoverflow.com/a/14723945

bit_size: int
can_represent_type(other: IntType) bool

Whether this type could represent integer values of another type.

can_represent_value(value: int) bool

Whether this type could represent the integer value.

is_signed: bool
max_value: int
min_value: int
wrapped_type: llvmir.IntType
class int3.compilation.types.IntVariable(compiler: Compiler, type: IntType, wrapped_llvm_node: llvmir.Constant | llvmir.Instruction)

An integer with a non-constant value.

class int3.compilation.types.Pointer(compiler: Compiler, type: PointerType, wrapped_llvm_node: llvmir.Instruction)

Wrapper around an opaque pointer value.

compiler: Compiler
type: PointerType
wrapped_llvm_node: llvmir.Instruction
class int3.compilation.types.PointerType(wrapped_type: <object object at 0x751129d46070> = <factory>)

Wrapper around an LLVM IR opaque pointer type.

wrapped_type: <object object at 0x751129d45e60>
class int3.compilation.types.Predicate(wrapped_llvm_node: <object object at 0x751129d45ea0>)

Wrapper around an LLVM comparison result (an implicit 1-bit integer).

wrapped_llvm_node: <object object at 0x751129d45e90>
class int3.compilation.types.TypeCoercion(result_type: IntType, args: list[PyIntValueType])

The result of coercing two types together.

args: list[PyIntValueType]
result_type: IntType
class int3.compilation.types.TypeManager(compiler: Compiler)

Manager for int3 high-level types.

compiler: Compiler
i16: IntType
i32: IntType
i64: IntType
i8: IntType
inat: IntType
ptr: PointerType
u16: IntType
u32: IntType
u64: IntType
u8: IntType
unat: IntType
void: VoidType
class int3.compilation.types.VoidType

Wrapper around the LLVM IR void type.

wrapped_type: <object object at 0x751129d46160>