ffi-udis86 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ module FFI
2
+ module UDis86
3
+ # udis86-ffi version
4
+ VERSION = '0.1.0'
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ require 'udis86/ud'
2
+
3
+ require 'spec_helper'
4
+
5
+ module Helpers
6
+ FILES_DIR = File.expand_path(File.join(File.dirname(__FILE__),'files'))
7
+
8
+ def ud_file(name,&block)
9
+ UD.open(File.join(FILES_DIR,name.to_s),&block)
10
+ end
11
+ end
@@ -0,0 +1,2 @@
1
+ _start:
2
+ movl (%esp,%eax,2),%ebx
@@ -0,0 +1 @@
1
+ �$
@@ -0,0 +1,2 @@
1
+ _start:
2
+ movl (%esp),%eax
@@ -0,0 +1 @@
1
+ �\$
@@ -0,0 +1,2 @@
1
+ _start:
2
+ movl 0x10(%esp),%ebx
@@ -0,0 +1,2 @@
1
+ _start:
2
+ movl $0x10,%eax
@@ -0,0 +1 @@
1
+ ���
@@ -0,0 +1,4 @@
1
+ _start:
2
+ nop
3
+ nop
4
+ ret
@@ -0,0 +1,14 @@
1
+ require 'udis86/ud'
2
+
3
+ require 'spec_helper'
4
+ require 'helpers/files'
5
+
6
+ module Helpers
7
+ def ud_operands(name)
8
+ ud_file(name) do |ud|
9
+ ud.next_insn
10
+
11
+ return ud.operands
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,72 @@
1
+ require 'udis86/operand'
2
+ require 'udis86/ud'
3
+
4
+ require 'spec_helper'
5
+ require 'helpers/operands'
6
+
7
+ describe Operand do
8
+ include Helpers
9
+
10
+ it "should provide the type of the operand" do
11
+ operands = ud_operands('operands_simple')
12
+
13
+ operands[0].type.should == :ud_op_reg
14
+ operands[1].type.should == :ud_op_imm
15
+ end
16
+
17
+ it "should provide the size of the operand" do
18
+ operands = ud_operands('operands_simple')
19
+
20
+ operands[1].size.should == 32
21
+ end
22
+
23
+ it "should provide the value of the operand" do
24
+ operands = ud_operands('operands_simple')
25
+
26
+ operands[1].value.signed_byte.should == 0x10
27
+ operands[1].value.unsigned_byte.should == 0x10
28
+ end
29
+
30
+ it "should specify value as nil for register operands" do
31
+ operands = ud_operands('operands_simple')
32
+
33
+ operands[0].value.should be_nil
34
+ end
35
+
36
+ it "should provide the base of memory operands" do
37
+ operands = ud_operands('operands_memory')
38
+
39
+ operands[1].type.should == :ud_op_mem
40
+ operands[1][:base].should == :ud_r_esp
41
+ operands[1].base.should == :esp
42
+ end
43
+
44
+ it "should provide the index of memory operands" do
45
+ operands = ud_operands('operands_index_scale')
46
+
47
+ operands[1].type.should == :ud_op_mem
48
+ operands[1][:index].should == :ud_r_eax
49
+ operands[1].index.should == :eax
50
+ end
51
+
52
+ it "should provide the offset of memory operands" do
53
+ operands = ud_operands('operands_offset')
54
+
55
+ operands[1].type.should == :ud_op_mem
56
+ operands[1].offset.byte.should == 0x10
57
+ end
58
+
59
+ it "should provide the scale of memory operands" do
60
+ operands = ud_operands('operands_index_scale')
61
+
62
+ operands[1].type.should == :ud_op_mem
63
+ operands[1].scale.should == 2
64
+ end
65
+
66
+ it "should provide the register name for register operands" do
67
+ operands = ud_operands('operands_simple')
68
+
69
+ operands[0][:base].should == :ud_r_eax
70
+ operands[0].reg.should == :eax
71
+ end
72
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ gem 'rspec', '>=1.3.0'
3
+ require 'spec'
4
+
5
+ require 'udis86/version'
6
+
7
+ include FFI
8
+ include FFI::UDis86
@@ -0,0 +1,195 @@
1
+ require 'udis86/ud'
2
+
3
+ require 'spec_helper'
4
+ require 'helpers/files'
5
+
6
+ describe UD do
7
+ include Helpers
8
+
9
+ describe "create" do
10
+ it "should accept a :mode option" do
11
+ ud = UD.create(:mode => 16)
12
+ ud.mode.should == 16
13
+ end
14
+
15
+ it "should accept a :syntax option" do
16
+ lambda {
17
+ UD.create(:syntax => :att)
18
+ }.should_not raise_error(ArgumentError)
19
+ end
20
+
21
+ it "should accept a :vendor option" do
22
+ ud = UD.create(:vendor => :amd)
23
+ ud.vendor.should == :amd
24
+ end
25
+
26
+ it "should accept a :pc option" do
27
+ ud = UD.create(:pc => 0x400000)
28
+ ud.pc.should == 0x400000
29
+ end
30
+
31
+ it "should accept a :buffer option" do
32
+ ud = UD.create(:buffer => "\x90\x90\x90")
33
+ ud.input_buffer.should == "\x90\x90\x90"
34
+ end
35
+
36
+ it "should accept a block as an input callback" do
37
+ bytes = [0x80, -1]
38
+
39
+ ud = UD.create { |ud| bytes.shift }
40
+
41
+ ud.next_insn.should == 1
42
+ ud.to_hex.should == '80'
43
+
44
+ ud.next_insn.should == 0
45
+ end
46
+ end
47
+
48
+ describe "open" do
49
+ it "should be able to open files" do
50
+ UD.open(File.join(Helpers::FILES_DIR,'simple')) do |ud|
51
+ ud.next_insn.should == 1
52
+ ud.to_hex.should == '90'
53
+
54
+ ud.next_insn.should == 1
55
+ ud.to_hex.should == '90'
56
+
57
+ ud.next_insn.should == 1
58
+ ud.to_hex.should == 'c3'
59
+
60
+ ud.next_insn.should == 0
61
+ end
62
+ end
63
+ end
64
+
65
+ describe "disassember" do
66
+ before(:each) do
67
+ File.open(File.join(Helpers::FILES_DIR,'simple'),'rb') do |file|
68
+ @string = file.read
69
+ @ud = UD.create(:buffer => @string)
70
+ end
71
+ end
72
+
73
+ it "should allow setting the mode" do
74
+ @ud.mode = 64
75
+
76
+ @ud.mode.should == 64
77
+ end
78
+
79
+ it "should allow setting the syntax" do
80
+ lambda {
81
+ @ud.syntax = :att
82
+ }.should_not raise_error(RuntimeError)
83
+ end
84
+
85
+ it "should allow setting the vendor" do
86
+ @ud.vendor = :amd
87
+
88
+ @ud.vendor.should == :amd
89
+ end
90
+
91
+ it "should allow setting the program counter (PC)" do
92
+ @ud.pc = 0x400000
93
+
94
+ @ud.pc.should == 0x400000
95
+ end
96
+
97
+ it "should provide read access to the input buffer" do
98
+ @ud.input_buffer.should == @string
99
+ end
100
+
101
+ it "should allow setting the input buffer" do
102
+ new_input = "\xc3"
103
+
104
+ @ud.input_buffer = new_input
105
+ @ud.input_buffer.should == new_input
106
+ end
107
+
108
+ it "should allow setting an input callback" do
109
+ bytes = [0x90, 0xc3]
110
+
111
+ @ud.input_callback do |ud|
112
+ bytes.shift || -1
113
+ end
114
+
115
+ @ud.next_insn.should == 1
116
+ @ud.to_asm.should == 'nop '
117
+
118
+ @ud.next_insn.should == 1
119
+ @ud.to_asm.should == 'ret '
120
+
121
+ @ud.next_insn.should == 0
122
+ end
123
+
124
+ it "should allow the skipping of input bytes" do
125
+ @ud.skip(2)
126
+
127
+ @ud.next_insn
128
+ @ud.to_asm.should == 'ret '
129
+ end
130
+
131
+ it "should get the next instruction" do
132
+ @ud.next_insn.should == 1
133
+ @ud.to_asm.should == 'nop '
134
+
135
+ @ud.next_insn.should == 1
136
+ @ud.to_asm.should == 'nop '
137
+
138
+ @ud.next_insn.should == 1
139
+ @ud.to_asm.should == 'ret '
140
+
141
+ @ud.next_insn.should == 0
142
+ end
143
+
144
+ it "should specify the instruction length" do
145
+ @ud.next_insn.should == 1
146
+ @ud.insn_length.should == 1
147
+ end
148
+
149
+ it "should specify the instruction offset" do
150
+ @ud.next_insn.should == 1
151
+ @ud.next_insn.should == 1
152
+
153
+ @ud.insn_offset.should == 1
154
+ end
155
+
156
+ it "should provide a pointer to the instruction bytes" do
157
+ @ud.next_insn.should == 1
158
+
159
+ @ud.insn_ptr.get_string(0).should == "\x90"
160
+ end
161
+
162
+ it "should provide hex form of the bytes" do
163
+ @ud.next_insn.should == 1
164
+ @ud.to_hex.should == '90'
165
+ end
166
+
167
+ it "should provide the mnemonic code of the disassembled instructions" do
168
+ @ud.next_insn.should == 1
169
+ @ud.mnemonic_code.should == :ud_inop
170
+ end
171
+
172
+ it "should provide the mnemonic of the disassembled instructions" do
173
+ @ud.next_insn.should == 1
174
+ @ud.mnemonic.should == :nop
175
+ end
176
+
177
+ it "should provide the assembly form of the disassembled instructions" do
178
+ @ud.next_insn.should == 1
179
+ @ud.to_asm.should == 'nop '
180
+ end
181
+
182
+ it "should provide the disassembled operands of the instruction" do
183
+ @ud.next_insn.should == 1
184
+ @ud.operands.should == []
185
+ end
186
+
187
+ it "should disassemble every byte" do
188
+ ops = ['nop ', 'nop ', 'ret ']
189
+
190
+ @ud.disassemble do |ud|
191
+ ud.to_asm.should == ops.shift
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,25 @@
1
+ require 'udis86/version'
2
+
3
+ require 'spec_helper'
4
+
5
+ describe UDis86 do
6
+ it "should have a VERSION constant" do
7
+ UDis86.const_defined?('VERSION').should == true
8
+ end
9
+
10
+ describe "types" do
11
+ it "should define syntices" do
12
+ SYNTAX[:att].should == :ud_translate_att
13
+ SYNTAX[:intel].should == :ud_translate_intel
14
+ end
15
+
16
+ it "should define mappings from :ud_type to register names" do
17
+ ud_type = UDis86.enum_type(:ud_type)
18
+
19
+ UDis86::REGS.each do |type,name|
20
+ :"ud_r_#{name}".should == type
21
+ ud_type[ud_type[type]].should == type
22
+ end
23
+ end
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ffi-udis86
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Postmodern
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-19 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ffi
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.6.2
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.3.0
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: yard
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.5.3
44
+ version:
45
+ description: Ruby FFI bindings for udis86, a x86 and x86-64 disassembler.
46
+ email: postmodern.mod3@gmail.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - ChangeLog.md
53
+ - LICENSE.txt
54
+ - README.md
55
+ files:
56
+ - .gitignore
57
+ - .specopts
58
+ - .yardopts
59
+ - ChangeLog.md
60
+ - LICENSE.txt
61
+ - README.md
62
+ - Rakefile
63
+ - ffi-udis86.gemspec
64
+ - lib/udis86.rb
65
+ - lib/udis86/ffi.rb
66
+ - lib/udis86/operand.rb
67
+ - lib/udis86/operand_pointer.rb
68
+ - lib/udis86/operand_value.rb
69
+ - lib/udis86/types.rb
70
+ - lib/udis86/ud.rb
71
+ - lib/udis86/version.rb
72
+ - spec/helpers/files.rb
73
+ - spec/helpers/files/operands_index_scale
74
+ - spec/helpers/files/operands_index_scale.s
75
+ - spec/helpers/files/operands_memory
76
+ - spec/helpers/files/operands_memory.s
77
+ - spec/helpers/files/operands_offset
78
+ - spec/helpers/files/operands_offset.s
79
+ - spec/helpers/files/operands_simple
80
+ - spec/helpers/files/operands_simple.s
81
+ - spec/helpers/files/simple
82
+ - spec/helpers/files/simple.s
83
+ - spec/helpers/operands.rb
84
+ - spec/operand_spec.rb
85
+ - spec/spec_helper.rb
86
+ - spec/ud_spec.rb
87
+ - spec/udis86_spec.rb
88
+ has_rdoc: yard
89
+ homepage: http://github.com/sophsec/ffi-udis86
90
+ licenses: []
91
+
92
+ post_install_message:
93
+ rdoc_options:
94
+ - --charset=UTF-8
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: "0"
102
+ version:
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: "0"
108
+ version:
109
+ requirements: []
110
+
111
+ rubyforge_project:
112
+ rubygems_version: 1.3.5
113
+ signing_key:
114
+ specification_version: 3
115
+ summary: Ruby FFI bindings for udis86, a x86 and x86-64 disassembler.
116
+ test_files:
117
+ - spec/spec_helper.rb
118
+ - spec/udis86_spec.rb
119
+ - spec/ud_spec.rb
120
+ - spec/helpers/files.rb
121
+ - spec/helpers/operands.rb
122
+ - spec/operand_spec.rb