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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +3 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +52 -0
- data/Gemfile +4 -0
- data/LICENSE +27 -0
- data/README.md +30 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/rex/arch.rb +173 -0
- data/lib/rex/arch/sparc.rb +75 -0
- data/lib/rex/arch/version.rb +5 -0
- data/lib/rex/arch/x86.rb +556 -0
- data/lib/rex/arch/zarch.rb +17 -0
- data/rex-arch.gemspec +26 -0
- metadata +194 -0
- metadata.gz.sig +1 -0
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
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -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
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
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
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
|
data/lib/rex/arch/x86.rb
ADDED
@@ -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
|
+
|
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��
|