Swift bindings for Capstone Engine.
Provides a complete swift-native wrapper for Capstone, without exposing the C API.
You need to have the capstone library and headers installed on your system.
-
Swift 5.3
-
Use the branch corresponding to your version of Capstone:
- Version 4.x:
v4
branch:
.package(name:"Capstone", url: "https://github.com/zydeco/capstone-swift", .branch("v4"))
next
branch:next
branch:
.package(name:"Capstone", url: "https://github.com/zydeco/capstone-swift", .branch("next"))
- Version 4.x:
-
Include "Capstone" as a dependency for your executable target:
let package = Package( // name, platforms, products, etc. dependencies: [ .package(name: "Capstone", url: "https://github.com/zydeco/capstone-swift", .branch("v4")), // other dependencies ], targets: [ .target(name: "<command-line-tool>", dependencies: [ "Capstone", ]), // other targets ] )
-
On macOS, you can install capstone with Homebrew:
brew install capstone
for stable version (currently 4.0.2)brew install capstone --head
fornext
branch
-
On Linux, build Capstone 4.0.2 or next branch from source.
- Create an instance of
Capstone
, with the desiredArchitecture
andMode
:
let capstone = try Capstone(arch: .arm, mode: [Mode.arm.thumb, Mode.arm.mClass])
- Set
Options
s if needed:
try capstone.set(option: .detail(value: true))
- Disassemble code:
Instructions are returned as an architecture-specific instruction class, which descends from
Instruction
let code = Data([0xef, 0xf3, 0x02, 0x80])
let instructions: [ArmInstruction] = try capstone.disassemble(code: code, address: 0x1000)
- Examine code:
for ins in instructions: {
print(" \(ins.mnemonic) \(ins.operandsString)")
}
- Documentation is generated with swift-doc.
- See
Examples/cstool
for an implementation ofcstool
in Swift.
import Capstone
import Foundation
// Code to disassemble
let code = Data([0x8d, 0x4c, 0x32, 0x08, 0x01, 0xd8, 0x81, 0xc6, 0x34, 0x12, 0x00, 0x00, 0x05, 0x23, 0x01, 0x00, 0x00, 0x36, 0x8b, 0x84, 0x91, 0x23, 0x01, 0x00, 0x00, 0x41, 0x8d, 0x84, 0x39, 0x89, 0x67, 0x00, 0x00, 0x8d, 0x87, 0x89, 0x67, 0x00, 0x00, 0xb4, 0xc6, 0xe9, 0xea, 0xbe, 0xad, 0xde, 0xff, 0xa0, 0x23, 0x01, 0x00, 0x00, 0xe8, 0xdf, 0xbe, 0xad, 0xde, 0x74, 0xff])
// Create instance of capstone
let capstone = try Capstone(arch: .x86, mode: Mode.bits.b32)
// Enable detail mode to get instruction groups and operands
try capstone.set(option: .detail(value: true))
// Disassemble instructions
let instructions: [X86Instruction] = try capstone.disassemble(code: code, address: 0x1000)
// Iterate through instructions
var insCountByGroup: [X86Grp: Int] = [:]
var opCountByType: [X86Op: Int] = [:]
print("Disassembly:")
for ins in instructions {
print(" \(ins.mnemonic) \(ins.operandsString)")
// Count by instruction groups
insCountByGroup.merge(ins.groups.map({ ($0, 1) }), uniquingKeysWith: +)
// Count operands by type
opCountByType.merge(ins.operands.map({ ($0.type, 1) }), uniquingKeysWith: +)
}
// Print results
print("Instructions by group:")
for (group, count) in insCountByGroup {
print(" \(group): \(count)")
}
print("Operands by type:")
for (type, count) in opCountByType {
print(" \(type): \(count)")
}