rex-arch 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1e73a03da5069cff65f1c9d22d50d1d6024eea48
4
+ data.tar.gz: 6f7f9129562968ef1d5d195730f05b2f1d6c5497
5
+ SHA512:
6
+ metadata.gz: 2181d12182bbc956c39468c476b263ff4417dae9cb01a8b231c96c78ae1fc315330ef9d7039a871e317aeb587f64098a76801b3ccf1bbdb6d9568ccf70218a11
7
+ data.tar.gz: 040d3144e31a36a327cb9fc70803be8745b89bc148681d2c107adcb620254a9f4f11ea16c8765cce2e63224a8264242c6154d8982b437356951457f37be05b8b
checksums.yaml.gz.sig ADDED
Binary file
data.tar.gz.sig ADDED
@@ -0,0 +1,3 @@
1
+ f��/��S�M2��qY��Y:���^�v�_7!�˲a�+E����>�W���™�Q/���:hS,n��L���z�r
2
+ �HM̳^���:�![S��8���b1�A]�5��5h��#R�� �qvӃ�l���U������}"�ϡջ����j�FG��h)"�w�� �d�"�y ��ݶ�G
3
+ 4��}5�*�mPw'+qH 4��
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.1.5
5
+ before_install: gem install bundler -v 1.12.5
@@ -0,0 +1,52 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This Code of Conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting the project maintainers at msfdev@metasploit.com. If
39
+ the incident involves a committer, you may report directly to
40
+ egypt@metasploit.com or todb@metasploit.com.
41
+
42
+ All complaints will be reviewed and investigated and will result in a
43
+ response that is deemed necessary and appropriate to the circumstances.
44
+ Maintainers are obligated to maintain confidentiality with regard to the
45
+ reporter of an incident.
46
+
47
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
48
+ version 1.3.0, available at
49
+ [http://contributor-covenant.org/version/1/3/0/][version]
50
+
51
+ [homepage]: http://contributor-covenant.org
52
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rex-arch.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (C) 2012-2013, Rapid7, Inc.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of Rapid7 LLC nor the names of its contributors
15
+ may be used to endorse or promote products derived from this software
16
+ without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # Rex::Arch
2
+
3
+ Ruby Exploitation(Rex) Library which contains architecture specific information such as registers, opcodes, and stack manipulation routines.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'rex-arch'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install rex-arch
20
+
21
+ ## Development
22
+
23
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
24
+
25
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
26
+
27
+ ## Contributing
28
+
29
+ Bug reports and pull requests are welcome on GitHub at https://github.com/rapid7/rex-arch. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
30
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rex/arch"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/rex/arch.rb ADDED
@@ -0,0 +1,173 @@
1
+ # -*- coding: binary -*-
2
+ require "rex/arch/version"
3
+
4
+ module Rex
5
+
6
+
7
+ ###
8
+ #
9
+ # This module provides generalized methods for performing operations that are
10
+ # architecture specific. Furthermore, the modules contained within this
11
+ # module provide features that are specific to a given architecture.
12
+ #
13
+ ###
14
+ module Arch
15
+
16
+ #
17
+ # Architecture classes
18
+ #
19
+ require 'rex/arch/x86'
20
+ require 'rex/arch/sparc'
21
+ require 'rex/arch/zarch'
22
+
23
+ #
24
+ # Architecture constants
25
+ #
26
+ ARCH_ANY = '_any_'
27
+ ARCH_X86 = 'x86'
28
+ ARCH_X86_64 = 'x86_64'
29
+ ARCH_X64 = 'x64' # To be used for compatability with ARCH_X86_64
30
+ ARCH_MIPS = 'mips'
31
+ ARCH_MIPSLE = 'mipsle'
32
+ ARCH_MIPSBE = 'mipsbe'
33
+ ARCH_PPC = 'ppc'
34
+ ARCH_PPC64 = 'ppc64'
35
+ ARCH_CBEA = 'cbea'
36
+ ARCH_CBEA64 = 'cbea64'
37
+ ARCH_SPARC = 'sparc'
38
+ ARCH_CMD = 'cmd'
39
+ ARCH_PHP = 'php'
40
+ ARCH_TTY = 'tty'
41
+ ARCH_ARMLE = 'armle'
42
+ ARCH_ARMBE = 'armbe'
43
+ ARCH_JAVA = 'java'
44
+ ARCH_RUBY = 'ruby'
45
+ ARCH_DALVIK = 'dalvik'
46
+ ARCH_PYTHON = 'python'
47
+ ARCH_NODEJS = 'nodejs'
48
+ ARCH_FIREFOX = 'firefox'
49
+ ARCH_ZARCH = 'zarch'
50
+ ARCH_TYPES =
51
+ [
52
+ ARCH_X86,
53
+ ARCH_X86_64,
54
+ ARCH_MIPS,
55
+ ARCH_MIPSLE,
56
+ ARCH_MIPSBE,
57
+ ARCH_PPC,
58
+ ARCH_PPC64,
59
+ ARCH_CBEA,
60
+ ARCH_CBEA64,
61
+ ARCH_SPARC,
62
+ ARCH_ARMLE,
63
+ ARCH_ARMBE,
64
+ ARCH_CMD,
65
+ ARCH_PHP,
66
+ ARCH_TTY,
67
+ ARCH_JAVA,
68
+ ARCH_RUBY,
69
+ ARCH_DALVIK,
70
+ ARCH_PYTHON,
71
+ ARCH_NODEJS,
72
+ ARCH_FIREFOX,
73
+ ARCH_ZARCH,
74
+ ]
75
+
76
+ ARCH_ALL = ARCH_TYPES
77
+
78
+ #
79
+ # Endian constants
80
+ #
81
+ ENDIAN_LITTLE = 0
82
+ ENDIAN_BIG = 1
83
+
84
+ IS_ENDIAN_LITTLE = ( [1].pack('s') == "\x01\x00" ) ? true : false
85
+ IS_ENDIAN_BIG = ( not IS_ENDIAN_LITTLE )
86
+
87
+ #
88
+ # This routine adjusts the stack pointer for a given architecture.
89
+ #
90
+ def self.adjust_stack_pointer(arch, adjustment)
91
+
92
+ if ( arch.is_a?(::Array))
93
+ arch = arch[0]
94
+ end
95
+
96
+ case arch
97
+ when /x86/
98
+ Rex::Arch::X86.adjust_reg(Rex::Arch::X86::ESP, adjustment)
99
+ else
100
+ nil
101
+ end
102
+ end
103
+
104
+ #
105
+ # This route provides address packing for the specified arch
106
+ #
107
+ def self.pack_addr(arch, addr)
108
+
109
+ if ( arch.is_a?(::Array))
110
+ arch = arch[0]
111
+ end
112
+
113
+ case arch
114
+ when ARCH_X86
115
+ [addr].pack('V')
116
+ when ARCH_X86_64, ARCH_X64
117
+ [addr].pack('Q<')
118
+ when ARCH_MIPS # ambiguous
119
+ [addr].pack('N')
120
+ when ARCH_MIPSBE
121
+ [addr].pack('N')
122
+ when ARCH_MIPSLE
123
+ [addr].pack('V')
124
+ when ARCH_PPC # ambiguous
125
+ [addr].pack('N')
126
+ when ARCH_SPARC
127
+ [addr].pack('N')
128
+ when ARCH_ARMLE
129
+ [addr].pack('V')
130
+ when ARCH_ARMBE
131
+ [addr].pack('N')
132
+ when ARCH_ZARCH
133
+ [addr].pack('Q>')
134
+ end
135
+ end
136
+
137
+ #
138
+ # This routine reports the endianess of a given architecture
139
+ #
140
+ def self.endian(arch)
141
+
142
+ if ( arch.is_a?(::Array))
143
+ arch = arch[0]
144
+ end
145
+
146
+ case arch
147
+ when ARCH_X86
148
+ return ENDIAN_LITTLE
149
+ when ARCH_X86_64
150
+ return ENDIAN_LITTLE
151
+ when ARCH_MIPS # ambiguous
152
+ return ENDIAN_BIG
153
+ when ARCH_MIPSLE
154
+ return ENDIAN_LITTLE
155
+ when ARCH_MIPSBE
156
+ return ENDIAN_BIG
157
+ when ARCH_PPC # ambiguous
158
+ return ENDIAN_BIG
159
+ when ARCH_SPARC
160
+ return ENDIAN_BIG
161
+ when ARCH_ARMLE
162
+ return ENDIAN_LITTLE
163
+ when ARCH_ARMBE
164
+ return ENDIAN_BIG
165
+ when ARCH_ZARCH
166
+ return ENDIAN_BIG
167
+ end
168
+
169
+ return ENDIAN_LITTLE
170
+ end
171
+
172
+ end
173
+ end
@@ -0,0 +1,75 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Arch
5
+
6
+ #
7
+ # Everything here is mostly stolen from vlad's perl sparc stuff
8
+ #
9
+ module Sparc
10
+
11
+ #
12
+ # Register number constants
13
+ #
14
+ RegisterNumber =
15
+ {
16
+ 'g0' => 0, 'g1' => 1, 'g2' => 2, 'g3' => 3,
17
+ 'g4' => 4, 'g5' => 5, 'g6' => 6, 'g7' => 7,
18
+ 'o0' => 8, 'o1' => 9, 'o2' => 10, 'o3' => 11,
19
+ 'o4' => 12, 'o5' => 13, 'o6' => 14, 'o7' => 15,
20
+ 'l0' => 16, 'l1' => 17, 'l2' => 18, 'l3' => 19,
21
+ 'l4' => 20, 'l5' => 21, 'l6' => 22, 'l7' => 23,
22
+ 'i0' => 24, 'i1' => 25, 'i2' => 26, 'i3' => 27,
23
+ 'i4' => 28, 'i5' => 29, 'i6' => 30, 'i7' => 31,
24
+ 'sp' => 14, 'fp' => 30,
25
+ } # :nodoc:
26
+
27
+ #
28
+ # Encodes a SETHI instruction with the value 'constant' being put into 'dst' register
29
+ #
30
+ def self.sethi(constant, dst)
31
+ [
32
+ (RegisterNumber[dst] << 25) |
33
+ (4 << 22) |
34
+ (constant >> 10)
35
+ ].pack('N')
36
+ end
37
+
38
+ #
39
+ # Encodes an OR instruction with the value 'constant' being OR'ed with the 'src' register into the 'dst' register
40
+ #
41
+ def self.ori(src, constant, dst)
42
+ [
43
+ (2 << 30) |
44
+ (RegisterNumber[dst] << 25) |
45
+ (2 << 19) |
46
+ (RegisterNumber[src] << 14) |
47
+ (1 << 13) |
48
+ (constant & 0x1fff)
49
+ ].pack('N')
50
+ end
51
+
52
+ #
53
+ # Puts 'constant' into the 'dst' register using as few instructions as possible by checking the size of the value.
54
+ # XXX: signedness support
55
+ #
56
+ def self.set(constant, dst)
57
+ if (constant <= 4095 and constant >= 0)
58
+ ori('g0', constant, dst)
59
+ elsif (constant & 0x3ff != 0)
60
+ set_dword(constant, dst)
61
+ else
62
+ sethi(constant, dst)
63
+ end
64
+ end
65
+
66
+ #
67
+ # Puts 'constant' into the 'dst' register using both sethi and ori (necessary to use both uncessarily in some cases with encoders)
68
+ #
69
+ def self.set_dword(constant, dst)
70
+ sethi(constant, dst) + ori(dst, constant & 0x3ff, dst)
71
+ end
72
+
73
+ end
74
+
75
+ end end
@@ -0,0 +1,5 @@
1
+ module Rex
2
+ module Arch
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,556 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Arch
5
+
6
+ #
7
+ # everything here is mostly stole from vlad's perl x86 stuff
8
+ #
9
+
10
+ module X86
11
+
12
+ #
13
+ # Register number constants
14
+ #
15
+ EAX = AL = AX = ES = 0
16
+ ECX = CL = CX = CS = 1
17
+ EDX = DL = DX = SS = 2
18
+ EBX = BL = BX = DS = 3
19
+ ESP = AH = SP = FS = 4
20
+ EBP = CH = BP = GS = 5
21
+ ESI = DH = SI = 6
22
+ EDI = BH = DI = 7
23
+
24
+ REG_NAMES32 = [ 'eax', 'ecx', 'edx', 'ebx', 'esp', 'ebp', 'esi', 'edi' ]
25
+
26
+ REG_NAMES16 = [ 'ax', 'cx', 'dx', 'bx', 'sp', 'bp', 'si', 'di' ]
27
+
28
+ REG_NAMES8L = [ 'al', 'cl', 'dl', 'bl', nil, nil, nil, nil ]
29
+
30
+ # Jump tp a specific register
31
+ def self.jmp_reg(str)
32
+ reg = reg_number(str)
33
+ _check_reg(reg)
34
+ "\xFF" + [224 + reg].pack('C')
35
+ end
36
+
37
+ #
38
+ # Generate a LOOP instruction (Decrement ECX and jump short if ECX == 0)
39
+ #
40
+ def self.loop(offset)
41
+ "\xE2" + pack_lsb(rel_number(offset, -2))
42
+ end
43
+
44
+ #
45
+ # This method returns the opcodes that compose a jump instruction to the
46
+ # supplied relative offset.
47
+ def self.jmp(addr)
48
+ "\xe9" + pack_dword(rel_number(addr))
49
+ end
50
+
51
+ #
52
+ # This method adds/subs a packed long integer
53
+ #
54
+ def self.dword_adjust(dword, amount=0)
55
+ pack_dword(dword.unpack('V')[0] + amount)
56
+ end
57
+
58
+ #
59
+ # This method returns the opcodes that compose a tag-based search routine
60
+ #
61
+ def self.searcher(tag)
62
+ "\xbe" + dword_adjust(tag,-1)+ # mov esi, Tag - 1
63
+ "\x46" + # inc esi
64
+ "\x47" + # inc edi (end_search:)
65
+ "\x39\x37" + # cmp [edi],esi
66
+ "\x75\xfb" + # jnz 0xa (end_search)
67
+ "\x46" + # inc esi
68
+ "\x4f" + # dec edi (start_search:)
69
+ "\x39\x77\xfc" + # cmp [edi-0x4],esi
70
+ "\x75\xfa" + # jnz 0x10 (start_search)
71
+ jmp_reg('edi') # jmp edi
72
+ end
73
+
74
+ #
75
+ # Generates a buffer that will copy memory immediately following the stub
76
+ # that is generated to be copied to the stack
77
+ #
78
+ def self.copy_to_stack(len)
79
+ # four byte align
80
+ len = (len + 3) & ~0x3
81
+
82
+ stub =
83
+ "\xeb\x0f"+ # jmp _end
84
+ push_dword(len)+ # push n
85
+ "\x59"+ # pop ecx
86
+ "\x5e"+ # pop esi
87
+ "\x29\xcc"+ # sub esp, ecx
88
+ "\x89\xe7"+ # mov edi, esp
89
+ "\xf3\xa4"+ # rep movsb
90
+ "\xff\xe4"+ # jmp esp
91
+ "\xe8\xec\xff\xff\xff" # call _start
92
+
93
+ stub
94
+ end
95
+
96
+ #
97
+ # This method returns the opcodes that compose a short jump instruction to
98
+ # the supplied relative offset.
99
+ #
100
+ def self.jmp_short(addr)
101
+ "\xeb" + pack_lsb(rel_number(addr, -2))
102
+ end
103
+
104
+ #
105
+ # This method returns the opcodes that compose a relative call instruction
106
+ # to the address specified.
107
+ #
108
+ def self.call(addr)
109
+ "\xe8" + pack_dword(rel_number(addr, -5))
110
+ end
111
+
112
+ #
113
+ # This method returns a number offset to the supplied string.
114
+ #
115
+ def self.rel_number(num, delta = 0)
116
+ s = num.to_s
117
+
118
+ case s[0, 2]
119
+ when '$+'
120
+ num = s[2 .. -1].to_i
121
+ when '$-'
122
+ num = -1 * s[2 .. -1].to_i
123
+ when '0x'
124
+ num = s.hex
125
+ else
126
+ delta = 0
127
+ end
128
+
129
+ return num + delta
130
+ end
131
+
132
+ #
133
+ # This method returns the number associated with a named register.
134
+ #
135
+ def self.reg_number(str)
136
+ return self.const_get(str.upcase)
137
+ end
138
+
139
+ #
140
+ # This method returns the register named associated with a given register
141
+ # number.
142
+ #
143
+ def self.reg_name32(num)
144
+ _check_reg(num)
145
+ return REG_NAMES32[num].dup
146
+ end
147
+
148
+ #
149
+ # This method generates the encoded effective value for a register.
150
+ #
151
+ def self.encode_effective(shift, dst)
152
+ return (0xc0 | (shift << 3) | dst)
153
+ end
154
+
155
+ #
156
+ # This method generates the mod r/m character for a source and destination
157
+ # register.
158
+ #
159
+ def self.encode_modrm(dst, src)
160
+ _check_reg(dst, src)
161
+ return (0xc0 | src | dst << 3).chr
162
+ end
163
+
164
+ #
165
+ # This method generates a push byte instruction.
166
+ #
167
+ def self.push_byte(byte)
168
+ # push byte will sign extend...
169
+ if byte < 128 && byte >= -128
170
+ return "\x6a" + (byte & 0xff).chr
171
+ end
172
+ raise ::ArgumentError, "Can only take signed byte values!", caller()
173
+ end
174
+
175
+ #
176
+ # This method generates a push word instruction.
177
+ #
178
+ def self.push_word(val)
179
+ return "\x66\x68" + pack_word(val)
180
+ end
181
+
182
+ #
183
+ # This method generates a push dword instruction.
184
+ #
185
+ def self.push_dword(val)
186
+ return "\x68" + pack_dword(val)
187
+ end
188
+
189
+ #
190
+ # This method generates a pop dword instruction into a register.
191
+ #
192
+ def self.pop_dword(dst)
193
+ _check_reg(dst)
194
+ return (0x58 | dst).chr
195
+ end
196
+
197
+ #
198
+ # This method generates an instruction that clears the supplied register in
199
+ # a manner that attempts to avoid bad characters, if supplied.
200
+ #
201
+ def self.clear(reg, badchars = '')
202
+ _check_reg(reg)
203
+ return set(reg, 0, badchars)
204
+ end
205
+
206
+ #
207
+ # This method generates the opcodes that set the low byte of a given
208
+ # register to the supplied value.
209
+ #
210
+ def self.mov_byte(reg, val)
211
+ _check_reg(reg)
212
+ # chr will raise RangeError if val not between 0 .. 255
213
+ return (0xb0 | reg).chr + val.chr
214
+ end
215
+
216
+ #
217
+ # This method generates the opcodes that set the low word of a given
218
+ # register to the supplied value.
219
+ #
220
+ def self.mov_word(reg, val)
221
+ _check_reg(reg)
222
+ if val < 0 || val > 0xffff
223
+ raise RangeError, "Can only take unsigned word values!", caller()
224
+ end
225
+ return "\x66" + (0xb8 | reg).chr + pack_word(val)
226
+ end
227
+
228
+ #
229
+ # This method generates the opcodes that set the a register to the
230
+ # supplied value.
231
+ #
232
+ def self.mov_dword(reg, val)
233
+ _check_reg(reg)
234
+ return (0xb8 | reg).chr + pack_dword(val)
235
+ end
236
+
237
+ #
238
+ # This method is a general way of setting a register to a value. Depending
239
+ # on the value supplied, different sets of instructions may be used.
240
+ #
241
+ # TODO: Make this moderatly intelligent so it chain instructions by itself
242
+ # (ie. xor eax, eax + mov al, 4 + xchg ah, al)
243
+ def self.set(dst, val, badchars = '')
244
+ _check_reg(dst)
245
+
246
+ # If the value is 0 try xor/sub dst, dst (2 bytes)
247
+ if val == 0
248
+ opcodes = Rex::Text.remove_badchars("\x29\x2b\x31\x33", badchars)
249
+ if !opcodes.empty?
250
+ return opcodes[rand(opcodes.length)].chr + encode_modrm(dst, dst)
251
+ end
252
+ # TODO: SHL/SHR
253
+ # TODO: AND
254
+ end
255
+
256
+ # try push BYTE val; pop dst (3 bytes)
257
+ begin
258
+ return _check_badchars(push_byte(val) + pop_dword(dst), badchars)
259
+ rescue ::ArgumentError, ::RuntimeError, ::RangeError
260
+ end
261
+
262
+ # try clear dst, mov BYTE dst (4 bytes)
263
+ begin
264
+ unless val == 0 # clear tries to set(dst, 0, badchars), entering an infinite recursion
265
+ return _check_badchars(clear(dst, badchars) + mov_byte(dst, val), badchars)
266
+ end
267
+ rescue ::ArgumentError, ::RuntimeError, ::RangeError
268
+ end
269
+
270
+ # try mov DWORD dst (5 bytes)
271
+ begin
272
+ return _check_badchars(mov_dword(dst, val), badchars)
273
+ rescue ::ArgumentError, ::RuntimeError, ::RangeError
274
+ end
275
+
276
+ # try push DWORD, pop dst (6 bytes)
277
+ begin
278
+ return _check_badchars(push_dword(val) + pop_dword(dst), badchars)
279
+ rescue ::ArgumentError, ::RuntimeError, ::RangeError
280
+ end
281
+
282
+ # try clear dst, mov WORD dst (6 bytes)
283
+ begin
284
+ unless val == 0 # clear tries to set(dst, 0, badchars), entering an infinite recursion
285
+ return _check_badchars(clear(dst, badchars) + mov_word(dst, val), badchars)
286
+ end
287
+ rescue ::ArgumentError, ::RuntimeError, ::RangeError
288
+ end
289
+
290
+ raise RuntimeError, "No valid set instruction could be created!", caller()
291
+ end
292
+
293
+ #
294
+ # Builds a subtraction instruction using the supplied operand
295
+ # and register.
296
+ #
297
+ def self.sub(val, reg, badchars = '', add = false, adjust = false, bits = 0)
298
+ opcodes = []
299
+ shift = (add == true) ? 0 : 5
300
+
301
+ if (bits <= 8 and val >= -0x7f and val <= 0x7f)
302
+ opcodes <<
303
+ ((adjust) ? '' : clear(reg, badchars)) +
304
+ "\x83" +
305
+ [ encode_effective(shift, reg) ].pack('C') +
306
+ [ val.to_i ].pack('C')
307
+ end
308
+
309
+ if (bits <= 16 and val >= -0xffff and val <= 0)
310
+ opcodes <<
311
+ ((adjust) ? '' : clear(reg, badchars)) +
312
+ "\x66\x81" +
313
+ [ encode_effective(shift, reg) ].pack('C') +
314
+ [ val.to_i ].pack('v')
315
+ end
316
+
317
+ opcodes <<
318
+ ((adjust) ? '' : clear(reg, badchars)) +
319
+ "\x81" +
320
+ [ encode_effective(shift, reg) ].pack('C') +
321
+ [ val.to_i ].pack('V')
322
+
323
+ # Search for a compatible opcode
324
+ opcodes.each { |op|
325
+ begin
326
+ _check_badchars(op, badchars)
327
+ rescue
328
+ next
329
+ end
330
+
331
+ return op
332
+ }
333
+
334
+ if opcodes.empty?
335
+ raise RuntimeError, "Could not find a usable opcode", caller()
336
+ end
337
+ end
338
+
339
+ #
340
+ # This method generates the opcodes equivalent to subtracting with a
341
+ # negative value from a given register.
342
+ #
343
+ def self.add(val, reg, badchars = '', adjust = false, bits = 0)
344
+ sub(val, reg, badchars, true, adjust, bits)
345
+ end
346
+
347
+ #
348
+ # This method wrappers packing a short integer as a little-endian buffer.
349
+ #
350
+ def self.pack_word(num)
351
+ [num].pack('v')
352
+ end
353
+
354
+ #
355
+ # This method wrappers packing an integer as a little-endian buffer.
356
+ #
357
+ def self.pack_dword(num)
358
+ [num].pack('V')
359
+ end
360
+
361
+ #
362
+ # This method returns the least significant byte of a packed dword.
363
+ #
364
+ def self.pack_lsb(num)
365
+ pack_dword(num)[0,1]
366
+ end
367
+
368
+ #
369
+ # This method adjusts the value of the ESP register by a given amount.
370
+ #
371
+ def self.adjust_reg(reg, adjustment)
372
+ if (adjustment > 0)
373
+ sub(adjustment, reg, '', false, false, 32)
374
+ else
375
+ add(adjustment, reg, '', true, 32)
376
+ end
377
+ end
378
+
379
+ def self._check_reg(*regs) # :nodoc:
380
+ regs.each { |reg|
381
+ if reg > 7 || reg < 0
382
+ raise ArgumentError, "Invalid register #{reg}", caller()
383
+ end
384
+ }
385
+ return nil
386
+ end
387
+
388
+ def self._check_badchars(data, badchars) # :nodoc:
389
+ idx = Rex::Text.badchar_index(data, badchars)
390
+ if idx
391
+ raise RuntimeError, "Bad character at #{idx}", caller()
392
+ end
393
+ return data
394
+ end
395
+
396
+ #
397
+ # This method returns an array of 'safe' FPU instructions
398
+ #
399
+ def self.fpu_instructions
400
+ fpus = []
401
+
402
+ 0xe8.upto(0xee) { |x| fpus << "\xd9" + x.chr }
403
+ 0xc0.upto(0xcf) { |x| fpus << "\xd9" + x.chr }
404
+ 0xc0.upto(0xdf) { |x| fpus << "\xda" + x.chr }
405
+ 0xc0.upto(0xdf) { |x| fpus << "\xdb" + x.chr }
406
+ 0xc0.upto(0xc7) { |x| fpus << "\xdd" + x.chr }
407
+
408
+ fpus << "\xd9\xd0"
409
+ fpus << "\xd9\xe1"
410
+ fpus << "\xd9\xf6"
411
+ fpus << "\xd9\xf7"
412
+ fpus << "\xd9\xe5"
413
+
414
+ # This FPU instruction seems to fail consistently on Linux
415
+ #fpus << "\xdb\xe1"
416
+
417
+ fpus
418
+ end
419
+
420
+ #
421
+ # This method returns an array containing a geteip stub, a register, and an offset
422
+ # This method will return nil if the getip generation fails
423
+ #
424
+ def self.geteip_fpu(badchars, modified_registers = [])
425
+ #
426
+ # Default badchars to an empty string
427
+ #
428
+ badchars ||= ''
429
+
430
+ #
431
+ # Bail out early if D9 is restricted
432
+ #
433
+ return nil if badchars.index("\xd9")
434
+
435
+ #
436
+ # Create a list of FPU instructions
437
+ #
438
+ fpus = *self.fpu_instructions
439
+ bads = []
440
+ badchars.each_byte do |c|
441
+ fpus.each do |str|
442
+ bads << str if (str.index(c.chr))
443
+ end
444
+ end
445
+ bads.each { |str| fpus.delete(str) }
446
+ return nil if fpus.length == 0
447
+
448
+ #
449
+ # Create a list of registers to use for fnstenv
450
+ #
451
+ dsts = []
452
+ 0.upto(7) do |c|
453
+ dsts << c if (not badchars.index( (0x70+c).chr ))
454
+ end
455
+
456
+ if (dsts.include?(ESP) and badchars.index("\x24"))
457
+ dsts.delete(ESP)
458
+ end
459
+
460
+ return nil if dsts.length == 0
461
+
462
+ #
463
+ # Grab a random FPU instruction
464
+ #
465
+ fpu = fpus[ rand(fpus.length) ]
466
+
467
+ #
468
+ # Grab a random register from dst
469
+ #
470
+ while(dsts.length > 0)
471
+ buf = ''
472
+ mod_registers = [ESP]
473
+ dst = dsts[ rand(dsts.length) ]
474
+ dsts.delete(dst)
475
+
476
+ # If the register is not ESP, copy ESP
477
+ if (dst != ESP)
478
+ mod_registers.push(dst)
479
+ if badchars.index( (0x70 + dst).chr )
480
+ mod_registers.pop(dst)
481
+ next
482
+ end
483
+
484
+ if !(badchars.index("\x89") or badchars.index( (0xE0+dst).chr ))
485
+ buf << "\x89" + (0xE0 + dst).chr
486
+ else
487
+ if badchars.index("\x54")
488
+ mod_registers.pop(dst)
489
+ next
490
+ end
491
+ if badchars.index( (0x58+dst).chr )
492
+ mod_registers.pop(dst)
493
+ next
494
+ end
495
+ buf << "\x54" + (0x58 + dst).chr
496
+ end
497
+ end
498
+
499
+ pad = 0
500
+ while (pad < (128-12) and badchars.index( (256-12-pad).chr))
501
+ pad += 4
502
+ end
503
+
504
+ # Give up on finding a value to use here
505
+ if (pad == (128-12))
506
+ return nil
507
+ end
508
+
509
+ out = buf + fpu + "\xd9" + (0x70 + dst).chr
510
+ out << "\x24" if dst == ESP
511
+ out << (256-12-pad).chr
512
+
513
+ regs = [*(0..7)]
514
+ while (regs.length > 0)
515
+ reg = regs[ rand(regs.length) ]
516
+ regs.delete(reg)
517
+ next if reg == ESP
518
+ next if badchars.index( (0x58 + reg).chr )
519
+ mod_registers.push(reg)
520
+
521
+ # Pop the value back out
522
+ 0.upto(pad / 4) { |c| out << (0x58 + reg).chr }
523
+
524
+ # Fix the value to point to self
525
+ gap = out.length - buf.length
526
+
527
+ mod_registers.uniq!
528
+ modified_registers.concat(mod_registers)
529
+ return [out, REG_NAMES32[reg].upcase, gap]
530
+ end
531
+ mod_registers.pop(dst)
532
+ end
533
+
534
+ return nil
535
+ end
536
+
537
+ #
538
+ # Parse a list of registers as a space or command delimited
539
+ # string and return the internal register IDs as an array
540
+ #
541
+ def self.register_names_to_ids(str)
542
+ register_ids = []
543
+ str.to_s.strip.split(/[,\s]/).
544
+ map {|reg| reg.to_s.strip.upcase }.
545
+ select {|reg| reg.length > 0 }.
546
+ uniq.each do |reg|
547
+ next unless self.const_defined?(reg.intern)
548
+ register_ids << self.const_get(reg.intern)
549
+ end
550
+ register_ids
551
+ end
552
+
553
+ end
554
+
555
+ end end
556
+
@@ -0,0 +1,17 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Arch
5
+
6
+ #
7
+ # base module for ZARCH creation 8/13/15
8
+ # Author: BeS Bigendian Smalls
9
+ #
10
+
11
+ module ZARCH
12
+
13
+
14
+ end
15
+
16
+ end end
17
+
data/rex-arch.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rex/arch/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rex-arch"
8
+ spec.version = Rex::Arch::VERSION
9
+ spec.authors = ["dmohanty-r7"]
10
+ spec.email = ["Dev_Mohanty@rapid7.com"]
11
+
12
+ spec.summary = %q{This library contains architecture specific information such as registers, opcodes, and stack manipulation routines.}
13
+ spec.description = %q{This library contains architecture specific information such as registers, opcodes, and stack manipulation routines.}
14
+ spec.homepage = "https://github.com/rapid7/rex-arch"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.12"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.0"
24
+
25
+ spec.add_runtime_dependency "rex-text"
26
+ end
metadata ADDED
@@ -0,0 +1,194 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rex-arch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - dmohanty-r7
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
14
+ A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
15
+ b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
16
+ MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
17
+ YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
18
+ aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
19
+ jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
20
+ xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
21
+ 1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
22
+ snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
23
+ U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
24
+ 9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
25
+ BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
26
+ AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
27
+ yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
28
+ 38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
29
+ AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
30
+ DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
31
+ HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
32
+ -----END CERTIFICATE-----
33
+ - |
34
+ -----BEGIN CERTIFICATE-----
35
+ MIIEKDCCAxCgAwIBAgILBAAAAAABL07hNVwwDQYJKoZIhvcNAQEFBQAwVzELMAkG
36
+ A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
37
+ b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xMTA0MTMxMDAw
38
+ MDBaFw0xOTA0MTMxMDAwMDBaMFExCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
39
+ YWxTaWduIG52LXNhMScwJQYDVQQDEx5HbG9iYWxTaWduIENvZGVTaWduaW5nIENB
40
+ IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyTxTnEL7XJnKr
41
+ NpfvU79ChF5Y0Yoo/ENGb34oRFALdV0A1zwKRJ4gaqT3RUo3YKNuPxL6bfq2RsNq
42
+ o7gMJygCVyjRUPdhOVW4w+ElhlI8vwUd17Oa+JokMUnVoqni05GrPjxz7/Yp8cg1
43
+ 0DB7f06SpQaPh+LO9cFjZqwYaSrBXrta6G6V/zuAYp2Zx8cvZtX9YhqCVVrG+kB3
44
+ jskwPBvw8jW4bFmc/enWyrRAHvcEytFnqXTjpQhU2YM1O46MIwx1tt6GSp4aPgpQ
45
+ STic0qiQv5j6yIwrJxF+KvvO3qmuOJMi+qbs+1xhdsNE1swMfi9tBoCidEC7tx/0
46
+ O9dzVB/zAgMBAAGjgfowgfcwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYB
47
+ Af8CAQAwHQYDVR0OBBYEFAhu2Lacir/tPtfDdF3MgB+oL1B6MEcGA1UdIARAMD4w
48
+ PAYEVR0gADA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNv
49
+ bS9yZXBvc2l0b3J5LzAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmdsb2Jh
50
+ bHNpZ24ubmV0L3Jvb3QuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMDMB8GA1UdIwQY
51
+ MBaAFGB7ZhpFDZfKiVAvfQTNNKj//P1LMA0GCSqGSIb3DQEBBQUAA4IBAQAiXMXd
52
+ PfQLcNjj9efFjgkBu7GWNlxaB63HqERJUSV6rg2kGTuSnM+5Qia7O2yX58fOEW1o
53
+ kdqNbfFTTVQ4jGHzyIJ2ab6BMgsxw2zJniAKWC/wSP5+SAeq10NYlHNUBDGpeA07
54
+ jLBwwT1+170vKsPi9Y8MkNxrpci+aF5dbfh40r5JlR4VeAiR+zTIvoStvODG3Rjb
55
+ 88rwe8IUPBi4A7qVPiEeP2Bpen9qA56NSvnwKCwwhF7sJnJCsW3LZMMSjNaES2dB
56
+ fLEDF3gJ462otpYtpH6AA0+I98FrWkYVzSwZi9hwnOUtSYhgcqikGVJwQ17a1kYD
57
+ sGgOJO9K9gslJO8k
58
+ -----END CERTIFICATE-----
59
+ - |
60
+ -----BEGIN CERTIFICATE-----
61
+ MIIEyjCCA7KgAwIBAgISESEyE8rNriS4+1dc8jOHEUL8MA0GCSqGSIb3DQEBBQUA
62
+ MFExCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMScwJQYD
63
+ VQQDEx5HbG9iYWxTaWduIENvZGVTaWduaW5nIENBIC0gRzIwHhcNMTMxMDExMTUx
64
+ NTM4WhcNMTYxMDExMTUxNTM4WjBgMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTWFz
65
+ c2FjaHVzZXR0czEPMA0GA1UEBxMGQm9zdG9uMRMwEQYDVQQKEwpSYXBpZDcgTExD
66
+ MRMwEQYDVQQDEwpSYXBpZDcgTExDMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
67
+ CgKCAQEAhD//7+739c69hssg0mD6CXgf2JkuWTcU81dgD7aKcoEPqU8e1FseBvDW
68
+ /Q5fNK2H2NgHV/Msn18zXuK0PkaJXqj/vDsuKB3Hq0BiR2AwyDdEw8K5MK5bgQc2
69
+ tmcVtEAejRoy1Uv5UyfaAYAxG6zsma3buV1fjnEAC3VouRg4+EX/f65H/a6srntK
70
+ 5Etp3D71k2f0oUl8dOqOmSsRJQQ5zSs4ktDvpjAmsvzoA+1svceLYU95mvQsIw2T
71
+ edpmibGMwGw/HmgV+YWBgF5UGvax6zbC2i6DF2YHnDfkNb8/1MEIaxOTAbJTazTK
72
+ 8laCQOyay6L1BNPQKjZBgOge8LZq1wIDAQABo4IBizCCAYcwDgYDVR0PAQH/BAQD
73
+ AgeAMEwGA1UdIARFMEMwQQYJKwYBBAGgMgEyMDQwMgYIKwYBBQUHAgEWJmh0dHBz
74
+ Oi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMAkGA1UdEwQCMAAwEwYD
75
+ VR0lBAwwCgYIKwYBBQUHAwMwPgYDVR0fBDcwNTAzoDGgL4YtaHR0cDovL2NybC5n
76
+ bG9iYWxzaWduLmNvbS9ncy9nc2NvZGVzaWduZzIuY3JsMIGGBggrBgEFBQcBAQR6
77
+ MHgwQAYIKwYBBQUHMAKGNGh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20vY2Fj
78
+ ZXJ0L2dzY29kZXNpZ25nMi5jcnQwNAYIKwYBBQUHMAGGKGh0dHA6Ly9vY3NwMi5n
79
+ bG9iYWxzaWduLmNvbS9nc2NvZGVzaWduZzIwHQYDVR0OBBYEFE536JwFx9SpaEi3
80
+ w8pcq2GRFA5BMB8GA1UdIwQYMBaAFAhu2Lacir/tPtfDdF3MgB+oL1B6MA0GCSqG
81
+ SIb3DQEBBQUAA4IBAQAGpGXHtFLjTTivV+xQPwtZhfPuJ7f+VGTMSAAYWmfzyHXM
82
+ YMFYUWJzSFcuVR2YfxtbS45P7U5Qopd7jBQ0Ygk5h2a+B5nE4+UlhHj665d0zpYM
83
+ 1eWndMaO6WBOYnqtNyi8Dqqc1foKZDNHEDggYhGso7OIBunup+N4sPL9PwQ3eYe6
84
+ mUu8z0E4GXYViaMPOFkqaYnoYgf2L+7L5zKYT4h/NE/P7kj7EbduHgy/v/aAIrNl
85
+ 2SpuQH+SWteq3NXkAmFEEqvLJQ4sbptZt8OP8ghL3pVAvZNFmww/YVszSkShSzcg
86
+ QdihYCSEL2drS2cFd50jBeq71sxUtxbv82DUa2b+
87
+ -----END CERTIFICATE-----
88
+ date: 2016-07-20 00:00:00.000000000 Z
89
+ dependencies:
90
+ - !ruby/object:Gem::Dependency
91
+ name: bundler
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.12'
97
+ type: :development
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.12'
104
+ - !ruby/object:Gem::Dependency
105
+ name: rake
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '10.0'
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '10.0'
118
+ - !ruby/object:Gem::Dependency
119
+ name: rspec
120
+ requirement: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.0'
125
+ type: :development
126
+ prerelease: false
127
+ version_requirements: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.0'
132
+ - !ruby/object:Gem::Dependency
133
+ name: rex-text
134
+ requirement: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ type: :runtime
140
+ prerelease: false
141
+ version_requirements: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ description: This library contains architecture specific information such as registers,
147
+ opcodes, and stack manipulation routines.
148
+ email:
149
+ - Dev_Mohanty@rapid7.com
150
+ executables: []
151
+ extensions: []
152
+ extra_rdoc_files: []
153
+ files:
154
+ - ".gitignore"
155
+ - ".rspec"
156
+ - ".travis.yml"
157
+ - CODE_OF_CONDUCT.md
158
+ - Gemfile
159
+ - LICENSE
160
+ - README.md
161
+ - Rakefile
162
+ - bin/console
163
+ - bin/setup
164
+ - lib/rex/arch.rb
165
+ - lib/rex/arch/sparc.rb
166
+ - lib/rex/arch/version.rb
167
+ - lib/rex/arch/x86.rb
168
+ - lib/rex/arch/zarch.rb
169
+ - rex-arch.gemspec
170
+ homepage: https://github.com/rapid7/rex-arch
171
+ licenses: []
172
+ metadata: {}
173
+ post_install_message:
174
+ rdoc_options: []
175
+ require_paths:
176
+ - lib
177
+ required_ruby_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ required_rubygems_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ requirements: []
188
+ rubyforge_project:
189
+ rubygems_version: 2.4.8
190
+ signing_key:
191
+ specification_version: 4
192
+ summary: This library contains architecture specific information such as registers,
193
+ opcodes, and stack manipulation routines.
194
+ test_files: []
metadata.gz.sig ADDED
@@ -0,0 +1 @@
1
+ :��2�<���5Q0�J�놤c��l�GJ� h������)��L��\'1���]vS,��ٹ?�;��'�y��`i祈% ��%�� �)�]Kt�,;w�d1�C���SwH��M��\� ��P@�l�$� s�-z<C!���>��1�.0���#A�eǂ]���E�d��