Lightweight, efficient binding for the Capstone disassembly engine offering a type-safe, idiomatic API, builder-based engine creation, automatic resource management, and optional WASM initialization for web.
Kotstone is a lightweight, efficient Kotlin Multiplatform binding for the Capstone disassembly engine. It provides a type-safe, idiomatic API for disassembling binary code across JVM, Android, iOS, macOS, Linux, Windows, and Web (JS/Wasm).
implementation("ir.alisalimik.kotstone:library:1.0.0-alpha01")implementation 'ir.alisalimik.kotstone:library:1.0.0-alpha01'<dependency>
<groupId>ir.alisalimik.kotstone</groupId>
<artifactId>library-jvm</artifactId>
<version>1.0.0-alpha01</version>
</dependency>For web projects using JavaScript or TypeScript, install via npm:
npm install @alisalimik/kotstone
# or
yarn add @alisalimik/kotstonePackage: @alisalimik/kotstone on npm
# Using pod name
pod 'Kotstone'
# Or using git URL
pod 'Kotstone', :git => 'https://github.com/alisalimik/kotstone.git', :tag => '1.0.0-alpha01'{
"dependencies": {
"Kotstone": {
"git": "https://github.com/alisalimik/kotstone.git",
"tag": "1.0.0-alpha01"
}
}
}Add the dependency to your Package.swift file:
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "YourProject",
platforms: [
.iOS(.v14),
.macOS(.v12),
.tvOS(.v14),
.watchOS(.v7)
],
dependencies: [
.package(url: "https://github.com/alisalimik/kotstone.git", from: "1.0.0-alpha01")
],
targets: [
.target(
name: "YourTarget",
dependencies: [
.product(name: "Kotstone", package: "kotstone")
]
)
]
)In Xcode, go to File > Add Package Dependencies... and enter:
https://github.com/alisalimik/kotstone.git
# Add package dependency
swift package add-dependency https://github.com/alisalimik/kotstone.git --from 1.0.0-alpha01
# Or manually edit Package.swift and resolve
swift package resolveImportant for Web/JS/WASM targets: You must call
initializeCapstone()before using the API, as it loads the WASM binary at runtime. This is a suspendable function.Note: For JVM, Native, and Android-only projects, initialization is not required (but calling it is harmless).
import ir.alisalimik.kotstone.api.CapstoneEngine
import ir.alisalimik.kotstone.api.initializeCapstone
import ir.alisalimik.kotstone.enums.Architecture
import ir.alisalimik.kotstone.enums.Mode
suspend fun disassembleCode() {
// Initialize Capstone (required for JS/WASM, no-op for JVM/Native/Android)
initializeCapstone()
// Automatic resource management
CapstoneEngine.build(Architecture.ARM64, Mode.LITTLE_ENDIAN).use { engine ->
val code = byteArrayOf(0x09, 0x00, 0x38.toByte(), 0xd5.toByte()) // "ret"
engine.disassemble(code, address = 0x1000).onSuccess { instructions ->
instructions.forEach { println("0x${it.address.toString(16)}: ${it.mnemonic} ${it.opStr}") }
}.onFailure {
println("Disassembly failed: ${it.message}")
}
}
}import ir.alisalimik.kotstone.api.CapstoneEngine;
import ir.alisalimik.kotstone.enums.Architecture;
import ir.alisalimik.kotstone.enums.Mode;
try (CapstoneEngine engine = CapstoneEngine.build(Architecture.X86, Mode.MODE_64)) {
byte[] code = {0x55, 0x48, (byte)0x8b, 0x05, (byte)0xb8, 0x13, 0x00, 0x00};
var result = engine.disassemble(code, 0x1000, 0);
if (result.isSuccess()) {
for (Instruction insn : result.getOrThrow()) {
System.out.printf("0x%x: %s %s%n", insn.getAddress(), insn.getMnemonic(), insn.getOpStr());
}
}
}For web projects, you must initialize the library before use to load the WASM module:
import { CapstoneEngine, Architecture, Mode, initializeCapstone } from '@alisalimik/kotstone';
async function disassembleCode() {
// Initialize Capstone WASM module (required for web targets)
await initializeCapstone();
// Create engine with ARM64 architecture
const engine = CapstoneEngine.Companion.build(
Architecture.ARM64,
Mode.LITTLE_ENDIAN,
(builder) => {
builder.detail = true;
}
);
try {
// Disassemble ARM64 "ret" instruction
const code = new Int8Array([0x09, 0x00, 0x38, 0xd5]);
const result = engine.disassemble(code, 0x1000n);
if (result.isSuccess()) {
const instructions = result.getOrThrow();
for (const insn of instructions) {
console.log(`0x${insn.address.toString(16)}: ${insn.mnemonic} ${insn.opStr}`);
}
}
} finally {
engine.close();
}
}
disassembleCode();For iOS, macOS, tvOS, and watchOS projects using Objective-C:
#import <KapstoneKit/KapstoneKit.h>
void disassembleCode() {
// No initialization needed for native targets
// Create engine with ARM64 architecture
KapstoneKitCapstoneEngine *engine = [KapstoneKitCapstoneEngineCompanion.shared
buildArchitecture:KapstoneKitArchitecture.arm64
mode:KapstoneKitMode.littleEndian
configure_:^(KapstoneKitCapstoneBuilder *builder) {
builder.detail = YES;
}];
// Disassemble ARM64 "ret" instruction
uint8_t bytes[] = {0x09, 0x00, 0x38, 0xd5};
KapstoneKitKotlinByteArray *code = [KapstoneKitKotlinByteArray arrayWithSize:4];
for (int i = 0; i < 4; i++) {
[code setIndex:i value:bytes[i]];
}
id result = [engine disassembleCode:code address:0x1000 count:0];
// Handle result...
[engine close];
}Or in Swift:
import KapstoneKit
func disassembleCode() {
// No initialization needed for native targets
// Create engine with ARM64 architecture
let engine = CapstoneEngine.companion.build(
architecture: .arm64,
mode: .littleEndian
) { builder in
builder.detail = true
}
defer { engine.close() }
// Disassemble ARM64 "ret" instruction
let code: [Int8] = [0x09, 0x00, 0x38, -43] // 0xd5 as signed byte
let byteArray = KotlinByteArray(size: Int32(code.count))
for (index, byte) in code.enumerated() {
byteArray.set(index: Int32(index), value: byte)
}
let result = engine.disassemble(code: byteArray, address: 0x1000, count: 0)
if result.isSuccess() {
if let instructions = result.getOrNull() {
for insn in instructions {
if let instruction = insn as? Instruction {
print(String(format: "0x%llx: %@ %@",
instruction.address,
instruction.mnemonic,
instruction.opStr))
}
}
}
}
}Compiler Error? If you encounter "Experimental API usage" errors, add this free compiler arg:
compilerOptions {
freeCompilerArgs.add("-Xcontext-parameters")
freeCompilerArgs.add("-Xexpect-actual-classes")
freeCompilerArgs.add("-Xreturn-value-checker=check")
}
# Clone and install Emscripten SDK
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install 4.0.21
./emsdk activate 4.0.21
source ./emsdk_env.sh# Add the cross-toolchains tap
brew tap messense/macos-cross-toolchains
# Install Linux cross-compilation toolchains
brew install x86_64-unknown-linux-gnu # For Linux x86_64
brew install aarch64-unknown-linux-gnu # For Linux ARM64
# Install Windows cross-compilation toolchain
brew install mingw-w64
# Optional: Install Zig as fallback for other scenarios
brew install zig# Build all targets native lib dependency for all targets
./gradlew buildCapstoneAll
# Build android/jvm library
./gradlew assembleAndroidMain
./gradlew jvmJar
# build apple frameworks
./gradlew assembleKotstoneKitReleaseXCFramework
# Build web target groups
./gradlew buildCapstoneWasmJs # WASM js target
./gradlew jsNodeProductionLibraryDistribution # Typescript binding
./gradlew wasmJsNodeProductionLibraryDistribution
./gradlew buildCapstoneWasmWasi # WASM WASI target
./gradlew wasmWasiNodeProductionLibraryDistribution
Contributions are welcome! I specifically need help verifying and testing on more architectures RISC-V/MIPS/etc.
Distributed under the APACHE-2.0 license.
Bundles Capstone Engine which is available under the BSD 3-Clause license.
Kotstone is a lightweight, efficient Kotlin Multiplatform binding for the Capstone disassembly engine. It provides a type-safe, idiomatic API for disassembling binary code across JVM, Android, iOS, macOS, Linux, Windows, and Web (JS/Wasm).
implementation("ir.alisalimik.kotstone:library:1.0.0-alpha01")implementation 'ir.alisalimik.kotstone:library:1.0.0-alpha01'<dependency>
<groupId>ir.alisalimik.kotstone</groupId>
<artifactId>library-jvm</artifactId>
<version>1.0.0-alpha01</version>
</dependency>For web projects using JavaScript or TypeScript, install via npm:
npm install @alisalimik/kotstone
# or
yarn add @alisalimik/kotstonePackage: @alisalimik/kotstone on npm
# Using pod name
pod 'Kotstone'
# Or using git URL
pod 'Kotstone', :git => 'https://github.com/alisalimik/kotstone.git', :tag => '1.0.0-alpha01'{
"dependencies": {
"Kotstone": {
"git": "https://github.com/alisalimik/kotstone.git",
"tag": "1.0.0-alpha01"
}
}
}Add the dependency to your Package.swift file:
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "YourProject",
platforms: [
.iOS(.v14),
.macOS(.v12),
.tvOS(.v14),
.watchOS(.v7)
],
dependencies: [
.package(url: "https://github.com/alisalimik/kotstone.git", from: "1.0.0-alpha01")
],
targets: [
.target(
name: "YourTarget",
dependencies: [
.product(name: "Kotstone", package: "kotstone")
]
)
]
)In Xcode, go to File > Add Package Dependencies... and enter:
https://github.com/alisalimik/kotstone.git
# Add package dependency
swift package add-dependency https://github.com/alisalimik/kotstone.git --from 1.0.0-alpha01
# Or manually edit Package.swift and resolve
swift package resolveImportant for Web/JS/WASM targets: You must call
initializeCapstone()before using the API, as it loads the WASM binary at runtime. This is a suspendable function.Note: For JVM, Native, and Android-only projects, initialization is not required (but calling it is harmless).
import ir.alisalimik.kotstone.api.CapstoneEngine
import ir.alisalimik.kotstone.api.initializeCapstone
import ir.alisalimik.kotstone.enums.Architecture
import ir.alisalimik.kotstone.enums.Mode
suspend fun disassembleCode() {
// Initialize Capstone (required for JS/WASM, no-op for JVM/Native/Android)
initializeCapstone()
// Automatic resource management
CapstoneEngine.build(Architecture.ARM64, Mode.LITTLE_ENDIAN).use { engine ->
val code = byteArrayOf(0x09, 0x00, 0x38.toByte(), 0xd5.toByte()) // "ret"
engine.disassemble(code, address = 0x1000).onSuccess { instructions ->
instructions.forEach { println("0x${it.address.toString(16)}: ${it.mnemonic} ${it.opStr}") }
}.onFailure {
println("Disassembly failed: ${it.message}")
}
}
}import ir.alisalimik.kotstone.api.CapstoneEngine;
import ir.alisalimik.kotstone.enums.Architecture;
import ir.alisalimik.kotstone.enums.Mode;
try (CapstoneEngine engine = CapstoneEngine.build(Architecture.X86, Mode.MODE_64)) {
byte[] code = {0x55, 0x48, (byte)0x8b, 0x05, (byte)0xb8, 0x13, 0x00, 0x00};
var result = engine.disassemble(code, 0x1000, 0);
if (result.isSuccess()) {
for (Instruction insn : result.getOrThrow()) {
System.out.printf("0x%x: %s %s%n", insn.getAddress(), insn.getMnemonic(), insn.getOpStr());
}
}
}For web projects, you must initialize the library before use to load the WASM module:
import { CapstoneEngine, Architecture, Mode, initializeCapstone } from '@alisalimik/kotstone';
async function disassembleCode() {
// Initialize Capstone WASM module (required for web targets)
await initializeCapstone();
// Create engine with ARM64 architecture
const engine = CapstoneEngine.Companion.build(
Architecture.ARM64,
Mode.LITTLE_ENDIAN,
(builder) => {
builder.detail = true;
}
);
try {
// Disassemble ARM64 "ret" instruction
const code = new Int8Array([0x09, 0x00, 0x38, 0xd5]);
const result = engine.disassemble(code, 0x1000n);
if (result.isSuccess()) {
const instructions = result.getOrThrow();
for (const insn of instructions) {
console.log(`0x${insn.address.toString(16)}: ${insn.mnemonic} ${insn.opStr}`);
}
}
} finally {
engine.close();
}
}
disassembleCode();For iOS, macOS, tvOS, and watchOS projects using Objective-C:
#import <KapstoneKit/KapstoneKit.h>
void disassembleCode() {
// No initialization needed for native targets
// Create engine with ARM64 architecture
KapstoneKitCapstoneEngine *engine = [KapstoneKitCapstoneEngineCompanion.shared
buildArchitecture:KapstoneKitArchitecture.arm64
mode:KapstoneKitMode.littleEndian
configure_:^(KapstoneKitCapstoneBuilder *builder) {
builder.detail = YES;
}];
// Disassemble ARM64 "ret" instruction
uint8_t bytes[] = {0x09, 0x00, 0x38, 0xd5};
KapstoneKitKotlinByteArray *code = [KapstoneKitKotlinByteArray arrayWithSize:4];
for (int i = 0; i < 4; i++) {
[code setIndex:i value:bytes[i]];
}
id result = [engine disassembleCode:code address:0x1000 count:0];
// Handle result...
[engine close];
}Or in Swift:
import KapstoneKit
func disassembleCode() {
// No initialization needed for native targets
// Create engine with ARM64 architecture
let engine = CapstoneEngine.companion.build(
architecture: .arm64,
mode: .littleEndian
) { builder in
builder.detail = true
}
defer { engine.close() }
// Disassemble ARM64 "ret" instruction
let code: [Int8] = [0x09, 0x00, 0x38, -43] // 0xd5 as signed byte
let byteArray = KotlinByteArray(size: Int32(code.count))
for (index, byte) in code.enumerated() {
byteArray.set(index: Int32(index), value: byte)
}
let result = engine.disassemble(code: byteArray, address: 0x1000, count: 0)
if result.isSuccess() {
if let instructions = result.getOrNull() {
for insn in instructions {
if let instruction = insn as? Instruction {
print(String(format: "0x%llx: %@ %@",
instruction.address,
instruction.mnemonic,
instruction.opStr))
}
}
}
}
}Compiler Error? If you encounter "Experimental API usage" errors, add this free compiler arg:
compilerOptions {
freeCompilerArgs.add("-Xcontext-parameters")
freeCompilerArgs.add("-Xexpect-actual-classes")
freeCompilerArgs.add("-Xreturn-value-checker=check")
}
# Clone and install Emscripten SDK
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install 4.0.21
./emsdk activate 4.0.21
source ./emsdk_env.sh# Add the cross-toolchains tap
brew tap messense/macos-cross-toolchains
# Install Linux cross-compilation toolchains
brew install x86_64-unknown-linux-gnu # For Linux x86_64
brew install aarch64-unknown-linux-gnu # For Linux ARM64
# Install Windows cross-compilation toolchain
brew install mingw-w64
# Optional: Install Zig as fallback for other scenarios
brew install zig# Build all targets native lib dependency for all targets
./gradlew buildCapstoneAll
# Build android/jvm library
./gradlew assembleAndroidMain
./gradlew jvmJar
# build apple frameworks
./gradlew assembleKotstoneKitReleaseXCFramework
# Build web target groups
./gradlew buildCapstoneWasmJs # WASM js target
./gradlew jsNodeProductionLibraryDistribution # Typescript binding
./gradlew wasmJsNodeProductionLibraryDistribution
./gradlew buildCapstoneWasmWasi # WASM WASI target
./gradlew wasmWasiNodeProductionLibraryDistribution
Contributions are welcome! I specifically need help verifying and testing on more architectures RISC-V/MIPS/etc.
Distributed under the APACHE-2.0 license.
Bundles Capstone Engine which is available under the BSD 3-Clause license.