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,166 @@
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
+
24
+ module Ronin
25
+ module ASM
26
+ module Archs
27
+ #
28
+ # Contains X86 Archtecture information.
29
+ #
30
+ module X86
31
+ # Default word size
32
+ WORD_SIZE = 4
33
+
34
+ # X86 registers
35
+ REGISTERS = {
36
+ :al => Register.new(:al, 1),
37
+ :ah => Register.new(:ah, 1),
38
+ :ax => Register.new(:ax, 2),
39
+ :eax => Register.new(:eax, 4, true),
40
+
41
+ :bl => Register.new(:bl, 1),
42
+ :bh => Register.new(:bh, 1),
43
+ :bx => Register.new(:bx, 2),
44
+ :ebx => Register.new(:ebx, 4, true),
45
+
46
+ :cl => Register.new(:cl, 1),
47
+ :ch => Register.new(:ch, 1),
48
+ :cx => Register.new(:cx, 2),
49
+ :ecx => Register.new(:ecx, 4, true),
50
+
51
+ :dl => Register.new(:dl, 1),
52
+ :dh => Register.new(:dh, 1),
53
+ :dx => Register.new(:dx, 2),
54
+ :edx => Register.new(:edx, 4, true),
55
+
56
+ :bp => Register.new(:bp, 2),
57
+ :ebp => Register.new(:ebp, 4),
58
+
59
+ :sp => Register.new(:sp, 2),
60
+ :esp => Register.new(:esp, 4),
61
+
62
+ :ip => Register.new(:ip, 2),
63
+ :eip => Register.new(:eip, 4),
64
+
65
+ :sil => Register.new(:sil, 1),
66
+ :si => Register.new(:si, 2),
67
+ :esi => Register.new(:esi, 4, true),
68
+
69
+ :dil => Register.new(:dil, 1),
70
+ :di => Register.new(:di, 2),
71
+ :edi => Register.new(:edi, 4, true),
72
+
73
+ :cs => Register.new(:cs, 2),
74
+ :ds => Register.new(:ds, 2),
75
+ :es => Register.new(:es, 2),
76
+ :fs => Register.new(:fs, 2),
77
+ :gs => Register.new(:gs, 2),
78
+ :ss => Register.new(:ss, 2)
79
+ }
80
+
81
+ #
82
+ # Generates the instruction to trigger an interrupt.
83
+ #
84
+ def interrupt(number); instruction(:int,number); end
85
+
86
+ #
87
+ # Generates the instruction to invoke a syscall.
88
+ #
89
+ def syscall; interrupt(0x80); end
90
+
91
+ #
92
+ # The Stack Base Pointer register.
93
+ #
94
+ # @see ebp
95
+ #
96
+ def stack_base; ebp; end
97
+
98
+ #
99
+ # The Stack Pointer register.
100
+ #
101
+ # @see esp
102
+ #
103
+ def stack_pointer; esp; end
104
+
105
+ #
106
+ # Generates the instruction to push a value onto the Stack.
107
+ #
108
+ # @param [ImmediateOperand, MemoryOperate, Register, Integer, Symbol] op
109
+ # The value.
110
+ #
111
+ def stack_push(op); instruction(:push,op); end
112
+
113
+ #
114
+ # Generates the instruction to pop a value off of the Stack.
115
+ #
116
+ # @param [Register] op
117
+ # The register operand to store the value.
118
+ #
119
+ def stack_pop(op); instruction(:pop,op); end
120
+
121
+ #
122
+ # Generates the instruction to clear a register.
123
+ #
124
+ # @param [Symbol] name
125
+ # The name of the register.
126
+ #
127
+ def register_clear(name)
128
+ instruction(:xor,register(name),register(name))
129
+ end
130
+
131
+ #
132
+ # Generates the instruction to set a register.
133
+ #
134
+ # @param [ImmediateOperand, MemoryOperate, Register, Integer, Symbol] value
135
+ # The value to set.
136
+ #
137
+ # @param [Symbol] name
138
+ # The name of the register.
139
+ #
140
+ def register_set(value,name)
141
+ instruction(:mov,value,register(name))
142
+ end
143
+
144
+ #
145
+ # Generates the instruction to save a register.
146
+ #
147
+ # @param [Symbol] name
148
+ # The name of the register.
149
+ #
150
+ def register_save(name)
151
+ stack_push(register(name))
152
+ end
153
+
154
+ #
155
+ # Generates the instruction to restore a register.
156
+ #
157
+ # @param [Symbol] name
158
+ # The name of the register.
159
+ #
160
+ def register_load(name)
161
+ stack_pop(register(name))
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,66 @@
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/program'
23
+ require 'ronin/asm/shellcode'
24
+
25
+ module Ronin
26
+ module ASM
27
+ #
28
+ # Creates a new Assembly Program.
29
+ #
30
+ # @param [Hash{Symbol => Object}] options
31
+ # Additional options.
32
+ #
33
+ # @option options [String, Symbol] :arch (:x86)
34
+ # The architecture of the Program.
35
+ #
36
+ # @option options [Hash{Symbol => Object}] :variables
37
+ # Variables to set in the program.
38
+ #
39
+ # @yield []
40
+ # The given block will be evaluated within the program.
41
+ #
42
+ # @return [Program]
43
+ # The new Assembly Program.
44
+ #
45
+ # @example
46
+ # ASM.new do
47
+ # mov 1, eax
48
+ # mov 1, ebx
49
+ # mov 2, ecx
50
+ #
51
+ # _loop do
52
+ # push ecx
53
+ # imul ebx, ecx
54
+ # pop ebx
55
+ #
56
+ # inc eax
57
+ # cmp ebx, 10
58
+ # jl :_loop
59
+ # end
60
+ # end
61
+ #
62
+ def ASM.new(options={},&block)
63
+ Program.new(options,&block)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,39 @@
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 'data_paths'
23
+
24
+ module Ronin
25
+ module ASM
26
+ #
27
+ # Handles configuration for ronin-asm.
28
+ #
29
+ module Config
30
+ include DataPaths
31
+ extend DataPaths::Finders
32
+
33
+ register_data_path File.join(File.dirname(__FILE__),'..','..','..','data')
34
+
35
+ # Data directory for ronin-asm
36
+ DATA_DIR = File.join('ronin','asm')
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,76 @@
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
+ module Ronin
23
+ module ASM
24
+ #
25
+ # Represents an Immediate Data Operand.
26
+ #
27
+ # @see http://asm.sourceforge.net/articles/linasm.html#Prefixes
28
+ #
29
+ class ImmediateOperand < Struct.new(:value, :width)
30
+
31
+ #
32
+ # Initializes a new Immediate Operand.
33
+ #
34
+ # @param [Integer, nil] value
35
+ # The value.
36
+ #
37
+ # @param [nil, 1, 2, 4, 8] width
38
+ # The size in bytes of the value.
39
+ #
40
+ def initialize(value,width=nil)
41
+ value = value.to_i
42
+ width ||= case value
43
+ when (0x100000000..0xffffffffffffffff),
44
+ (-0x7fffffffffffffff..-0x800000000) then 8
45
+ when (0x10000..0xffffffff),
46
+ (-0x7fffffff..-0x80000) then 4
47
+ when (0x100..0xffff), (-0x7fff..-0x80) then 2
48
+ when (0..0xff), (-0x7f..0) then 1
49
+ end
50
+
51
+ super(value,width)
52
+ end
53
+
54
+ #
55
+ # Converts the operand to an Integer.
56
+ #
57
+ # @return [Integer]
58
+ # The value.
59
+ #
60
+ def to_i
61
+ self.value
62
+ end
63
+
64
+ #
65
+ # Converts the operand to a String.
66
+ #
67
+ # @return [String]
68
+ # The value in String form.
69
+ #
70
+ def to_s
71
+ self.value.to_s
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,65 @@
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/immediate_operand'
23
+
24
+ module Ronin
25
+ module ASM
26
+ #
27
+ # Represents an instruction.
28
+ #
29
+ class Instruction < Struct.new(:name, :operands)
30
+
31
+ #
32
+ # Initializes the instruction.
33
+ #
34
+ # @param [Symbol] name
35
+ # The instruction name.
36
+ #
37
+ # @param [Array<MemoryOperand, Register, Symbo, Integer>] operands
38
+ # Operands for the instruction.
39
+ #
40
+ def initialize(name,operands)
41
+ operands = operands.map do |op|
42
+ case op
43
+ when Integer, nil then ImmediateOperand.new(op)
44
+ else op
45
+ end
46
+ end
47
+
48
+ super(name,operands)
49
+ end
50
+
51
+ #
52
+ # The word size of the instruction.
53
+ #
54
+ # @return [Integer, nil]
55
+ # The word size in bytes.
56
+ #
57
+ def width
58
+ self.operands.map { |op|
59
+ op.width if op.respond_to?(:width)
60
+ }.compact.max
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,109 @@
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
+
24
+ module Ronin
25
+ module ASM
26
+ #
27
+ # Represents a Memory Operand.
28
+ #
29
+ # @see http://asm.sourceforge.net/articles/linasm.html#Memory
30
+ #
31
+ class MemoryOperand < Struct.new(:base, :offset, :index, :scale)
32
+
33
+ #
34
+ # Creates a new Memory Operand.
35
+ #
36
+ # @param [Register, nil] base
37
+ # The base of the value.
38
+ #
39
+ # @param [Integer] offset
40
+ # The fixed offset to add to the `base`.
41
+ #
42
+ # @param [Register, nil] index
43
+ # The variable index to multiple by `scale`, then add to `base.
44
+ #
45
+ # @param [Integer] scale
46
+ # The scale to multiple `index` by.
47
+ #
48
+ # @raise [TypeError]
49
+ # `base` or `index` was not a {Register} or `nil`.
50
+ #
51
+ def initialize(base=nil,offset=0,index=nil,scale=1)
52
+ unless (base.nil? || base.kind_of?(Register))
53
+ raise(TypeError,"base must be a Register or nil")
54
+ end
55
+
56
+ unless offset.kind_of?(Integer)
57
+ raise(TypeError,"offset must be an Integer")
58
+ end
59
+
60
+ unless (index.nil? || index.kind_of?(Register))
61
+ raise(TypeError,"index must be a Register or nil")
62
+ end
63
+
64
+ unless scale.kind_of?(Integer)
65
+ raise(TypeError,"scale must be an Integer")
66
+ end
67
+
68
+ super(base,offset,index,scale)
69
+ end
70
+
71
+ #
72
+ # Adds to the offset of the Memory Operand.
73
+ #
74
+ # @param [Integer] offset
75
+ # The offset to add to the Memory Operand.
76
+ #
77
+ # @return [MemoryOperand]
78
+ # The new Memory Operand.
79
+ #
80
+ def +(offset)
81
+ MemoryOperand.new(self.base,self.offset+offset,self.index,self.scale)
82
+ end
83
+
84
+ #
85
+ # Subtracts from the offset of the Memory Operand.
86
+ #
87
+ # @param [Integer] offset
88
+ # The offset to subject from the Memory Operand.
89
+ #
90
+ # @return [Memoryoperand]
91
+ # The new Memory Operand.
92
+ #
93
+ def -(offset)
94
+ MemoryOperand.new(self.base,self.offset-offset,self.index,self.scale)
95
+ end
96
+
97
+ #
98
+ # The width of the Memory Operand.
99
+ #
100
+ # @return [Integer]
101
+ # The width taken from the base {Register}.
102
+ #
103
+ def width
104
+ base.width
105
+ end
106
+
107
+ end
108
+ end
109
+ end