Skip to content

Commit

Permalink
Merge pull request #6 from furunkel/remove_disassembly
Browse files Browse the repository at this point in the history
Remove Disassembly class
  • Loading branch information
bnagy committed Sep 14, 2015
2 parents 5ef6f24 + ab135a5 commit e3e0a55
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 58 deletions.
17 changes: 6 additions & 11 deletions examples/hello_world.rb
Expand Up @@ -21,20 +21,15 @@

begin
cs.decomposer = true
cs.disasm(arm, 0x1000).each {|i|

# disasm is an array of Crabstone::Instruction objects
disasm = cs.disasm(arm, 0x1000)

disasm.each {|i|
printf("0x%x:\t%s\t\t%s\n",i.address, i.mnemonic, i.op_str)
}
# disasm is a Crabstone::Disassembly object that mixes in Enumerable

disasm = cs.disasm(arm, 0x1000)
# insns is now an Array of Crabstone::Instructions, with an ObjectSpace
# finalizer proc attached to the Array itself. Try not to do this unless
# you REALLY REALLY HAVE TO, because there are all kinds of horrible
# things that can go wrong, especially if you start keeping refs to any of
# the Instructions inside the array.
insns = disasm.insns
# disasm, on the other hand, is lazy, and doesn't call into C until it has
# to. It automatically frees resources. However, it WILL make a new C call
# to cs_disasm_ex every time you invoke an Enumerable method like this.
puts disasm.map {|i| "0x%x:\t%s\t\t%s\n" % [i.address, i.mnemonic, i.op_str]}

rescue
Expand Down
70 changes: 23 additions & 47 deletions lib/crabstone.rb
Expand Up @@ -425,51 +425,6 @@ def raise_if_diet

end

class Disassembly

include Enumerable

attr_reader :engine
attr_reader :insns

def initialize(engine, code, offset, count = 0)
@engine = engine
@code = code
@offset = offset
@count = count

disasm!
end

def each(&block)
insns.each(&block)
end

private
def disasm!
insn_ptr = FFI::MemoryPointer.new :pointer
insn_count = Binding.cs_disasm(
@engine.csh,
@code,
@code.bytesize,
@offset,
@count,
insn_ptr
)
Crabstone.raise_errno(errno) if insn_count.zero?

@insns = (0...insn_count * Binding::Instruction.size).step(Binding::Instruction.size).map do |off|
cs_insn_ptr = Binding.malloc Binding::Instruction.size
cs_insn = Binding::Instruction.new cs_insn_ptr
Binding.memcpy(cs_insn_ptr, insn_ptr.read_pointer + off, Binding::Instruction.size)
Instruction.new engine.csh, cs_insn, engine.arch
end

@insns.freeze

Binding.free(insn_ptr.read_pointer)
end
end

class Disassembler

Expand Down Expand Up @@ -574,9 +529,30 @@ def reg_name regid
name
end

def disasm code, offset, count=0
def disasm code, offset, count = 0
return [] if code.empty?
Disassembly.new self, code, offset, count

insn_ptr = FFI::MemoryPointer.new :pointer
insn_count = Binding.cs_disasm(
@csh,
code,
code.bytesize,
offset,
count,
insn_ptr
)
Crabstone.raise_errno(errno) if insn_count.zero?

insns = (0...insn_count * Binding::Instruction.size).step(Binding::Instruction.size).map do |off|
cs_insn_ptr = Binding.malloc Binding::Instruction.size
cs_insn = Binding::Instruction.new cs_insn_ptr
Binding.memcpy(cs_insn_ptr, insn_ptr.read_pointer + off, Binding::Instruction.size)
Instruction.new @csh, cs_insn, @arch
end

Binding.free(insn_ptr.read_pointer)

insns
end

def set_raw_option opt, val
Expand Down

0 comments on commit e3e0a55

Please sign in to comment.