ronin-code-asm 1.0.0.beta1
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.
- checksums.yaml +7 -0
- data/.document +4 -0
- data/.editorconfig +11 -0
- data/.github/workflows/ruby.yml +31 -0
- data/.gitignore +11 -0
- data/.mailmap +1 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/COPYING.txt +165 -0
- data/ChangeLog.md +44 -0
- data/Gemfile +25 -0
- data/README.md +166 -0
- data/Rakefile +39 -0
- data/data/os/freebsd/amd64/syscalls.yml +415 -0
- data/data/os/freebsd/x86/syscalls.yml +415 -0
- data/data/os/linux/amd64/syscalls.yml +306 -0
- data/data/os/linux/x86/syscalls.yml +339 -0
- data/gemspec.yml +26 -0
- data/lib/ronin/code/asm/archs/amd64.rb +100 -0
- data/lib/ronin/code/asm/archs/x86.rb +170 -0
- data/lib/ronin/code/asm/archs.rb +22 -0
- data/lib/ronin/code/asm/config.rb +33 -0
- data/lib/ronin/code/asm/immediate_operand.rb +84 -0
- data/lib/ronin/code/asm/instruction.rb +66 -0
- data/lib/ronin/code/asm/memory_operand.rb +119 -0
- data/lib/ronin/code/asm/os/freebsd.rb +35 -0
- data/lib/ronin/code/asm/os/linux.rb +35 -0
- data/lib/ronin/code/asm/os/os.rb +47 -0
- data/lib/ronin/code/asm/os.rb +57 -0
- data/lib/ronin/code/asm/program.rb +509 -0
- data/lib/ronin/code/asm/register.rb +111 -0
- data/lib/ronin/code/asm/shellcode.rb +75 -0
- data/lib/ronin/code/asm/syntax/att.rb +164 -0
- data/lib/ronin/code/asm/syntax/common.rb +241 -0
- data/lib/ronin/code/asm/syntax/intel.rb +150 -0
- data/lib/ronin/code/asm/syntax.rb +22 -0
- data/lib/ronin/code/asm/version.rb +28 -0
- data/lib/ronin/code/asm.rb +68 -0
- data/ronin-code-asm.gemspec +62 -0
- data/spec/asm_spec.rb +14 -0
- data/spec/config_spec.rb +10 -0
- data/spec/immediate_operand_spec.rb +79 -0
- data/spec/instruction_spec.rb +62 -0
- data/spec/memory_operand_spec.rb +80 -0
- data/spec/os_spec.rb +68 -0
- data/spec/program_spec.rb +439 -0
- data/spec/register_spec.rb +112 -0
- data/spec/shellcode_spec.rb +58 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/syntax/att_spec.rb +181 -0
- data/spec/syntax/common_spec.rb +42 -0
- data/spec/syntax/intel_spec.rb +174 -0
- metadata +143 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-code-asm - A Ruby DSL for crafting Assembly programs and shellcode.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-code-asm is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-code-asm is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with ronin-code-asm. If not, see <https://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'ronin/code/asm/program'
|
22
|
+
|
23
|
+
require 'tempfile'
|
24
|
+
|
25
|
+
module Ronin
|
26
|
+
module Code
|
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 ebx, esp
|
38
|
+
# push eax
|
39
|
+
# push ebx
|
40
|
+
# mov ecx, esp
|
41
|
+
# xor edx, edx
|
42
|
+
# mov al, 0xb
|
43
|
+
# int 0x80
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
#
|
47
|
+
class Shellcode < Program
|
48
|
+
|
49
|
+
#
|
50
|
+
# Assembles the Shellcode.
|
51
|
+
#
|
52
|
+
# @param [String] output
|
53
|
+
# The optional output to write the shellcode to. If no `:output` is
|
54
|
+
# given a tempfile will be used.
|
55
|
+
#
|
56
|
+
# @param [Hash{Symbol => Object}] kwargs
|
57
|
+
# Additional keyword arguments for {Program#assemble}.
|
58
|
+
#
|
59
|
+
# @return [String]
|
60
|
+
# The raw object-code of the Shellcode.
|
61
|
+
#
|
62
|
+
# @see Program#assemble
|
63
|
+
#
|
64
|
+
def assemble(output: nil, **kwargs)
|
65
|
+
output ||= Tempfile.new(['ronin-shellcode', '.bin']).path
|
66
|
+
|
67
|
+
super(output, format: :bin, **kwargs)
|
68
|
+
|
69
|
+
return File.binread(output)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-code-asm - A Ruby DSL for crafting Assembly programs and shellcode.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-code-asm is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-code-asm is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with ronin-code-asm. If not, see <https://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'ronin/code/asm/syntax/common'
|
22
|
+
|
23
|
+
module Ronin
|
24
|
+
module Code
|
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 multiple operands.
|
92
|
+
#
|
93
|
+
# @param [Array<ImmediateOperand, MemoryOperand, Register, Symbol>] ops
|
94
|
+
# The Array of operands.
|
95
|
+
#
|
96
|
+
# @return [String]
|
97
|
+
# The formatted operands.
|
98
|
+
#
|
99
|
+
def self.emit_operands(ops)
|
100
|
+
if ops.length > 1
|
101
|
+
[*ops[1..-1], ops[0]].map { |op| emit_operand(op) }.join(",\t")
|
102
|
+
else
|
103
|
+
super(ops)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# Emits an instruction.
|
109
|
+
#
|
110
|
+
# @param [Instruction] ins
|
111
|
+
# The instruction.
|
112
|
+
#
|
113
|
+
# @return [String]
|
114
|
+
# The formatted instruction.
|
115
|
+
#
|
116
|
+
def self.emit_instruction(ins)
|
117
|
+
line = emit_keyword(ins.name)
|
118
|
+
|
119
|
+
unless ins.operands.empty?
|
120
|
+
unless (ins.operands.length == 1 && ins.width == 1)
|
121
|
+
line << WIDTHS[ins.width]
|
122
|
+
end
|
123
|
+
|
124
|
+
line << "\t" << emit_operands(ins.operands)
|
125
|
+
end
|
126
|
+
|
127
|
+
return line
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
# Emits a section name.
|
132
|
+
#
|
133
|
+
# @param [Symbol] name
|
134
|
+
# The section name.
|
135
|
+
#
|
136
|
+
# @return [String]
|
137
|
+
# The formatted section name.
|
138
|
+
#
|
139
|
+
# @since 0.2.0
|
140
|
+
#
|
141
|
+
def self.emit_section(name)
|
142
|
+
".#{name}"
|
143
|
+
end
|
144
|
+
|
145
|
+
#
|
146
|
+
# Emits the program's prologue.
|
147
|
+
#
|
148
|
+
# @param [Program] program
|
149
|
+
# The program.
|
150
|
+
#
|
151
|
+
# @return [String]
|
152
|
+
# The formatted prologue.
|
153
|
+
#
|
154
|
+
# @since 0.2.0
|
155
|
+
#
|
156
|
+
def self.emit_prologue(program)
|
157
|
+
".code#{BITS[program.arch]}"
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,241 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-code-asm - A Ruby DSL for crafting Assembly programs and shellcode.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-code-asm is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-code-asm is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with ronin-code-asm. If not, see <https://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'ronin/code/asm/register'
|
22
|
+
require 'ronin/code/asm/immediate_operand'
|
23
|
+
require 'ronin/code/asm/memory_operand'
|
24
|
+
|
25
|
+
module Ronin
|
26
|
+
module Code
|
27
|
+
module ASM
|
28
|
+
module Syntax
|
29
|
+
#
|
30
|
+
# Abstract base-class for all Assembly Syntax classes.
|
31
|
+
#
|
32
|
+
class Common
|
33
|
+
|
34
|
+
# Bit sizes for various architectures
|
35
|
+
BITS = {
|
36
|
+
x86: 32,
|
37
|
+
amd64: 64,
|
38
|
+
}
|
39
|
+
|
40
|
+
#
|
41
|
+
# Emits a keyword.
|
42
|
+
#
|
43
|
+
# @param [Symbol] name
|
44
|
+
# Name of the keyword.
|
45
|
+
#
|
46
|
+
# @return [String]
|
47
|
+
# The formatted keyword.
|
48
|
+
#
|
49
|
+
def self.emit_keyword(name)
|
50
|
+
name.to_s
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Emits a register.
|
55
|
+
#
|
56
|
+
# @param [Register] reg
|
57
|
+
#
|
58
|
+
# @return [String]
|
59
|
+
# The formatted register.
|
60
|
+
#
|
61
|
+
# @abstract
|
62
|
+
#
|
63
|
+
def self.emit_register(reg)
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Emits an integer.
|
68
|
+
#
|
69
|
+
# @param [Integer] value
|
70
|
+
# The integer.
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
# The formatted integer.
|
74
|
+
#
|
75
|
+
def self.emit_integer(value)
|
76
|
+
if value >= 0 then "0x%x" % value
|
77
|
+
else "-0x%x" % value.abs
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Emits a floating point number.
|
83
|
+
#
|
84
|
+
# @param [Float] value
|
85
|
+
# The number.
|
86
|
+
#
|
87
|
+
# @return [String]
|
88
|
+
# The formatted float.
|
89
|
+
#
|
90
|
+
# @abstract
|
91
|
+
#
|
92
|
+
def self.emit_float(value)
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Emits an immediate operand.
|
97
|
+
#
|
98
|
+
# @param [ImmediateOperand] op
|
99
|
+
# The immediate operand.
|
100
|
+
#
|
101
|
+
# @return [String]
|
102
|
+
# The formatted immediate operand.
|
103
|
+
#
|
104
|
+
# @abstract
|
105
|
+
#
|
106
|
+
def self.emit_immediate_operand(op)
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# Emits an memory operand.
|
111
|
+
#
|
112
|
+
# @param [MemoryOperand] op
|
113
|
+
# The memory operand.
|
114
|
+
#
|
115
|
+
# @return [String]
|
116
|
+
# The formatted memory operand.
|
117
|
+
#
|
118
|
+
# @abstract
|
119
|
+
#
|
120
|
+
def self.emit_memory_operand(op)
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# Emits an operand.
|
125
|
+
#
|
126
|
+
# @param [ImmediateOperand, MemoryOperand, Register, Symbol] op
|
127
|
+
# The operand.
|
128
|
+
#
|
129
|
+
# @return [String]
|
130
|
+
# The formatted operand.
|
131
|
+
#
|
132
|
+
def self.emit_operand(op)
|
133
|
+
case op
|
134
|
+
when ImmediateOperand then emit_immediate_operand(op)
|
135
|
+
when MemoryOperand then emit_memory_operand(op)
|
136
|
+
when Register then emit_register(op)
|
137
|
+
when Symbol then emit_keyword(op)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Emits multiple operands.
|
143
|
+
#
|
144
|
+
# @param [Array<ImmediateOperand, MemoryOperand, Register, Symbol>] ops
|
145
|
+
# The Array of operands.
|
146
|
+
#
|
147
|
+
# @return [String]
|
148
|
+
# The formatted operands.
|
149
|
+
#
|
150
|
+
def self.emit_operands(ops)
|
151
|
+
ops.map { |op| emit_operand(op) }.join(",\t")
|
152
|
+
end
|
153
|
+
|
154
|
+
#
|
155
|
+
# Emits a label.
|
156
|
+
#
|
157
|
+
# @param [Symbol] name
|
158
|
+
# The name of the label.
|
159
|
+
#
|
160
|
+
# @return [String]
|
161
|
+
# The formatted label.
|
162
|
+
#
|
163
|
+
def self.emit_label(name)
|
164
|
+
"#{name}:"
|
165
|
+
end
|
166
|
+
|
167
|
+
#
|
168
|
+
# Emits an instruction.
|
169
|
+
#
|
170
|
+
# @param [Instruction] ins
|
171
|
+
# The instruction.
|
172
|
+
#
|
173
|
+
# @return [String]
|
174
|
+
# The formatted instruction.
|
175
|
+
#
|
176
|
+
# @abstract
|
177
|
+
#
|
178
|
+
def self.emit_instruction(ins)
|
179
|
+
end
|
180
|
+
|
181
|
+
#
|
182
|
+
# Emits a section name.
|
183
|
+
#
|
184
|
+
# @param [Symbol] name
|
185
|
+
# The section name.
|
186
|
+
#
|
187
|
+
# @return [String]
|
188
|
+
# The formatted section name.
|
189
|
+
#
|
190
|
+
# @since 0.2.0
|
191
|
+
#
|
192
|
+
def self.emit_section(name)
|
193
|
+
end
|
194
|
+
|
195
|
+
#
|
196
|
+
# Emits the program's prologue.
|
197
|
+
#
|
198
|
+
# @param [Program] program
|
199
|
+
# The program.
|
200
|
+
#
|
201
|
+
# @return [String]
|
202
|
+
# The formatted prologue.
|
203
|
+
#
|
204
|
+
# @since 0.2.0
|
205
|
+
#
|
206
|
+
def self.emit_prologue(program)
|
207
|
+
end
|
208
|
+
|
209
|
+
#
|
210
|
+
# Emits a program.
|
211
|
+
#
|
212
|
+
# @param [Program] program
|
213
|
+
# The program.
|
214
|
+
#
|
215
|
+
# @return [String]
|
216
|
+
# The formatted program.
|
217
|
+
#
|
218
|
+
def self.emit_program(program)
|
219
|
+
lines = [
|
220
|
+
emit_prologue(program),
|
221
|
+
emit_section(:text),
|
222
|
+
emit_label(:_start)
|
223
|
+
].compact
|
224
|
+
|
225
|
+
program.instructions.each do |ins|
|
226
|
+
case ins
|
227
|
+
when Symbol then lines << emit_label(ins)
|
228
|
+
when Instruction then lines << "\t#{emit_instruction(ins)}"
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
lines << ''
|
233
|
+
|
234
|
+
return lines.join($/)
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-code-asm - A Ruby DSL for crafting Assembly programs and shellcode.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-code-asm is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-code-asm is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with ronin-code-asm. If not, see <https://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'ronin/code/asm/syntax/common'
|
22
|
+
|
23
|
+
module Ronin
|
24
|
+
module Code
|
25
|
+
module ASM
|
26
|
+
module Syntax
|
27
|
+
class Intel < Common
|
28
|
+
|
29
|
+
# Data sizes and their identifiers
|
30
|
+
WIDTHS = {
|
31
|
+
1 => 'BYTE',
|
32
|
+
2 => 'WORD',
|
33
|
+
4 => 'DWORD',
|
34
|
+
8 => 'QWORD'
|
35
|
+
}
|
36
|
+
|
37
|
+
#
|
38
|
+
# Emits a register.
|
39
|
+
#
|
40
|
+
# @param [Register] reg
|
41
|
+
# The register.
|
42
|
+
#
|
43
|
+
# @return [String]
|
44
|
+
# The register name.
|
45
|
+
#
|
46
|
+
def self.emit_register(reg)
|
47
|
+
reg.name.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Emits an immediate operand.
|
52
|
+
#
|
53
|
+
# @param [ImmediateOperand] op
|
54
|
+
# The operand.
|
55
|
+
#
|
56
|
+
# @return [String]
|
57
|
+
# The formatted immediate operand.
|
58
|
+
#
|
59
|
+
def self.emit_immediate_operand(op)
|
60
|
+
"#{WIDTHS[op.width]} #{emit_integer(op.value)}"
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# Emits a memory operand.
|
65
|
+
#
|
66
|
+
# @param [MemoryOperand] op
|
67
|
+
# The operand.
|
68
|
+
#
|
69
|
+
# @return [String]
|
70
|
+
# The formatted memory operand.
|
71
|
+
#
|
72
|
+
def self.emit_memory_operand(op)
|
73
|
+
asm = emit_register(op.base)
|
74
|
+
|
75
|
+
if op.index
|
76
|
+
asm << '+' << emit_register(op.index)
|
77
|
+
asm << '*' << emit_integer(op.scale) if op.scale > 1
|
78
|
+
end
|
79
|
+
|
80
|
+
if op.offset != 0
|
81
|
+
sign = if op.offset >= 0 then '+'
|
82
|
+
else '-'
|
83
|
+
end
|
84
|
+
|
85
|
+
asm << sign << emit_integer(op.offset)
|
86
|
+
end
|
87
|
+
|
88
|
+
asm = "[#{asm}]"
|
89
|
+
|
90
|
+
unless op.width == op.base.width
|
91
|
+
asm = "#{WIDTHS[op.width]} #{asm}"
|
92
|
+
end
|
93
|
+
|
94
|
+
return asm
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Emits an instruction.
|
99
|
+
#
|
100
|
+
# @param [Instruction] ins
|
101
|
+
# The instruction.
|
102
|
+
#
|
103
|
+
# @return [String]
|
104
|
+
# The formatted instruction.
|
105
|
+
#
|
106
|
+
def self.emit_instruction(ins)
|
107
|
+
line = emit_keyword(ins.name)
|
108
|
+
|
109
|
+
unless ins.operands.empty?
|
110
|
+
line << "\t" << emit_operands(ins.operands)
|
111
|
+
end
|
112
|
+
|
113
|
+
return line
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
# Emits a section name.
|
118
|
+
#
|
119
|
+
# @param [Symbol] name
|
120
|
+
# The section name.
|
121
|
+
#
|
122
|
+
# @return [String]
|
123
|
+
# The formatted section name.
|
124
|
+
#
|
125
|
+
# @since 0.2.0
|
126
|
+
#
|
127
|
+
def self.emit_section(name)
|
128
|
+
"section .#{name}"
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# Emits the program's prologue.
|
133
|
+
#
|
134
|
+
# @param [Program] program
|
135
|
+
# The program.
|
136
|
+
#
|
137
|
+
# @return [String]
|
138
|
+
# The formatted prologue.
|
139
|
+
#
|
140
|
+
# @since 0.2.0
|
141
|
+
#
|
142
|
+
def self.emit_prologue(program)
|
143
|
+
"BITS #{BITS[program.arch]}"
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-code-asm - A Ruby DSL for crafting Assembly programs and shellcode.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-code-asm is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-code-asm is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with ronin-code-asm. If not, see <https://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'ronin/code/asm/syntax/att'
|
22
|
+
require 'ronin/code/asm/syntax/intel'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-code-asm - A Ruby DSL for crafting Assembly programs and shellcode.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2007-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-code-asm is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-code-asm is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with ronin-code-asm. If not, see <https://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
module Ronin
|
22
|
+
module Code
|
23
|
+
module ASM
|
24
|
+
# ronin-code-asm version
|
25
|
+
VERSION = '1.0.0.beta1'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|