ronin-asm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.document +4 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +11 -0
  4. data/.rspec +1 -0
  5. data/.yardopts +1 -0
  6. data/COPYING.txt +674 -0
  7. data/ChangeLog.md +10 -0
  8. data/Gemfile +19 -0
  9. data/README.md +142 -0
  10. data/Rakefile +44 -0
  11. data/data/ronin/asm/freebsd/amd64/syscalls.yml +415 -0
  12. data/data/ronin/asm/freebsd/x86/syscalls.yml +415 -0
  13. data/data/ronin/asm/linux/amd64/syscalls.yml +306 -0
  14. data/data/ronin/asm/linux/x86/syscalls.yml +339 -0
  15. data/data/ronin/gen/asm/source_file.s.erb +4 -0
  16. data/gemspec.yml +20 -0
  17. data/lib/ronin/asm.rb +25 -0
  18. data/lib/ronin/asm/archs.rb +23 -0
  19. data/lib/ronin/asm/archs/amd64.rb +99 -0
  20. data/lib/ronin/asm/archs/x86.rb +166 -0
  21. data/lib/ronin/asm/asm.rb +66 -0
  22. data/lib/ronin/asm/config.rb +39 -0
  23. data/lib/ronin/asm/immediate_operand.rb +76 -0
  24. data/lib/ronin/asm/instruction.rb +65 -0
  25. data/lib/ronin/asm/memory_operand.rb +109 -0
  26. data/lib/ronin/asm/os.rb +24 -0
  27. data/lib/ronin/asm/os/freebsd.rb +34 -0
  28. data/lib/ronin/asm/os/linux.rb +34 -0
  29. data/lib/ronin/asm/os/os.rb +40 -0
  30. data/lib/ronin/asm/program.rb +476 -0
  31. data/lib/ronin/asm/register.rb +110 -0
  32. data/lib/ronin/asm/shellcode.rb +70 -0
  33. data/lib/ronin/asm/syntax.rb +23 -0
  34. data/lib/ronin/asm/syntax/att.rb +136 -0
  35. data/lib/ronin/asm/syntax/common.rb +202 -0
  36. data/lib/ronin/asm/syntax/intel.rb +150 -0
  37. data/lib/ronin/asm/version.rb +27 -0
  38. data/ronin-asm.gemspec +61 -0
  39. data/spec/asm_spec.rb +8 -0
  40. data/spec/helpers/database.rb +7 -0
  41. data/spec/immediate_operand_spec.rb +77 -0
  42. data/spec/instruction_spec.rb +62 -0
  43. data/spec/memory_operand_spec.rb +80 -0
  44. data/spec/program_spec.rb +365 -0
  45. data/spec/register_spec.rb +110 -0
  46. data/spec/shellcode_spec.rb +34 -0
  47. data/spec/spec_helper.rb +10 -0
  48. data/spec/syntax/att_spec.rb +171 -0
  49. data/spec/syntax/common_spec.rb +42 -0
  50. data/spec/syntax/intel_spec.rb +156 -0
  51. metadata +163 -0
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'ronin/asm/shellcode'
3
+
4
+ describe ASM::Shellcode do
5
+ describe "#assemble", :yasm => true do
6
+ subject do
7
+ described_class.new do
8
+ xor eax, eax
9
+ push eax
10
+ push 0x68732f2f
11
+ push 0x6e69622f
12
+ mov esp, ebx
13
+ push eax
14
+ push ebx
15
+ mov esp, ecx
16
+ xor edx, edx
17
+ mov 0xb, al
18
+ int 0x80
19
+ end
20
+ end
21
+
22
+ let(:shellcode) { "f1\xC0fPfh//shfh/binf\x89\xE3fPfSf\x89\xE1f1\xD2\xB0\v\xCD\x80" }
23
+
24
+ it "assemble down to raw machine code" do
25
+ subject.assemble.should == shellcode
26
+ end
27
+
28
+ context "with :syntax => :intel" do
29
+ it "assemble down to raw machine code" do
30
+ subject.assemble(:syntax => :intel).should == shellcode
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,10 @@
1
+ require 'rspec'
2
+ require 'ronin/asm/version'
3
+
4
+ include Ronin
5
+ include Ronin::ASM
6
+
7
+ RSpec.configure do |specs|
8
+ specs.treat_symbols_as_metadata_keys_with_true_values = true
9
+ specs.filter_run_excluding :yasm
10
+ end
@@ -0,0 +1,171 @@
1
+ require 'spec_helper'
2
+
3
+ require 'ronin/asm/syntax/att'
4
+ require 'ronin/asm/register'
5
+ require 'ronin/asm/immediate_operand'
6
+ require 'ronin/asm/memory_operand'
7
+ require 'ronin/asm/instruction'
8
+ require 'ronin/asm/program'
9
+
10
+ describe ASM::Syntax::ATT do
11
+ subject { described_class }
12
+
13
+ describe "emit_register" do
14
+ let(:register) { Register.new(:eax, 4) }
15
+
16
+ it "should prepend a '%' to the register name" do
17
+ subject.emit_register(register).should == "%eax"
18
+ end
19
+ end
20
+
21
+ describe "emit_immediate_operand" do
22
+ let(:operand) { ImmediateOperand.new(255, 1) }
23
+
24
+ it "should prepend a '$' to the immediate" do
25
+ subject.emit_immediate_operand(operand).should == "$0xff"
26
+ end
27
+ end
28
+
29
+ describe "emit_memory_operand" do
30
+ let(:register) { Register.new(:eax, 4) }
31
+ let(:operand) { MemoryOperand.new(register) }
32
+
33
+ it "should enclose the memory in parenthesis" do
34
+ subject.emit_memory_operand(operand).should == "(%eax)"
35
+ end
36
+
37
+ context "with an offset" do
38
+ let(:offset) { 255 }
39
+ let(:operand) { MemoryOperand.new(register,offset) }
40
+
41
+ it "should prepend the offset as an integer" do
42
+ subject.emit_memory_operand(operand).should == "0xff(%eax)"
43
+ end
44
+
45
+ context "when 0" do
46
+ let(:operand) { MemoryOperand.new(register,0) }
47
+
48
+ it "should omit the offset" do
49
+ subject.emit_memory_operand(operand).should == "(%eax)"
50
+ end
51
+ end
52
+ end
53
+
54
+ context "with an index" do
55
+ let(:index) { Register.new(:esi, 4) }
56
+ let(:operand) { MemoryOperand.new(register,0,index) }
57
+
58
+ it "should include the index argument" do
59
+ subject.emit_memory_operand(operand).should == "(%eax,%esi)"
60
+ end
61
+
62
+ context "with a scale" do
63
+ let(:scale) { 4 }
64
+ let(:operand) { MemoryOperand.new(register,0,index,scale) }
65
+
66
+ it "should prepend the scale argument as a decimal" do
67
+ subject.emit_memory_operand(operand).should == "(%eax,%esi,#{scale})"
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "emit_instruction" do
74
+ context "with no operands" do
75
+ let(:instruction) { Instruction.new(:ret, []) }
76
+
77
+ it "should emit the instruction name" do
78
+ subject.emit_instruction(instruction).should == 'ret'
79
+ end
80
+ end
81
+
82
+ context "with one operand" do
83
+ context "with width of 1" do
84
+ let(:immediate) { ImmediateOperand.new(0x80, 1) }
85
+ let(:instruction) { Instruction.new(:int, [immediate]) }
86
+
87
+ it "should not append a size specifier to the instruction name" do
88
+ subject.emit_instruction(instruction).should == "int\t$0x80"
89
+ end
90
+ end
91
+ end
92
+
93
+ context "with multiple operands" do
94
+ let(:register) { Register.new(:eax, 4) }
95
+ let(:immediate) { ImmediateOperand.new(0xff, 1) }
96
+ let(:instruction) { Instruction.new(:mov, [immediate, register]) }
97
+
98
+ it "should add a size specifier to the instruction name" do
99
+ subject.emit_instruction(instruction).should =~ /^movl/
100
+ end
101
+
102
+ it "should emit the operands" do
103
+ subject.emit_instruction(instruction).should == "movl\t$0xff,\t%eax"
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "emit_program" do
109
+ let(:program) do
110
+ Program.new do
111
+ mov 0xff, eax
112
+ ret
113
+ end
114
+ end
115
+
116
+ it "should output the _start label and the program" do
117
+ asm = subject.emit_program(program)
118
+
119
+ asm.should == [
120
+ "_start:",
121
+ "\tmovl\t$0xff,\t%eax",
122
+ "\tret",
123
+ ""
124
+ ].join($/)
125
+ end
126
+
127
+ context "when emitting labels" do
128
+ let(:program) do
129
+ Program.new do
130
+ mov 0, eax
131
+
132
+ _loop do
133
+ inc eax
134
+ cmp eax, 10
135
+ jl :_loop
136
+ end
137
+
138
+ ret
139
+ end
140
+ end
141
+
142
+ it "should emit both labels and instructions" do
143
+ subject.emit_program(program).should == [
144
+ "_start:",
145
+ "\tmovl\t$0x0,\t%eax",
146
+ "_loop:",
147
+ "\tincl\t%eax",
148
+ "\tcmpl\t%eax,\t$0xa",
149
+ "\tjl\t_loop",
150
+ "\tret",
151
+ ""
152
+ ].join($/)
153
+ end
154
+ end
155
+
156
+ context "when the program arch is :amd64" do
157
+ let(:program) do
158
+ Program.new(:arch => :amd64) do
159
+ push rax
160
+ push rbx
161
+ mov 0xff, rax
162
+ ret
163
+ end
164
+ end
165
+
166
+ it "should include start with the '.code64' directive" do
167
+ subject.emit_program(program).should =~ /^\.code64$/
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ require 'ronin/asm/syntax/common'
4
+
5
+ describe ASM::Syntax::Common do
6
+ subject { described_class }
7
+
8
+ describe "emit_keyword" do
9
+ let(:name) { :_start }
10
+
11
+ it "should convert a keyword to a String" do
12
+ subject.emit_keyword(name).should == name.to_s
13
+ end
14
+ end
15
+
16
+ describe "emit_integer" do
17
+ let(:integer) { 255 }
18
+ let(:hexadecimal) { "0xff" }
19
+
20
+ it "should convert it into a hexadecimal value" do
21
+ subject.emit_integer(integer).should == hexadecimal
22
+ end
23
+
24
+ context "when given a negative number" do
25
+ let(:negative) { -255 }
26
+ let(:hexadecimal) { "-0xff" }
27
+
28
+ it "should convert it into a hexadecimal value" do
29
+ subject.emit_integer(negative).should == hexadecimal
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "emit_label" do
35
+ let(:name) { :_start }
36
+ let(:label) { '_start:' }
37
+
38
+ it "should append a ':' to the name" do
39
+ subject.emit_label(name).should == label
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,156 @@
1
+ require 'spec_helper'
2
+
3
+ require 'ronin/asm/syntax/intel'
4
+ require 'ronin/asm/register'
5
+ require 'ronin/asm/immediate_operand'
6
+ require 'ronin/asm/memory_operand'
7
+ require 'ronin/asm/instruction'
8
+ require 'ronin/asm/program'
9
+
10
+ describe ASM::Syntax::Intel do
11
+ subject { described_class }
12
+
13
+ describe "emit_register" do
14
+ let(:register) { Register.new(:eax, 4) }
15
+
16
+ it "should return the register name" do
17
+ subject.emit_register(register).should == "eax"
18
+ end
19
+ end
20
+
21
+ describe "emit_immediate_operand" do
22
+ let(:operand) { ImmediateOperand.new(255, 1) }
23
+
24
+ it "should prepend a size specifier" do
25
+ subject.emit_immediate_operand(operand).should == "BYTE 0xff"
26
+ end
27
+ end
28
+
29
+ describe "emit_memory_operand" do
30
+ let(:register) { Register.new(:eax, 4) }
31
+ let(:operand) { MemoryOperand.new(register) }
32
+
33
+ it "should enclose the memory in brackets" do
34
+ subject.emit_memory_operand(operand).should == "[eax]"
35
+ end
36
+
37
+ context "with an offset" do
38
+ let(:offset) { 255 }
39
+ let(:operand) { MemoryOperand.new(register,offset) }
40
+
41
+ it "should add the offset to the base" do
42
+ subject.emit_memory_operand(operand).should == "[eax+0xff]"
43
+ end
44
+
45
+ context "when 0" do
46
+ let(:operand) { MemoryOperand.new(register,0) }
47
+
48
+ it "should omit the offset" do
49
+ subject.emit_memory_operand(operand).should == "[eax]"
50
+ end
51
+ end
52
+ end
53
+
54
+ context "with an index" do
55
+ let(:index) { Register.new(:esi, 4) }
56
+ let(:operand) { MemoryOperand.new(register,0,index) }
57
+
58
+ it "should add the index to the base" do
59
+ subject.emit_memory_operand(operand).should == "[eax+esi]"
60
+ end
61
+
62
+ context "with a scale" do
63
+ let(:scale) { 4 }
64
+ let(:operand) { MemoryOperand.new(register,0,index,scale) }
65
+
66
+ it "should multiple the index by the scale" do
67
+ subject.emit_memory_operand(operand).should == "[eax+esi*0x4]"
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "emit_instruction" do
74
+ context "with no operands" do
75
+ let(:instruction) { Instruction.new(:ret, []) }
76
+
77
+ it "should emit the instruction name" do
78
+ subject.emit_instruction(instruction).should == 'ret'
79
+ end
80
+ end
81
+
82
+ context "with multiple operands" do
83
+ let(:register) { Register.new(:eax, 4) }
84
+ let(:immediate) { ImmediateOperand.new(0xff, 1) }
85
+ let(:instruction) { Instruction.new(:mov, [immediate, register]) }
86
+
87
+ it "should emit the operands" do
88
+ subject.emit_instruction(instruction).should == "mov\teax,\tBYTE 0xff"
89
+ end
90
+ end
91
+ end
92
+
93
+ describe "emit_program" do
94
+ let(:program) do
95
+ Program.new do
96
+ mov 0xff, eax
97
+ ret
98
+ end
99
+ end
100
+
101
+ it "should output the _start label and the program" do
102
+ asm = subject.emit_program(program)
103
+
104
+ asm.should == [
105
+ "_start:",
106
+ "\tmov\teax,\tBYTE 0xff",
107
+ "\tret",
108
+ ""
109
+ ].join($/)
110
+ end
111
+
112
+ context "when emitting labels" do
113
+ let(:program) do
114
+ Program.new do
115
+ mov 0, eax
116
+
117
+ _loop do
118
+ inc eax
119
+ cmp eax, 10
120
+ jl :_loop
121
+ end
122
+
123
+ ret
124
+ end
125
+ end
126
+
127
+ it "should emit both labels and instructions" do
128
+ subject.emit_program(program).should == [
129
+ "_start:",
130
+ "\tmov\teax,\tBYTE 0x0",
131
+ "_loop:",
132
+ "\tinc\teax",
133
+ "\tcmp\tBYTE 0xa,\teax",
134
+ "\tjl\t_loop",
135
+ "\tret",
136
+ ""
137
+ ].join($/)
138
+ end
139
+ end
140
+
141
+ context "when the program arch is :amd64" do
142
+ let(:program) do
143
+ Program.new(:arch => :amd64) do
144
+ push rax
145
+ push rbx
146
+ mov 0xff, rax
147
+ ret
148
+ end
149
+ end
150
+
151
+ it "should include start with the '.code64' directive" do
152
+ subject.emit_program(program).should =~ /^BITS 64$/
153
+ end
154
+ end
155
+ end
156
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ronin-asm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Postmodern
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: data_paths
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '0.3'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '0.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: ruby-yasm
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '0.2'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '0.2'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: yard
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '0.7'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '0.7'
78
+ description: ronin-asm is a Ruby DSL for crafting Assmebly programs and Shellcode.
79
+ email: postmodern.mod3@gmail.com
80
+ executables: []
81
+ extensions: []
82
+ extra_rdoc_files:
83
+ - COPYING.txt
84
+ - ChangeLog.md
85
+ - README.md
86
+ files:
87
+ - .document
88
+ - .gemtest
89
+ - .gitignore
90
+ - .rspec
91
+ - .yardopts
92
+ - COPYING.txt
93
+ - ChangeLog.md
94
+ - Gemfile
95
+ - README.md
96
+ - Rakefile
97
+ - data/ronin/asm/freebsd/amd64/syscalls.yml
98
+ - data/ronin/asm/freebsd/x86/syscalls.yml
99
+ - data/ronin/asm/linux/amd64/syscalls.yml
100
+ - data/ronin/asm/linux/x86/syscalls.yml
101
+ - data/ronin/gen/asm/source_file.s.erb
102
+ - gemspec.yml
103
+ - lib/ronin/asm.rb
104
+ - lib/ronin/asm/archs.rb
105
+ - lib/ronin/asm/archs/amd64.rb
106
+ - lib/ronin/asm/archs/x86.rb
107
+ - lib/ronin/asm/asm.rb
108
+ - lib/ronin/asm/config.rb
109
+ - lib/ronin/asm/immediate_operand.rb
110
+ - lib/ronin/asm/instruction.rb
111
+ - lib/ronin/asm/memory_operand.rb
112
+ - lib/ronin/asm/os.rb
113
+ - lib/ronin/asm/os/freebsd.rb
114
+ - lib/ronin/asm/os/linux.rb
115
+ - lib/ronin/asm/os/os.rb
116
+ - lib/ronin/asm/program.rb
117
+ - lib/ronin/asm/register.rb
118
+ - lib/ronin/asm/shellcode.rb
119
+ - lib/ronin/asm/syntax.rb
120
+ - lib/ronin/asm/syntax/att.rb
121
+ - lib/ronin/asm/syntax/common.rb
122
+ - lib/ronin/asm/syntax/intel.rb
123
+ - lib/ronin/asm/version.rb
124
+ - ronin-asm.gemspec
125
+ - spec/asm_spec.rb
126
+ - spec/helpers/database.rb
127
+ - spec/immediate_operand_spec.rb
128
+ - spec/instruction_spec.rb
129
+ - spec/memory_operand_spec.rb
130
+ - spec/program_spec.rb
131
+ - spec/register_spec.rb
132
+ - spec/shellcode_spec.rb
133
+ - spec/spec_helper.rb
134
+ - spec/syntax/att_spec.rb
135
+ - spec/syntax/common_spec.rb
136
+ - spec/syntax/intel_spec.rb
137
+ homepage: https://github.com/ronin-ruby/ronin-asm#readme
138
+ licenses:
139
+ - GPL-3
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ! '>='
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements:
157
+ - yasm >= 0.6.0
158
+ rubyforge_project:
159
+ rubygems_version: 1.8.23
160
+ signing_key:
161
+ specification_version: 3
162
+ summary: A Ruby DSL for crafting Assembly programs and Shellcode.
163
+ test_files: []