rex-arch 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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��