Skip to content

tenderlove/hatstone

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hatstone

This is a very simple wrapper around Capstone. Capstone is a library that disassembles binary data in to assembly code. This library, Hatstone, offers a Ruby interface to the Capstone library.

Why a new library?

Crabstone is a different wrapper for Capstone. I've been using Crabstone for quite a while and I really love it. However, I've been running in to problems with libffi, and especially problems on my M1 Mac where I have both the ARM64 installation and x86 installation of Capstone on the same system (via two installations of Homebrew).

This C extension finds the right Capstone library at gem installation time, so you can be assured that if you can install this gem, you can use this gem (hopefully!!)

Installation

Make sure you have Capstone installed. On macOS this is brew install capstone. Then install this gem via the normal method gem install hatstone.

Note: RISCV support is only available in Capstone version 5 or later.

Example Usage

In this example we'll assemble some simple ARM64 instructions and then use Hatstone to disassemble them.

require "hatstone"

# ARM64 movz instruction
def movz reg, imm
  insn = 0b0_10_100101_00_0000000000000000_00000
  insn |= (1 << 31)  # 64 bit
  insn |= (imm << 5) # immediate
  insn |= reg        # reg
end

# ARM64 ret instruction
def ret xn = 30
  insn = 0b1101011_0_0_10_11111_0000_0_0_00000_00000
  insn |= (xn << 5)
  insn
end

# Assemble some instructions
insns = [
  movz(0, 0x2a), # mov X0, 0x2a
  ret            # ret
].pack("L<L<")

# Now disassemble the instructions with Hatstone
hs = Hatstone.new(Hatstone::ARCH_ARM64, Hatstone::MODE_ARM)

hs.disasm(insns, 0x0).each do |insn|
  puts "%#05x %s %s" % [insn.address, insn.mnemonic, insn.op_str]
end

Another example, this time for RISCV64

require 'hatstone'

def lui reg, imm
  insn = 0b00000000000000000000_00000_0110111 
  insn |= (reg << 7)  # Set destination register 
  insn |= (imm & 0xFFFFF) << 12  # Set 20-bit immediate
  insn
end

def auipc reg, imm
  insn = 0b00000000000000000000_00000_0010111  # auipc base
  insn |= (reg << 7)  # Set destination register
  insn |= (imm & 0xFFFFF) << 12  # Set 20-bit immediate
  insn
end

def addi reg, imm
  insn = 0b00000000000000000000_00000_0010011  # addi base
  insn |= (reg << 7)  # Set destination register
  insn |= (reg << 15)  # Set source register
  insn |= (imm & 0xFFF) << 20  # Set 12-bit immediate
  insn
end

insns = [
  lui(17, 64), # lui a7,64
  lui(10, 1),  # lui a0,1
  auipc(0, 0), # auipc a0,0x0
  addi(0, 36), # addi a0,a0,36
].pack("L<*")

hs = Hatstone.new(Hatstone::ARCH_RISCV, Hatstone::MODE_RISCV64)

hs.disasm(insns, 0x0).each do |insn|
  puts "%#05x %s %s" % [insn.address, insn.mnemonic, insn.op_str]
end

About

A minimal Ruby wrapper for Capstone disassembler

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published