ronin-asm 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.
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,110 @@
1
+ #
2
+ # Ronin ASM - A Ruby DSL for crafting Assembly programs and Shellcode.
3
+ #
4
+ # Copyright (c) 2007-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ #
6
+ # This file is part of Ronin ASM.
7
+ #
8
+ # Ronin is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Ronin is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Ronin. If not, see <http://www.gnu.org/licenses/>
20
+ #
21
+
22
+ require 'ronin/asm/memory_operand'
23
+
24
+ module Ronin
25
+ module ASM
26
+ #
27
+ # Represents a Register.
28
+ #
29
+ class Register < Struct.new(:name, :width, :general)
30
+
31
+ #
32
+ # Initializes a register.
33
+ #
34
+ # @param [Symbol] name
35
+ # The register name.
36
+ #
37
+ # @param [Integer] width
38
+ # The width of the register.
39
+ #
40
+ # @param [Boolean] general
41
+ # Specifies whether the register is a General Purpose Register (GPR).
42
+ #
43
+ def initialize(name,width,general=false)
44
+ super(name,width,general)
45
+ end
46
+
47
+ #
48
+ # Adds an offset to the value within the register and dereferences the
49
+ # address.
50
+ #
51
+ # @param [MemoryOperand, Register, Integer] offset
52
+ # The offset to add to the value of the register.
53
+ #
54
+ # @return [MemoryOperand]
55
+ # The new Memory Operand.
56
+ #
57
+ # @raise [TypeError]
58
+ # the `offset` was not an {MemoryOperand}, {Register} or Integer.
59
+ #
60
+ def +(offset)
61
+ case offset
62
+ when MemoryOperand
63
+ MemoryOperand.new(self,offset.offset,offset.index,offset.scale)
64
+ when Register
65
+ MemoryOperand.new(self,0,offset)
66
+ when Integer
67
+ MemoryOperand.new(self,offset)
68
+ else
69
+ raise(TypeError,"offset was not an MemoryOperand, Register or Integer")
70
+ end
71
+ end
72
+
73
+ #
74
+ # Substracts from the value within the register and dereferences the
75
+ # address.
76
+ #
77
+ # @param [Integer] offset
78
+ # The value to subtract from the value of the register.
79
+ #
80
+ # @return [MemoryOperand]
81
+ # The new Memory Operand.
82
+ #
83
+ def -(offset)
84
+ MemoryOperand.new(self,-offset)
85
+ end
86
+
87
+ #
88
+ # Multiples the value within the register.
89
+ #
90
+ # @param [Integer] scale
91
+ # The scale to multiply the value within register by.
92
+ #
93
+ # @return [MemoryOperand]
94
+ # The new Memory Operand.
95
+ #
96
+ def *(scale)
97
+ MemoryOperand.new(nil,0,self,scale)
98
+ end
99
+
100
+ #
101
+ # @return [String]
102
+ # The register's name.
103
+ #
104
+ def to_s
105
+ self.name.to_s
106
+ end
107
+
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,70 @@
1
+ #
2
+ # Ronin ASM - A Ruby DSL for crafting Assembly programs and Shellcode.
3
+ #
4
+ # Copyright (c) 2007-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ #
6
+ # This file is part of Ronin ASM.
7
+ #
8
+ # Ronin Asm is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Ronin Asm is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Ronin Asm. If not, see <http://www.gnu.org/licenses/>.
20
+ #
21
+
22
+ require 'ronin/asm/program'
23
+
24
+ require 'tempfile'
25
+
26
+ module Ronin
27
+ module ASM
28
+ #
29
+ # Represents Shellcode. Shellcode is like an Assembly {Program}, but
30
+ # assembles into raw machine code which can be injected into a process.
31
+ #
32
+ # ASM::Shellcode.new do
33
+ # xor eax, eax
34
+ # push eax
35
+ # push 0x68732f2f
36
+ # push 0x6e69622f
37
+ # mov esp, ebx
38
+ # push eax
39
+ # push ebx
40
+ # mov esp, ecx
41
+ # xor edx, edx
42
+ # mov 0xb, al
43
+ # int 0x80
44
+ # end
45
+ #
46
+ #
47
+ class Shellcode < Program
48
+
49
+ #
50
+ # Assembles the Shellcode.
51
+ #
52
+ # @param [Hash] options
53
+ # Additional options.
54
+ #
55
+ # @return [String]
56
+ # The raw object-code of the Shellcode.
57
+ #
58
+ # @see Program#assemble
59
+ #
60
+ def assemble(options={})
61
+ output = Tempfile.new(['ronin-shellcode', '.bin']).path
62
+
63
+ super(output,options.merge(:format => :bin))
64
+
65
+ return File.new(output,'rb').read
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,23 @@
1
+ #
2
+ # Ronin ASM - A Ruby DSL for crafting Assembly programs and Shellcode.
3
+ #
4
+ # Copyright (c) 2007-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ #
6
+ # This file is part of Ronin ASM.
7
+ #
8
+ # Ronin is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Ronin is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Ronin. If not, see <http://www.gnu.org/licenses/>
20
+ #
21
+
22
+ require 'ronin/asm/syntax/att'
23
+ require 'ronin/asm/syntax/intel'
@@ -0,0 +1,136 @@
1
+ #
2
+ # Ronin ASM - A Ruby DSL for crafting Assembly programs and Shellcode.
3
+ #
4
+ # Copyright (c) 2007-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ #
6
+ # This file is part of Ronin ASM.
7
+ #
8
+ # Ronin is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Ronin is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Ronin. If not, see <http://www.gnu.org/licenses/>
20
+ #
21
+
22
+ require 'ronin/asm/syntax/common'
23
+
24
+ module Ronin
25
+ module ASM
26
+ module Syntax
27
+ #
28
+ # Handles emitting Assembly source code in ATT syntax.
29
+ #
30
+ class ATT < Common
31
+
32
+ # Data sizes and their instruction mnemonics
33
+ WIDTHS = {
34
+ 8 => 'q',
35
+ 4 => 'l',
36
+ 2 => 'w',
37
+ 1 => 'b',
38
+ nil => ''
39
+ }
40
+
41
+ #
42
+ # Emits a register.
43
+ #
44
+ # @param [Register] reg
45
+ # The register.
46
+ #
47
+ # @return [String]
48
+ # The register name.
49
+ #
50
+ def self.emit_register(reg)
51
+ "%#{reg.name}"
52
+ end
53
+
54
+ #
55
+ # Emits an immediate operand.
56
+ #
57
+ # @param [ImmediateOperand] op
58
+ # The operand.
59
+ #
60
+ # @return [String]
61
+ # The formatted immediate operand.
62
+ #
63
+ def self.emit_immediate_operand(op)
64
+ "$#{emit_integer(op.value)}"
65
+ end
66
+
67
+ #
68
+ # Emits a memory operand.
69
+ #
70
+ # @param [MemoryOperand] op
71
+ # The operand.
72
+ #
73
+ # @return [String]
74
+ # The formatted memory operand.
75
+ #
76
+ def self.emit_memory_operand(op)
77
+ asm = emit_register(op.base)
78
+
79
+ if op.index
80
+ asm << ',' << emit_register(op.index)
81
+ asm << ',' << op.scale.to_s if op.scale > 1
82
+ end
83
+
84
+ asm = "(#{asm})"
85
+ asm = emit_integer(op.offset) + asm if op.offset != 0
86
+
87
+ return asm
88
+ end
89
+
90
+ #
91
+ # Emits an instruction.
92
+ #
93
+ # @param [Instruction] ins
94
+ # The instruction.
95
+ #
96
+ # @return [String]
97
+ # The formatted instruction.
98
+ #
99
+ def self.emit_instruction(ins)
100
+ line = emit_keyword(ins.name)
101
+
102
+ unless ins.operands.empty?
103
+ unless (ins.operands.length == 1 && ins.width == 1)
104
+ line << WIDTHS[ins.width]
105
+ end
106
+
107
+ line << "\t" << emit_operands(ins.operands)
108
+ end
109
+
110
+ return line
111
+ end
112
+
113
+ #
114
+ # Emits a program.
115
+ #
116
+ # @param [Program] program
117
+ # The program.
118
+ #
119
+ # @return [String]
120
+ # The formatted program.
121
+ #
122
+ def self.emit_program(program)
123
+ asm = super(program)
124
+
125
+ # prepend the `.code64` directive for YASM
126
+ if program.arch == :amd64
127
+ asm = [".code64", '', asm].join($/)
128
+ end
129
+
130
+ return asm
131
+ end
132
+
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,202 @@
1
+ #
2
+ # Ronin ASM - A Ruby DSL for crafting Assembly programs and Shellcode.
3
+ #
4
+ # Copyright (c) 2007-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ #
6
+ # This file is part of Ronin ASM.
7
+ #
8
+ # Ronin is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Ronin is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Ronin. If not, see <http://www.gnu.org/licenses/>
20
+ #
21
+
22
+ require 'ronin/asm/register'
23
+ require 'ronin/asm/immediate_operand'
24
+ require 'ronin/asm/memory_operand'
25
+
26
+ module Ronin
27
+ module ASM
28
+ module Syntax
29
+ #
30
+ # Abstract base-class for all Assembly Syntax classes.
31
+ #
32
+ class Common
33
+
34
+ #
35
+ # Emits a keyword.
36
+ #
37
+ # @param [Symbol] name
38
+ # Name of the keyword.
39
+ #
40
+ # @return [String]
41
+ # The formatted keyword.
42
+ #
43
+ def self.emit_keyword(name)
44
+ name.to_s
45
+ end
46
+
47
+ #
48
+ # Emits a register.
49
+ #
50
+ # @param [Register] reg
51
+ #
52
+ # @return [String]
53
+ # The formatted register.
54
+ #
55
+ # @abstract
56
+ #
57
+ def self.emit_register(reg)
58
+ end
59
+
60
+ #
61
+ # Emits an integer.
62
+ #
63
+ # @param [Integer] value
64
+ # The integer.
65
+ #
66
+ # @return [String]
67
+ # The formatted integer.
68
+ #
69
+ def self.emit_integer(value)
70
+ if value >= 0 then "0x%x" % value
71
+ else "-0x%x" % value.abs
72
+ end
73
+ end
74
+
75
+ #
76
+ # Emits a floating point number.
77
+ #
78
+ # @param [Float] value
79
+ # The number.
80
+ #
81
+ # @return [String]
82
+ # The formatted float.
83
+ #
84
+ # @abstract
85
+ #
86
+ def self.emit_float(value)
87
+ end
88
+
89
+ #
90
+ # Emits an immediate operand.
91
+ #
92
+ # @param [ImmediateOperand] op
93
+ # The immediate operand.
94
+ #
95
+ # @return [String]
96
+ # The formatted immediate operand.
97
+ #
98
+ # @abstract
99
+ #
100
+ def self.emit_immediate_operand(op)
101
+ end
102
+
103
+ #
104
+ # Emits an memory operand.
105
+ #
106
+ # @param [MemoryOperand] op
107
+ # The memory operand.
108
+ #
109
+ # @return [String]
110
+ # The formatted memory operand.
111
+ #
112
+ # @abstract
113
+ #
114
+ def self.emit_memory_operand(op)
115
+ end
116
+
117
+ #
118
+ # Emits an operand.
119
+ #
120
+ # @param [ImmediateOperand, MemoryOperand, Register, Symbol] op
121
+ # The operand.
122
+ #
123
+ # @return [String]
124
+ # The formatted operand.
125
+ #
126
+ def self.emit_operand(op)
127
+ case op
128
+ when ImmediateOperand then emit_immediate_operand(op)
129
+ when MemoryOperand then emit_memory_operand(op)
130
+ when Register then emit_register(op)
131
+ when Symbol then emit_keyword(op)
132
+ end
133
+ end
134
+
135
+ #
136
+ # Emits multiple operands.
137
+ #
138
+ # @param [Array<ImmediateOperand, MemoryOperand, Register, Symbol>] ops
139
+ # The Array of operands.
140
+ #
141
+ # @return [String]
142
+ # The formatted operands.
143
+ #
144
+ def self.emit_operands(ops)
145
+ ops.map { |op| emit_operand(op) }.join(",\t")
146
+ end
147
+
148
+ #
149
+ # Emits a label.
150
+ #
151
+ # @param [Symbol] name
152
+ # The name of the label.
153
+ #
154
+ # @return [String]
155
+ # The formatted label.
156
+ #
157
+ def self.emit_label(name)
158
+ "#{name}:"
159
+ end
160
+
161
+ #
162
+ # Emits an instruction.
163
+ #
164
+ # @param [Instruction] ins
165
+ # The instruction.
166
+ #
167
+ # @return [String]
168
+ # The formatted instruction.
169
+ #
170
+ # @abstract
171
+ #
172
+ def self.emit_instruction(ins)
173
+ end
174
+
175
+ #
176
+ # Emits a program.
177
+ #
178
+ # @param [Program] program
179
+ # The program.
180
+ #
181
+ # @return [String]
182
+ # The formatted program.
183
+ #
184
+ def self.emit_program(program)
185
+ lines = [emit_label(:_start)]
186
+
187
+ program.instructions.each do |ins|
188
+ case ins
189
+ when Symbol then lines << emit_label(ins)
190
+ when Instruction then lines << "\t#{emit_instruction(ins)}"
191
+ end
192
+ end
193
+
194
+ lines << ''
195
+
196
+ return lines.join($/)
197
+ end
198
+
199
+ end
200
+ end
201
+ end
202
+ end