ronin-code-asm 1.0.0.beta1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -0
  3. data/.yardopts +1 -1
  4. data/README.md +2 -1
  5. data/gemspec.yml +2 -2
  6. data/lib/ronin/code/asm/archs/amd64.rb +2 -2
  7. data/lib/ronin/code/asm/archs/x86.rb +2 -2
  8. data/lib/ronin/code/asm/archs.rb +1 -1
  9. data/lib/ronin/code/asm/config.rb +1 -1
  10. data/lib/ronin/code/asm/immediate_operand.rb +1 -1
  11. data/lib/ronin/code/asm/instruction.rb +1 -1
  12. data/lib/ronin/code/asm/memory_operand.rb +1 -1
  13. data/lib/ronin/code/asm/os/freebsd.rb +1 -1
  14. data/lib/ronin/code/asm/os/linux.rb +1 -1
  15. data/lib/ronin/code/asm/os/os.rb +1 -1
  16. data/lib/ronin/code/asm/os.rb +1 -1
  17. data/lib/ronin/code/asm/program.rb +6 -6
  18. data/lib/ronin/code/asm/register.rb +2 -2
  19. data/lib/ronin/code/asm/shellcode.rb +1 -1
  20. data/lib/ronin/code/asm/syntax/att.rb +1 -1
  21. data/lib/ronin/code/asm/syntax/common.rb +1 -1
  22. data/lib/ronin/code/asm/syntax/intel.rb +1 -1
  23. data/lib/ronin/code/asm/syntax.rb +1 -1
  24. data/lib/ronin/code/asm/version.rb +2 -2
  25. data/lib/ronin/code/asm.rb +1 -1
  26. data/ronin-code-asm.gemspec +2 -1
  27. metadata +5 -30
  28. data/spec/asm_spec.rb +0 -14
  29. data/spec/config_spec.rb +0 -10
  30. data/spec/immediate_operand_spec.rb +0 -79
  31. data/spec/instruction_spec.rb +0 -62
  32. data/spec/memory_operand_spec.rb +0 -80
  33. data/spec/os_spec.rb +0 -68
  34. data/spec/program_spec.rb +0 -439
  35. data/spec/register_spec.rb +0 -112
  36. data/spec/shellcode_spec.rb +0 -58
  37. data/spec/spec_helper.rb +0 -7
  38. data/spec/syntax/att_spec.rb +0 -181
  39. data/spec/syntax/common_spec.rb +0 -42
  40. data/spec/syntax/intel_spec.rb +0 -174
