Class: Crabstone::Instruction
- Inherits:
-
Object
- Object
- Crabstone::Instruction
show all
- Defined in:
- lib/crabstone/instruction.rb
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
#initialize(csh, insn, arch) ⇒ Instruction
Returns a new instance of Instruction.
11
12
13
14
15
16
|
# File 'lib/crabstone/instruction.rb', line 11
def initialize(csh, insn, arch)
@arch_module = Arch.module_of(arch)
@csh = csh
@raw_insn = insn
init_detail(insn[:detail]) if detailed?
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args) ⇒ Object
So an Instruction should respond to all the methods in Instruction, and all the methods in the Arch specific Instruction class. The methods / members that have special handling for detail mode or diet mode are handled above. The rest is dynamically dispatched below.
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
# File 'lib/crabstone/instruction.rb', line 123
def method_missing(meth, *args)
return raw_insn[meth] if raw_insn.members.include?(meth)
unless detailed?
raise(
NoMethodError,
"Either CS_DETAIL is off, or #{self.class} doesn't implement #{meth}"
)
end
return @arch_insn.__send__(meth, *args) if @arch_insn.respond_to?(meth)
return @arch_insn[meth] if @arch_insn.members.include?(meth)
super
end
|
Instance Attribute Details
#csh ⇒ Object
Returns the value of attribute csh.
9
10
11
|
# File 'lib/crabstone/instruction.rb', line 9
def csh
@csh
end
|
#raw_insn ⇒ Object
Returns the value of attribute raw_insn.
9
10
11
|
# File 'lib/crabstone/instruction.rb', line 9
def raw_insn
@raw_insn
end
|
Instance Method Details
#bytes ⇒ Object
115
116
117
|
# File 'lib/crabstone/instruction.rb', line 115
def bytes
raw_insn[:bytes].first(raw_insn[:size])
end
|
#detail ⇒ Object
37
38
39
40
|
# File 'lib/crabstone/instruction.rb', line 37
def detail
raise_unless_detailed
@detail
end
|
#detailed? ⇒ Boolean
It’s more informative to raise if CS_DETAIL is off than just return nil
33
34
35
|
# File 'lib/crabstone/instruction.rb', line 33
def detailed?
!@raw_insn[:detail].pointer.null?
end
|
#group?(group_id) ⇒ Boolean
60
61
62
63
64
|
# File 'lib/crabstone/instruction.rb', line 60
def group?(group_id)
raise_unless_detailed
raise_if_diet
Binding.cs_insn_group(csh, raw_insn, group_id)
end
|
#group_name(grp) ⇒ Object
25
26
27
28
29
30
|
# File 'lib/crabstone/instruction.rb', line 25
def group_name(grp)
raise_if_diet
name = Binding.cs_group_name(csh, Integer(grp))
Crabstone::Error.raise!(ErrCsh) unless name
name
end
|
#groups ⇒ Object
54
55
56
57
58
|
# File 'lib/crabstone/instruction.rb', line 54
def groups
raise_unless_detailed
raise_if_diet
@groups
end
|
#mnemonic ⇒ Object
96
97
98
99
|
# File 'lib/crabstone/instruction.rb', line 96
def mnemonic
raise_if_diet
raw_insn[:mnemonic]
end
|
#name ⇒ Object
18
19
20
21
22
23
|
# File 'lib/crabstone/instruction.rb', line 18
def name
raise_if_diet
name = Binding.cs_insn_name(csh, id)
Crabstone::Error.raise!(ErrCsh) unless name
name
end
|
#op_count(op_type = nil) ⇒ Object
106
107
108
109
110
111
112
113
|
# File 'lib/crabstone/instruction.rb', line 106
def op_count(op_type = nil)
raise_unless_detailed
if op_type
Binding.cs_op_count(csh, raw_insn, op_type)
else
operands.size
end
end
|
#op_str ⇒ Object
101
102
103
104
|
# File 'lib/crabstone/instruction.rb', line 101
def op_str
raise_if_diet
raw_insn[:op_str]
end
|
#reads_reg?(reg) ⇒ Boolean
66
67
68
69
70
|
# File 'lib/crabstone/instruction.rb', line 66
def reads_reg?(reg)
raise_unless_detailed
raise_if_diet
Binding.cs_reg_read(csh, raw_insn, @arch_module.register(reg))
end
|
#regs_access ⇒ {:regs_read => Array<Integer>, :regs_write => Array<Integer>}
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
# File 'lib/crabstone/instruction.rb', line 79
def regs_access
raise_unless_detailed
raise_if_diet
regs_read = FFI::MemoryPointer.new(:uint16, 64)
regs_read_count = FFI::MemoryPointer.new(:uint8)
regs_write = FFI::MemoryPointer.new(:uint16, 64)
regs_write_count = FFI::MemoryPointer.new(:uint8)
err = Binding.cs_regs_access(csh, raw_insn, regs_read, regs_read_count, regs_write, regs_write_count)
Crabstone::Error.raise_errno(err) if err.nonzero?
{
regs_read: regs_read.read_array_of_short(regs_read_count.read_int8),
regs_write: regs_write.read_array_of_short(regs_write_count.read_int8)
}
end
|
#regs_read ⇒ Object
42
43
44
45
46
|
# File 'lib/crabstone/instruction.rb', line 42
def regs_read
raise_unless_detailed
raise_if_diet
@regs_read
end
|
#regs_write ⇒ Object
48
49
50
51
52
|
# File 'lib/crabstone/instruction.rb', line 48
def regs_write
raise_unless_detailed
raise_if_diet
@regs_write
end
|
#respond_to_missing?(meth, include_private = true) ⇒ Boolean
141
142
143
144
145
146
147
148
|
# File 'lib/crabstone/instruction.rb', line 141
def respond_to_missing?(meth, include_private = true)
return true if raw_insn.members.include?(meth)
return super unless detailed?
return true if @arch_insn.respond_to?(meth)
return true if @arch_insn.members.include?(meth)
super
end
|
#writes_reg?(reg) ⇒ Boolean
72
73
74
75
76
|
# File 'lib/crabstone/instruction.rb', line 72
def writes_reg?(reg)
raise_unless_detailed
raise_if_diet
Binding.cs_reg_write(csh, raw_insn, @arch_module.register(reg))
end
|