rex-bin_tools 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 +1 -0
- data.tar.gz.sig +0 -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 +22 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/msfbinscan +284 -0
- data/bin/msfelfscan +120 -0
- data/bin/msfmachscan +100 -0
- data/bin/msfpescan +184 -0
- data/bin/setup +8 -0
- data/data/identify.txt +3043 -0
- data/lib/rex/assembly/nasm.rb +104 -0
- data/lib/rex/bin_tools.rb +13 -0
- data/lib/rex/bin_tools/version.rb +5 -0
- data/lib/rex/elfparsey.rb +9 -0
- data/lib/rex/elfparsey/elf.rb +121 -0
- data/lib/rex/elfparsey/elfbase.rb +265 -0
- data/lib/rex/elfparsey/exceptions.rb +25 -0
- data/lib/rex/elfscan.rb +10 -0
- data/lib/rex/elfscan/scanner.rb +226 -0
- data/lib/rex/elfscan/search.rb +44 -0
- data/lib/rex/image_source.rb +10 -0
- data/lib/rex/image_source/disk.rb +58 -0
- data/lib/rex/image_source/image_source.rb +48 -0
- data/lib/rex/image_source/memory.rb +35 -0
- data/lib/rex/machparsey.rb +9 -0
- data/lib/rex/machparsey/exceptions.rb +31 -0
- data/lib/rex/machparsey/mach.rb +209 -0
- data/lib/rex/machparsey/machbase.rb +408 -0
- data/lib/rex/machscan.rb +9 -0
- data/lib/rex/machscan/scanner.rb +217 -0
- data/lib/rex/peparsey.rb +10 -0
- data/lib/rex/peparsey/exceptions.rb +30 -0
- data/lib/rex/peparsey/pe.rb +210 -0
- data/lib/rex/peparsey/pe_memdump.rb +61 -0
- data/lib/rex/peparsey/pebase.rb +1662 -0
- data/lib/rex/peparsey/section.rb +128 -0
- data/lib/rex/pescan.rb +11 -0
- data/lib/rex/pescan/analyze.rb +366 -0
- data/lib/rex/pescan/scanner.rb +230 -0
- data/lib/rex/pescan/search.rb +68 -0
- data/rex-bin_tools.gemspec +32 -0
- metadata +284 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module MachParsey
|
5
|
+
|
6
|
+
class MachError < ::RuntimeError
|
7
|
+
end
|
8
|
+
|
9
|
+
class MachParseError < MachError
|
10
|
+
end
|
11
|
+
|
12
|
+
class MachHeaderError < MachParseError
|
13
|
+
end
|
14
|
+
|
15
|
+
class ProgramHeaderError < MachParseError
|
16
|
+
end
|
17
|
+
|
18
|
+
class BoundsError < MachError
|
19
|
+
end
|
20
|
+
|
21
|
+
class FatError < ::RuntimeError
|
22
|
+
end
|
23
|
+
|
24
|
+
class FatParseError < FatError
|
25
|
+
end
|
26
|
+
|
27
|
+
class FatHeaderError < FatParseError
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
require 'rex/machparsey/machbase'
|
4
|
+
require 'rex/machparsey/exceptions'
|
5
|
+
require 'rex/image_source'
|
6
|
+
|
7
|
+
module Rex
|
8
|
+
module MachParsey
|
9
|
+
|
10
|
+
|
11
|
+
class Mach < MachBase
|
12
|
+
attr_accessor :mach_header, :segments, :isource, :bits, :endian, :arch, :fat_offset
|
13
|
+
|
14
|
+
def initialize(isource, offset = 0, fat = false)
|
15
|
+
_parse_mach_header(isource, offset)
|
16
|
+
if fat == true
|
17
|
+
self.fat_offset = offset
|
18
|
+
else
|
19
|
+
self.fat_offset = 0
|
20
|
+
end
|
21
|
+
|
22
|
+
self.isource = isource
|
23
|
+
end
|
24
|
+
|
25
|
+
def _parse_mach_header(isource, offset)
|
26
|
+
self.mach_header = MachHeader.new(isource.read(offset, MACH_HEADER_SIZE_64))
|
27
|
+
bits = mach_header.bits
|
28
|
+
endian = mach_header.endian
|
29
|
+
ncmds = mach_header.ncmds
|
30
|
+
|
31
|
+
if bits == BITS_32
|
32
|
+
offset += MACH_HEADER_SIZE
|
33
|
+
else
|
34
|
+
offset += MACH_HEADER_SIZE_64
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
segments = []
|
39
|
+
ncmds.times do
|
40
|
+
load_command = LoadCommand.new(isource.read(offset, LOAD_COMMAND_SIZE), endian)
|
41
|
+
|
42
|
+
case load_command.cmd
|
43
|
+
when LC_SEGMENT
|
44
|
+
segments << Segment.new(isource.read(offset, SEGMENT_COMMAND_SIZE), bits, endian)
|
45
|
+
when LC_SEGMENT_64
|
46
|
+
segments << Segment.new(isource.read(offset, SEGMENT_COMMAND_SIZE_64), bits, endian)
|
47
|
+
end
|
48
|
+
|
49
|
+
offset += load_command.cmdsize
|
50
|
+
end
|
51
|
+
|
52
|
+
self.mach_header = mach_header
|
53
|
+
self.segments = segments
|
54
|
+
self.isource = isource
|
55
|
+
self.bits = bits
|
56
|
+
self.endian = endian
|
57
|
+
|
58
|
+
return segments
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.new_from_file(filename, disk_backed = false)
|
62
|
+
|
63
|
+
file = ::File.open(filename, "rb")
|
64
|
+
|
65
|
+
if disk_backed
|
66
|
+
return self.new(ImageSource::Disk.new(file))
|
67
|
+
else
|
68
|
+
obj = new_from_string(file.read)
|
69
|
+
file.close
|
70
|
+
return obj
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.new_from_string(data)
|
75
|
+
return self.new(ImageSource::Memory.new(data))
|
76
|
+
end
|
77
|
+
|
78
|
+
def ptr_64?
|
79
|
+
mach_header.bits == BITS_64
|
80
|
+
end
|
81
|
+
|
82
|
+
def ptr_32?
|
83
|
+
ptr_64? == false
|
84
|
+
end
|
85
|
+
|
86
|
+
def ptr_s(vaddr)
|
87
|
+
(ptr_32?) ? ("0x%.8x" % vaddr) : ("0x%.16x" % vaddr)
|
88
|
+
end
|
89
|
+
|
90
|
+
def read(offset, len)
|
91
|
+
isource.read(fat_offset + offset, len)
|
92
|
+
end
|
93
|
+
|
94
|
+
def index(*args)
|
95
|
+
isource.index(*args)
|
96
|
+
end
|
97
|
+
|
98
|
+
def close
|
99
|
+
isource.close
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
class Fat < FatBase
|
105
|
+
attr_accessor :fat_header, :fat_archs, :machos, :isource
|
106
|
+
|
107
|
+
def initialize(isource, offset = 0)
|
108
|
+
self.fat_archs = []
|
109
|
+
self.machos = []
|
110
|
+
self.isource = isource
|
111
|
+
self.fat_header = FatHeader.new(isource.read(offset, FAT_HEADER_SIZE))
|
112
|
+
|
113
|
+
if !self.fat_header
|
114
|
+
raise FatHeaderError, "Could not parse FAT header"
|
115
|
+
end
|
116
|
+
|
117
|
+
print "Detected " + self.fat_header.nfat_arch.to_s + " archs in binary.\n"
|
118
|
+
|
119
|
+
offset += FAT_HEADER_SIZE
|
120
|
+
|
121
|
+
self.fat_header.nfat_arch.times do
|
122
|
+
fat_arch = FatArch.new(isource.read(offset, FAT_ARCH_SIZE), self.fat_header.endian)
|
123
|
+
self.fat_archs << fat_arch
|
124
|
+
self.machos << Mach.new(isource, fat_arch.offset, true)
|
125
|
+
offset += FAT_ARCH_SIZE
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
#this is useful for debugging but we don't use it for anything.
|
132
|
+
def _parse_fat_header(isource, offset)
|
133
|
+
archs = []
|
134
|
+
nfat_arch = self.fat_header.nfat_arch
|
135
|
+
|
136
|
+
print "Number of archs in binary: " + nfat_arch.to_s + "\n"
|
137
|
+
|
138
|
+
nfat_arch.times do
|
139
|
+
arch = FatArch.new(isource.read(offset, FAT_ARCH_SIZE), self.endian)
|
140
|
+
|
141
|
+
case arch.cpu_type
|
142
|
+
|
143
|
+
when CPU_TYPE_I386
|
144
|
+
print "i386\n"
|
145
|
+
|
146
|
+
when CPU_TYPE_X86_64
|
147
|
+
print "x86_64\n"
|
148
|
+
|
149
|
+
when CPU_TYPE_ARM
|
150
|
+
print "Arm\n"
|
151
|
+
|
152
|
+
when CPU_TYPE_POWERPC
|
153
|
+
print "Power PC\n"
|
154
|
+
|
155
|
+
when CPU_TYPE_POWERPC64
|
156
|
+
print "Power PC 64\n"
|
157
|
+
end
|
158
|
+
|
159
|
+
offset += FAT_ARCH_SIZE
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.new_from_file(filename, disk_backed = false)
|
164
|
+
|
165
|
+
file = ::File.open(filename, "rb")
|
166
|
+
|
167
|
+
if disk_backed
|
168
|
+
return self.new(ImageSource::Disk.new(file))
|
169
|
+
else
|
170
|
+
obj = new_from_string(file.read)
|
171
|
+
file.close
|
172
|
+
return obj
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
def self.new_from_string(data)
|
178
|
+
return self.new(ImageSource::Memory.new(data))
|
179
|
+
end
|
180
|
+
|
181
|
+
def ptr_64?
|
182
|
+
mach_header.bits == BITS_64
|
183
|
+
end
|
184
|
+
|
185
|
+
def ptr_32?
|
186
|
+
ptr_64? == false
|
187
|
+
end
|
188
|
+
|
189
|
+
def ptr_s(vaddr)
|
190
|
+
(ptr_32?) ? ("0x%.8x" % vaddr) : ("0x%.16x" % vaddr)
|
191
|
+
end
|
192
|
+
|
193
|
+
def read(offset, len)
|
194
|
+
isource.read(offset, len)
|
195
|
+
end
|
196
|
+
|
197
|
+
def index(*args)
|
198
|
+
isource.index(*args)
|
199
|
+
end
|
200
|
+
|
201
|
+
def close
|
202
|
+
isource.close
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
end
|
209
|
+
end
|
@@ -0,0 +1,408 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
require 'rex/struct2'
|
4
|
+
|
5
|
+
module Rex
|
6
|
+
module MachParsey
|
7
|
+
|
8
|
+
require 'rex/machparsey/exceptions'
|
9
|
+
require 'rex/struct2'
|
10
|
+
|
11
|
+
class GenericStruct
|
12
|
+
attr_accessor :struct
|
13
|
+
def initialize(_struct)
|
14
|
+
self.struct = _struct
|
15
|
+
end
|
16
|
+
|
17
|
+
# Access a value
|
18
|
+
def v
|
19
|
+
struct.v
|
20
|
+
end
|
21
|
+
|
22
|
+
# Access a value by array
|
23
|
+
def [](*args)
|
24
|
+
struct[*args]
|
25
|
+
end
|
26
|
+
|
27
|
+
# Obtain an array of all fields
|
28
|
+
def keys
|
29
|
+
struct.keys
|
30
|
+
end
|
31
|
+
|
32
|
+
def method_missing(meth, *args)
|
33
|
+
v[meth.to_s] || (raise NoMethodError.new, meth)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class GenericHeader < GenericStruct
|
38
|
+
end
|
39
|
+
|
40
|
+
BITS_32 = 0
|
41
|
+
BITS_64 = 1
|
42
|
+
ENDIAN_LSB = 0
|
43
|
+
ENDIAN_MSB = 1
|
44
|
+
|
45
|
+
class MachBase
|
46
|
+
|
47
|
+
MH_MAGIC = 0xfeedface
|
48
|
+
MH_MAGIC_64 = 0xfeedfacf
|
49
|
+
MH_CIGAM = 0xcefaedfe
|
50
|
+
MH_CIGAM_64 = 0xcffaedfe
|
51
|
+
MACH_HEADER_SIZE = 28
|
52
|
+
MACH_HEADER_SIZE_64 = 32
|
53
|
+
|
54
|
+
|
55
|
+
MACH_HEADER_LSB = Rex::Struct2::CStructTemplate.new(
|
56
|
+
['uint32v', 'magic', 0],
|
57
|
+
['uint32v', 'cputype', 0],
|
58
|
+
['uint32v', 'cpusubtype',0],
|
59
|
+
['uint32v', 'filetype', 0],
|
60
|
+
['uint32v', 'ncmds', 0],
|
61
|
+
['uint32v', 'sizeofcmds',0],
|
62
|
+
['uint32v', 'flags', 0]
|
63
|
+
)
|
64
|
+
|
65
|
+
MACH_HEADER_MSB = Rex::Struct2::CStructTemplate.new(
|
66
|
+
['uint32n', 'magic', 0],
|
67
|
+
['uint32n', 'cputype', 0],
|
68
|
+
['uint32n', 'cpusubtype',0],
|
69
|
+
['uint32n', 'filetype', 0],
|
70
|
+
['uint32n', 'ncmds', 0],
|
71
|
+
['uint32n', 'sizeofcmds',0],
|
72
|
+
['uint32n', 'flags', 0]
|
73
|
+
)
|
74
|
+
|
75
|
+
|
76
|
+
MACH_HEADER_64_LSB = Rex::Struct2::CStructTemplate.new(
|
77
|
+
['uint32v', 'magic', 0],
|
78
|
+
['uint32v', 'cputype', 0],
|
79
|
+
['uint32v', 'cpusubtype',0],
|
80
|
+
['uint32v', 'filetype', 0],
|
81
|
+
['uint32v', 'ncmds', 0],
|
82
|
+
['uint32v', 'sizeofcmds',0],
|
83
|
+
['uint32v', 'flags', 0],
|
84
|
+
['uint32v', 'reserved', 0]
|
85
|
+
)
|
86
|
+
|
87
|
+
MACH_HEADER_64_MSB = Rex::Struct2::CStructTemplate.new(
|
88
|
+
['uint32n', 'magic', 0],
|
89
|
+
['uint32n', 'cputype', 0],
|
90
|
+
['uint32n', 'cpusubtype',0],
|
91
|
+
['uint32n', 'filetype', 0],
|
92
|
+
['uint32n', 'ncmds', 0],
|
93
|
+
['uint32n', 'sizeofcmds',0],
|
94
|
+
['uint32n', 'flags', 0],
|
95
|
+
['uint32n', 'reserved', 0]
|
96
|
+
)
|
97
|
+
|
98
|
+
#cpu types for Mach-O binaries
|
99
|
+
CPU_TYPE_I386 = 0x7
|
100
|
+
CPU_TYPE_X86_64 = 0x01000007
|
101
|
+
CPU_TYPE_ARM = 0xC
|
102
|
+
CPU_TYPE_POWERPC = 0x12
|
103
|
+
CPU_TYPE_POWERPC64 = 0x01000012
|
104
|
+
|
105
|
+
CPU_SUBTYPE_LITTLE_ENDIAN = 0
|
106
|
+
CPU_SUBTYPE_BIG_ENDIAN = 1
|
107
|
+
|
108
|
+
LC_SEGMENT = 0x1 #/* segment of this file to be mapped */
|
109
|
+
LC_SYMTAB = 0x2 #/* link-edit stab symbol table info */
|
110
|
+
LC_SYMSEG = 0x3 #/* link-edit gdb symbol table info (obsolete) */
|
111
|
+
LC_THREAD = 0x4 #/* thread */
|
112
|
+
LC_UNIXTHREAD = 0x5 #/* unix thread (includes a stack) */
|
113
|
+
LC_LOADFVMLIB = 0x6 #/* load a specified fixed VM shared library */
|
114
|
+
LC_IDFVMLIB = 0x7 #/* fixed VM shared library identification */
|
115
|
+
LC_IDENT = 0x8 #/* object identification info (obsolete) */
|
116
|
+
LC_FVMFILE = 0x9 #/* fixed VM file inclusion (internal use) */
|
117
|
+
LC_PREPAGE = 0xa #/* prepage command (internal use) */
|
118
|
+
LC_DYSYMTAB = 0xb #/* dynamic link-edit symbol table info */
|
119
|
+
LC_LOAD_DYLIB = 0xc #/* load a dynamicly linked shared library */
|
120
|
+
LC_ID_DYLIB = 0xd #/* dynamicly linked shared lib identification */
|
121
|
+
LC_LOAD_DYLINKER = 0xe #/* load a dynamic linker */
|
122
|
+
LC_ID_DYLINKER = 0xf #/* dynamic linker identification */
|
123
|
+
LC_PREBOUND_DYLIB = 0x10 #/* modules prebound for a dynamicly */
|
124
|
+
LC_SEGMENT_64 = 0x19 #/* segment of this file to be mapped */
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
class MachHeader < GenericHeader
|
130
|
+
attr_accessor :bits, :endian
|
131
|
+
|
132
|
+
def initialize(rawdata)
|
133
|
+
mach_header = MACH_HEADER_LSB.make_struct
|
134
|
+
if !mach_header.from_s(rawdata)
|
135
|
+
raise MachHeaderError, "Could't access Mach-O Magic", caller
|
136
|
+
end
|
137
|
+
|
138
|
+
if mach_header.v['magic'] == MH_MAGIC
|
139
|
+
endian = ENDIAN_LSB
|
140
|
+
bits = BITS_32
|
141
|
+
mach_header = MACH_HEADER_LSB.make_struct
|
142
|
+
elsif mach_header.v['magic'] == MH_CIGAM
|
143
|
+
bits = BITS_32
|
144
|
+
endian = ENDIAN_MSB
|
145
|
+
mach_header = MACH_HEADER_MSB.make_struct
|
146
|
+
elsif mach_header.v['magic'] == MH_MAGIC_64
|
147
|
+
endian = ENDIAN_LSB
|
148
|
+
bits = BITS_64
|
149
|
+
mach_header = MACH_HEADER_LSB.make_struct
|
150
|
+
elsif mach_header.v['magic'] == MH_CIGAM_64
|
151
|
+
endian = ENDIAN_MSB
|
152
|
+
bits = BITS_64
|
153
|
+
mach_header = MACH_HEADER_MSB.make_struct
|
154
|
+
else
|
155
|
+
raise MachHeaderError, "Couldn't find Mach Magic", caller
|
156
|
+
end
|
157
|
+
|
158
|
+
if !mach_header.from_s(rawdata)
|
159
|
+
raise MachHeaderError, "Could't process Mach-O Header", caller
|
160
|
+
end
|
161
|
+
|
162
|
+
self.struct = mach_header
|
163
|
+
self.endian = endian
|
164
|
+
self.bits = bits
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
LOAD_COMMAND_SIZE = 8
|
169
|
+
|
170
|
+
LOAD_COMMAND_LSB = Rex::Struct2::CStructTemplate.new(
|
171
|
+
['uint32v','cmd',0],
|
172
|
+
['uint32v','cmdsize',0]
|
173
|
+
)
|
174
|
+
|
175
|
+
LOAD_COMMAND_MSB = Rex::Struct2::CStructTemplate.new(
|
176
|
+
['uint32n','cmd',0],
|
177
|
+
['uint32n','cmdsize',0]
|
178
|
+
)
|
179
|
+
|
180
|
+
class LoadCommand < GenericHeader
|
181
|
+
def initialize(rawdata, endian)
|
182
|
+
|
183
|
+
if endian == ENDIAN_MSB
|
184
|
+
load_command = LOAD_COMMAND_MSB.make_struct
|
185
|
+
else
|
186
|
+
load_command = LOAD_COMMAND_LSB.make_struct
|
187
|
+
end
|
188
|
+
|
189
|
+
if !load_command.from_s(rawdata)
|
190
|
+
raise MachParseError, "Couldn't parse load command"
|
191
|
+
end
|
192
|
+
|
193
|
+
self.struct = load_command
|
194
|
+
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
SEGMENT_COMMAND_SIZE = 56
|
199
|
+
|
200
|
+
SEGMENT_COMMAND_LSB = Rex::Struct2::CStructTemplate.new(
|
201
|
+
['uint32v', 'cmd', 0],
|
202
|
+
['uint32v', 'cmdsize', 0],
|
203
|
+
['string', 'segname', 16, ''],
|
204
|
+
['uint32v', 'vmaddr', 0],
|
205
|
+
['uint32v', 'vmsize', 0],
|
206
|
+
['uint32v', 'fileoff', 0],
|
207
|
+
['uint32v', 'filesize', 0],
|
208
|
+
['uint32v', 'maxprot', 0],
|
209
|
+
['uint32v', 'initprot', 0],
|
210
|
+
['uint32v', 'nsects', 0],
|
211
|
+
['uint32v', 'flags', 0]
|
212
|
+
)
|
213
|
+
|
214
|
+
SEGMENT_COMMAND_MSB = Rex::Struct2::CStructTemplate.new(
|
215
|
+
['uint32n', 'cmd', 0],
|
216
|
+
['uint32n', 'cmdsize', 0],
|
217
|
+
['string', 'segname', 16, ''],
|
218
|
+
['uint32n', 'vmaddr', 0],
|
219
|
+
['uint32n', 'vmsize', 0],
|
220
|
+
['uint32n', 'fileoff', 0],
|
221
|
+
['uint32n', 'filesize', 0],
|
222
|
+
['uint32n', 'maxprot', 0],
|
223
|
+
['uint32n', 'initprot', 0],
|
224
|
+
['uint32n', 'nsects', 0],
|
225
|
+
['uint32n', 'flags', 0]
|
226
|
+
)
|
227
|
+
|
228
|
+
SEGMENT_COMMAND_SIZE_64 = 72
|
229
|
+
|
230
|
+
SEGMENT_COMMAND_64_LSB = Rex::Struct2::CStructTemplate.new(
|
231
|
+
['uint32v', 'cmd', 0],
|
232
|
+
['uint32v', 'cmdsize', 0],
|
233
|
+
['string', 'segname', 16, ''],
|
234
|
+
['uint64v', 'vmaddr', 0],
|
235
|
+
['uint64v', 'vmsize', 0],
|
236
|
+
['uint64v', 'fileoff', 0],
|
237
|
+
['uint64v', 'filesize', 0],
|
238
|
+
['uint32v', 'maxprot', 0],
|
239
|
+
['uint32v', 'initprot', 0],
|
240
|
+
['uint32v', 'nsects', 0],
|
241
|
+
['uint32v', 'flags', 0]
|
242
|
+
)
|
243
|
+
|
244
|
+
SEGMENT_COMMAND_64_MSB = Rex::Struct2::CStructTemplate.new(
|
245
|
+
['uint32n', 'cmd', 0],
|
246
|
+
['uint32n', 'cmdsize', 0],
|
247
|
+
['string', 'segname', 16, ''],
|
248
|
+
['uint64n', 'vmaddr', 0],
|
249
|
+
['uint64n', 'vmsize', 0],
|
250
|
+
['uint64n', 'fileoff', 0],
|
251
|
+
['uint64n', 'filesize', 0],
|
252
|
+
['uint32n', 'maxprot', 0],
|
253
|
+
['uint32n', 'initprot', 0],
|
254
|
+
['uint32n', 'nsects', 0],
|
255
|
+
['uint32n', 'flags', 0]
|
256
|
+
)
|
257
|
+
|
258
|
+
class Segment < GenericHeader
|
259
|
+
attr_accessor :_bits, :_endian
|
260
|
+
|
261
|
+
def initialize(rawdata, bits, endian)
|
262
|
+
self._bits = bits
|
263
|
+
|
264
|
+
if bits == BITS_64
|
265
|
+
if endian == ENDIAN_MSB
|
266
|
+
segment_command = SEGMENT_COMMAND_64_MSB.make_struct
|
267
|
+
else
|
268
|
+
segment_command = SEGMENT_COMMAND_64_LSB.make_struct
|
269
|
+
end
|
270
|
+
else
|
271
|
+
if endian == ENDIAN_MSB
|
272
|
+
segment_command = SEGMENT_COMMAND_MSB.make_struct
|
273
|
+
else
|
274
|
+
segment_command = SEGMENT_COMMAND_LSB.make_struct
|
275
|
+
end
|
276
|
+
end
|
277
|
+
if !segment_command.from_s(rawdata)
|
278
|
+
raise MachParseError, "Couldn't parse segment command"
|
279
|
+
end
|
280
|
+
|
281
|
+
self.struct = segment_command
|
282
|
+
end
|
283
|
+
|
284
|
+
def Segname
|
285
|
+
v['segname']
|
286
|
+
end
|
287
|
+
|
288
|
+
def Vmaddr
|
289
|
+
v['vmaddr']
|
290
|
+
end
|
291
|
+
|
292
|
+
def Vmsize
|
293
|
+
v['vmsize']
|
294
|
+
end
|
295
|
+
|
296
|
+
def FileOff
|
297
|
+
v['fileoff']
|
298
|
+
end
|
299
|
+
|
300
|
+
def FileSize
|
301
|
+
v['filesize']
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
class Thread < GenericHeader
|
306
|
+
def initialize(rawdata)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
FAT_MAGIC = 0xcafebabe
|
312
|
+
FAT_CIGAM = 0xbebafeca
|
313
|
+
FAT_HEADER_SIZE = 8
|
314
|
+
|
315
|
+
FAT_HEADER_LSB = Rex::Struct2::CStructTemplate.new(
|
316
|
+
['uint32v', 'magic', 0],
|
317
|
+
['uint32v', 'nfat_arch',0]
|
318
|
+
)
|
319
|
+
|
320
|
+
FAT_HEADER_MSB = Rex::Struct2::CStructTemplate.new(
|
321
|
+
['uint32n', 'magic', 0],
|
322
|
+
['uint32n', 'nfat_arch',0]
|
323
|
+
)
|
324
|
+
|
325
|
+
|
326
|
+
FAT_ARCH_SIZE = 20
|
327
|
+
|
328
|
+
FAT_ARCH_LSB = Rex::Struct2::CStructTemplate.new(
|
329
|
+
['uint32v', 'cpu_type', 0],
|
330
|
+
['uint32v', 'cpu_subtype',0],
|
331
|
+
['uint32v', 'offset', 0],
|
332
|
+
['uint32v', 'size', 0],
|
333
|
+
['uint32v', 'align', 0]
|
334
|
+
)
|
335
|
+
|
336
|
+
FAT_ARCH_MSB = Rex::Struct2::CStructTemplate.new(
|
337
|
+
['uint32n', 'cpu_type', 0],
|
338
|
+
['uint32n', 'cpu_subtype',0],
|
339
|
+
['uint32n', 'offset', 0],
|
340
|
+
['uint32n', 'size', 0],
|
341
|
+
['uint32n', 'align', 0]
|
342
|
+
)
|
343
|
+
|
344
|
+
|
345
|
+
class FatBase
|
346
|
+
|
347
|
+
class FatHeader < GenericHeader
|
348
|
+
attr_accessor :nfat_arch, :endian, :exists
|
349
|
+
|
350
|
+
def initialize(rawdata)
|
351
|
+
fat_header = FAT_HEADER_LSB.make_struct
|
352
|
+
if !fat_header.from_s(rawdata)
|
353
|
+
#raise something
|
354
|
+
end
|
355
|
+
|
356
|
+
magic = fat_header.v['magic']
|
357
|
+
if magic == FAT_MAGIC
|
358
|
+
endian = ENDIAN_LSB
|
359
|
+
elsif magic == FAT_CIGAM
|
360
|
+
endian = ENDIAN_MSB
|
361
|
+
fat_header = FAT_HEADER_MSB.make_struct
|
362
|
+
if !fat_header.from_s(rawdata)
|
363
|
+
raise FatHeaderError, "Could not parse FAT header"
|
364
|
+
end
|
365
|
+
else
|
366
|
+
self.exists = 0
|
367
|
+
return
|
368
|
+
end
|
369
|
+
|
370
|
+
self.nfat_arch = fat_header.v['nfat_arch']
|
371
|
+
self.struct = fat_header
|
372
|
+
self.endian = endian
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
class FatArch < GenericHeader
|
377
|
+
attr_accessor :cpu_type, :cpu_subtype, :offset, :size
|
378
|
+
|
379
|
+
def initialize(rawdata, endian)
|
380
|
+
if endian == ENDIAN_LSB
|
381
|
+
fat_arch = FAT_ARCH_LSB.make_struct
|
382
|
+
else
|
383
|
+
fat_arch = FAT_ARCH_MSB.make_struct
|
384
|
+
end
|
385
|
+
|
386
|
+
if !fat_arch.from_s(rawdata)
|
387
|
+
raise FatHeaderError, "Could not parse arch from FAT header"
|
388
|
+
end
|
389
|
+
|
390
|
+
self.cpu_type = fat_arch.v['cpu_type']
|
391
|
+
self.cpu_subtype = fat_arch.v['cpu_subtype']
|
392
|
+
self.offset = fat_arch.v['offset']
|
393
|
+
self.size = fat_arch.v['size']
|
394
|
+
self.struct = fat_arch
|
395
|
+
end
|
396
|
+
|
397
|
+
end
|
398
|
+
|
399
|
+
class Thread < GenericHeader
|
400
|
+
def initialize(rawdata)
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
|
405
|
+
end
|
406
|
+
|
407
|
+
end
|
408
|
+
end
|