@@ -1,58 +0,0 @@
1
- # encoding: US-ASCII
2
-
3
- require 'spec_helper'
4
- require 'ronin/code/asm/shellcode'
5
-
6
- describe Ronin::Code::ASM::Shellcode do
7
- describe "#assemble", integration: true do
8
- subject do
9
- described_class.new do
10
- xor eax, eax
11
- push eax
12
- push 0x68732f2f
13
- push 0x6e69622f
14
- mov ebx, esp
15
- push eax
16
- push ebx
17
- mov ecx, esp
18
- xor edx, edx
19
- mov al, 0xb
20
- int 0x80
21
- end
22
- end
23
-
24
- let(:shellcode) { "1\xC0Ph//shh/bin\x89\xE3PS\x89\xE11\xD2\xB0\v\xCD\x80" }
25
-
26
- it "must assemble down to raw machine code" do
27
- expect(subject.assemble).to eq(shellcode)
28
- end
29
-
30
- it "must return an ASCII-8bit encoded String" do
31
- expect(subject.assemble.encoding).to eq(Encoding::ASCII_8BIT)
32
- end
33
-
34
- context "with :output" do
35
- let(:output) do
36
- Tempfile.new(['ronin-shellcode-custom-path', '.bin']).path
37
- end
38
-
39
- it "must write to the custom path" do
40
- expect(subject.assemble(output: output)).to eq(shellcode)
41
-
42
- File.binread(output)
43
- end
44
- end
45
-
46
- context "with :syntax is :intel" do
47
- it "assemble down to raw machine code" do
48
- expect(subject.assemble(syntax: :intel)).to eq(shellcode)
49
- end
50
- end
51
-
52
- context "with :syntax is :att" do
53
- it "assemble down to raw machine code" do
54
- expect(subject.assemble(syntax: :att)).to eq(shellcode)
55
- end
56
- end
57
- end
58
- end
data/spec/spec_helper.rb DELETED
@@ -1,7 +0,0 @@
1
- require 'rspec'
2
- require 'simplecov'
3
- SimpleCov.start
4
-
5
- RSpec.configure do |specs|
6
- specs.filter_run_excluding :yasm
7
- end
@@ -1,181 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'ronin/code/asm/syntax/att'
4
- require 'ronin/code/asm/register'
5
- require 'ronin/code/asm/immediate_operand'
6
- require 'ronin/code/asm/memory_operand'
7
- require 'ronin/code/asm/instruction'
8
- require 'ronin/code/asm/program'
9
-
10
- describe Ronin::Code::ASM::Syntax::ATT do
11
- subject { described_class }
12
-
13
- describe "emit_register" do
14
- let(:register) { Ronin::Code::ASM::Register.new(:eax, 4) }
15
-
16
- it "must prepend a '%' to the register name" do
17
- expect(subject.emit_register(register)).to eq("%eax")
18
- end
19
- end
20
-
21
- describe "emit_immediate_operand" do
22
- let(:operand) { Ronin::Code::ASM::ImmediateOperand.new(255, 1) }
23
-
24
- it "must prepend a '$' to the immediate" do
25
- expect(subject.emit_immediate_operand(operand)).to eq("$0xff")
26
- end
27
- end
28
-
29
- describe "emit_memory_operand" do
30
- let(:register) { Ronin::Code::ASM::Register.new(:eax, 4) }
31
- let(:operand) { Ronin::Code::ASM::MemoryOperand.new(register) }
32
-
33
- it "must enclose the memory in parenthesis" do
34
- expect(subject.emit_memory_operand(operand)).to eq("(%eax)")
35
- end
36
-
37
- context "with an offset" do
38
- let(:offset) { 255 }
39
- let(:operand) { Ronin::Code::ASM::MemoryOperand.new(register,offset) }
40
-
41
- it "must prepend the offset as an integer" do
42
- expect(subject.emit_memory_operand(operand)).to eq("0xff(%eax)")
43
- end
44
-
45
- context "when 0" do
46
- let(:operand) { Ronin::Code::ASM::MemoryOperand.new(register,0) }
47
-
48
- it "must omit the offset" do
49
- expect(subject.emit_memory_operand(operand)).to eq("(%eax)")
50
- end
51
- end
52
- end
53
-
54
- context "with an index" do
55
- let(:index) { Ronin::Code::ASM::Register.new(:esi, 4) }
56
- let(:operand) { Ronin::Code::ASM::MemoryOperand.new(register,0,index) }
57
-
58
- it "must include the index argument" do
59
- expect(subject.emit_memory_operand(operand)).to eq("(%eax,%esi)")
60
- end
61
-
62
- context "with a scale" do
63
- let(:scale) { 4 }
64
- let(:operand) { Ronin::Code::ASM::MemoryOperand.new(register,0,index,scale) }
65
-
66
- it "must prepend the scale argument as a decimal" do
67
- expect(subject.emit_memory_operand(operand)).to eq("(%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) { Ronin::Code::ASM::Instruction.new(:ret, []) }
76
-
77
- it "must emit the instruction name" do
78
- expect(subject.emit_instruction(instruction)).to eq('ret')
79
- end
80
- end
81
-
82
- context "with one operand" do
83
- context "with width of 1" do
84
- let(:immediate) { Ronin::Code::ASM::ImmediateOperand.new(0x80, 1) }
85
- let(:instruction) { Ronin::Code::ASM::Instruction.new(:int, [immediate]) }
86
-
87
- it "must not append a size specifier to the instruction name" do
88
- expect(subject.emit_instruction(instruction)).to eq("int\t$0x80")
89
- end
90
- end
91
- end
92
-
93
- context "with multiple operands" do
94
- let(:register) { Ronin::Code::ASM::Register.new(:eax, 4) }
95
- let(:immediate) { Ronin::Code::ASM::ImmediateOperand.new(0xff, 1) }
96
- let(:instruction) { Ronin::Code::ASM::Instruction.new(:mov, [register, immediate]) }
97
-
98
- it "must add a size specifier to the instruction name" do
99
- expect(subject.emit_instruction(instruction)).to match(/^movl/)
100
- end
101
-
102
- it "must emit the operands" do
103
- expect(subject.emit_instruction(instruction)).to eq("movl\t$0xff,\t%eax")
104
- end
105
- end
106
- end
107
-
108
- describe "emit_section" do
109
- it "must emit the section name" do
110
- expect(subject.emit_section(:text)).to eq(".text")
111
- end
112
- end
113
-
114
- describe "emit_program" do
115
- let(:program) do
116
- Ronin::Code::ASM::Program.new do
117
- mov eax, 0xff
118
- ret
119
- end
120
- end
121
-
122
- it "must output the _start label and the program" do
123
- asm = subject.emit_program(program)
124
-
125
- expect(asm).to eq([
126
- ".code32",
127
- ".text",
128
- "_start:",
129
- "\tmovl\t$0xff,\t%eax",
130
- "\tret",
131
- ""
132
- ].join($/))
133
- end
134
-
135
- context "when emitting labels" do
136
- let(:program) do
137
- Ronin::Code::ASM::Program.new do
138
- mov eax, 0
139
-
140
- _loop do
141
- inc eax
142
- cmp eax, 10
143
- jl :_loop
144
- end
145
-
146
- ret
147
- end
148
- end
149
-
150
- it "must emit both labels and instructions" do
151
- expect(subject.emit_program(program)).to eq([
152
- ".code32",
153
- ".text",
154
- "_start:",
155
- "\tmovl\t$0x0,\t%eax",
156
- "_loop:",
157
- "\tincl\t%eax",
158
- "\tcmpl\t$0xa,\t%eax",
159
- "\tjl\t_loop",
160
- "\tret",
161
- ""
162
- ].join($/))
163
- end
164
- end
165
-
166
- context "when the program arch is :amd64" do
167
- let(:program) do
168
- Ronin::Code::ASM::Program.new(arch: :amd64) do
169
- push rax
170
- push rbx
171
- mov 0xff, rax
172
- ret
173
- end
174
- end
175
-
176
- it "must include start with the '.code64' directive" do
177
- expect(subject.emit_program(program)).to match(/^\.code64$/)
178
- end
179
- end
180
- end
181
- end
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'ronin/code/asm/syntax/common'
4
-
5
- describe Ronin::Code::ASM::Syntax::Common do
6
- subject { described_class }
7
-
8
- describe "emit_keyword" do
9
- let(:name) { :_start }
10
-
11
- it "must convert a keyword to a String" do
12
- expect(subject.emit_keyword(name)).to eq(name.to_s)
13
- end
14
- end
15
-
16
- describe "emit_integer" do
17
- let(:integer) { 255 }
18
- let(:hexadecimal) { "0xff" }
19
-
20
- it "must convert it into a hexadecimal value" do
21
- expect(subject.emit_integer(integer)).to eq(hexadecimal)
22
- end
23
-
24
- context "when given a negative number" do
25
- let(:negative) { -255 }
26
- let(:hexadecimal) { "-0xff" }
27
-
28
- it "must convert it into a hexadecimal value" do
29
- expect(subject.emit_integer(negative)).to eq(hexadecimal)
30
- end
31
- end
32
- end
33
-
34
- describe "emit_label" do
35
- let(:name) { :_start }
36
- let(:label) { '_start:' }
37
-
38
- it "must append a ':' to the name" do
39
- expect(subject.emit_label(name)).to eq(label)
40
- end
41
- end
42
- end
@@ -1,174 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'ronin/code/asm/syntax/intel'
4
- require 'ronin/code/asm/register'
5
- require 'ronin/code/asm/immediate_operand'
6
- require 'ronin/code/asm/memory_operand'
7
- require 'ronin/code/asm/instruction'
8
- require 'ronin/code/asm/program'
9
-
10
- describe Ronin::Code::ASM::Syntax::Intel do
11
- subject { described_class }
12
-
13
- describe "emit_register" do
14
- let(:register) { Ronin::Code::ASM::Register.new(:eax, 4) }
15
-
16
- it "must return the register name" do
17
- expect(subject.emit_register(register)).to eq("eax")
18
- end
19
- end
20
-
21
- describe "emit_immediate_operand" do
22
- let(:operand) { Ronin::Code::ASM::ImmediateOperand.new(255, 1) }
23
-
24
- it "must prepend a size specifier" do
25
- expect(subject.emit_immediate_operand(operand)).to eq("BYTE 0xff")
26
- end
27
- end
28
-
29
- describe "emit_memory_operand" do
30
- let(:register) { Ronin::Code::ASM::Register.new(:eax, 4) }
31
- let(:operand) { Ronin::Code::ASM::MemoryOperand.new(register) }
32
-
33
- it "must enclose the memory in brackets" do
34
- expect(subject.emit_memory_operand(operand)).to eq("[eax]")
35
- end
36
-
37
- context "when operand width does not match the base width" do
38
- before { operand.width = 2 }
39
-
40
- it "must specify the width" do
41
- expect(subject.emit_memory_operand(operand)).to eq("WORD [eax]")
42
- end
43
- end
44
-
45
- context "with an offset" do
46
- let(:offset) { 255 }
47
- let(:operand) { Ronin::Code::ASM::MemoryOperand.new(register,offset) }
48
-
49
- it "must add the offset to the base" do
50
- expect(subject.emit_memory_operand(operand)).to eq("[eax+0xff]")
51
- end
52
-
53
- context "when 0" do
54
- let(:operand) { Ronin::Code::ASM::MemoryOperand.new(register,0) }
55
-
56
- it "must omit the offset" do
57
- expect(subject.emit_memory_operand(operand)).to eq("[eax]")
58
- end
59
- end
60
- end
61
-
62
- context "with an index" do
63
- let(:index) { Ronin::Code::ASM::Register.new(:esi, 4) }
64
- let(:operand) { Ronin::Code::ASM::MemoryOperand.new(register,0,index) }
65
-
66
- it "must add the index to the base" do
67
- expect(subject.emit_memory_operand(operand)).to eq("[eax+esi]")
68
- end
69
-
70
- context "with a scale" do
71
- let(:scale) { 4 }
72
- let(:operand) { Ronin::Code::ASM::MemoryOperand.new(register,0,index,scale) }
73
-
74
- it "must multiple the index by the scale" do
75
- expect(subject.emit_memory_operand(operand)).to eq("[eax+esi*0x4]")
76
- end
77
- end
78
- end
79
- end
80
-
81
- describe "emit_instruction" do
82
- context "with no operands" do
83
- let(:instruction) { Ronin::Code::ASM::Instruction.new(:ret, []) }
84
-
85
- it "must emit the instruction name" do
86
- expect(subject.emit_instruction(instruction)).to eq('ret')
87
- end
88
- end
89
-
90
- context "with multiple operands" do
91
- let(:register) { Ronin::Code::ASM::Register.new(:eax, 4) }
92
- let(:immediate) { Ronin::Code::ASM::ImmediateOperand.new(0xff, 1) }
93
- let(:instruction) { Ronin::Code::ASM::Instruction.new(:mov, [register, immediate]) }
94
-
95
- it "must emit the operands" do
96
- expect(subject.emit_instruction(instruction)).to eq("mov\teax,\tBYTE 0xff")
97
- end
98
- end
99
- end
100
-
101
- describe "emit_section" do
102
- it "must emit the section name" do
103
- expect(subject.emit_section(:text)).to eq("section .text")
104
- end
105
- end
106
-
107
- describe "emit_program" do
108
- let(:program) do
109
- Ronin::Code::ASM::Program.new do
110
- mov eax, 0xff
111
- ret
112
- end
113
- end
114
-
115
- it "must output the _start label and the program" do
116
- asm = subject.emit_program(program)
117
-
118
- expect(asm).to eq([
119
- "BITS 32",
120
- "section .text",
121
- "_start:",
122
- "\tmov\teax,\tBYTE 0xff",
123
- "\tret",
124
- ""
125
- ].join($/))
126
- end
127
-
128
- context "when emitting labels" do
129
- let(:program) do
130
- Ronin::Code::ASM::Program.new do
131
- mov eax, 0
132
-
133
- _loop do
134
- inc eax
135
- cmp eax, 10
136
- jl :_loop
137
- end
138
-
139
- ret
140
- end
141
- end
142
-
143
- it "must emit both labels and instructions" do
144
- expect(subject.emit_program(program)).to eq([
145
- "BITS 32",
146
- "section .text",
147
- "_start:",
148
- "\tmov\teax,\tBYTE 0x0",
149
- "_loop:",
150
- "\tinc\teax",
151
- "\tcmp\teax,\tBYTE 0xa",
152
- "\tjl\t_loop",
153
- "\tret",
154
- ""
155
- ].join($/))
156
- end
157
- end
158
-
159
- context "when the program arch is :amd64" do
160
- let(:program) do
161
- Ronin::Code::ASM::Program.new(arch: :amd64) do
162
- push rax
163
- push rbx
164
- mov rax, 0xff
165
- ret
166
- end
167
- end
168
-
169
- it "must include start with the '.code64' directive" do
170
- expect(subject.emit_program(program)).to match(/^BITS 64$/)
171
- end
172
- end
173
- end
174
- end