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,104 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
require 'tempfile'
|
4
|
+
require 'rex/file'
|
5
|
+
require 'rex/text'
|
6
|
+
|
7
|
+
module Rex
|
8
|
+
module Assembly
|
9
|
+
|
10
|
+
###
|
11
|
+
#
|
12
|
+
# This class uses assembly to assemble and disassemble stuff.
|
13
|
+
#
|
14
|
+
###
|
15
|
+
class Nasm
|
16
|
+
|
17
|
+
@@nasm_path = 'assembly'
|
18
|
+
@@ndisasm_path = 'ndisasm'
|
19
|
+
|
20
|
+
#
|
21
|
+
# Ensures that the assembly environment is sane.
|
22
|
+
#
|
23
|
+
def self.check
|
24
|
+
@@nasm_path =
|
25
|
+
Rex::FileUtils.find_full_path('assembly') ||
|
26
|
+
Rex::FileUtils.find_full_path('assembly.exe') ||
|
27
|
+
Rex::FileUtils.find_full_path('nasmw.exe') ||
|
28
|
+
raise(RuntimeError, "No assembly installation was found.")
|
29
|
+
|
30
|
+
@@ndisasm_path =
|
31
|
+
Rex::FileUtils.find_full_path('ndisasm') ||
|
32
|
+
Rex::FileUtils.find_full_path('ndisasm.exe') ||
|
33
|
+
Rex::FileUtils.find_full_path('ndisasmw.exe') ||
|
34
|
+
raise(RuntimeError, "No ndisasm installation was found.")
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# Assembles the supplied assembly and returns the raw opcodes.
|
39
|
+
#
|
40
|
+
def self.assemble(assembly, bits=32)
|
41
|
+
check
|
42
|
+
|
43
|
+
# Open the temporary file
|
44
|
+
tmp = Tempfile.new('nasmXXXX')
|
45
|
+
tmp.binmode
|
46
|
+
|
47
|
+
tpath = tmp.path
|
48
|
+
opath = tmp.path + '.out'
|
49
|
+
|
50
|
+
# Write the assembly data to a file
|
51
|
+
tmp.write("BITS #{bits}\n" + assembly)
|
52
|
+
tmp.flush()
|
53
|
+
tmp.seek(0)
|
54
|
+
|
55
|
+
# Run assembly
|
56
|
+
if (system(@@nasm_path, '-f', 'bin', '-o', opath, tpath) == false)
|
57
|
+
raise RuntimeError, "Assembler did not complete successfully: #{$?.exitstatus}"
|
58
|
+
end
|
59
|
+
|
60
|
+
# Read the assembled text
|
61
|
+
rv = ::IO.read(opath)
|
62
|
+
|
63
|
+
# Remove temporary files
|
64
|
+
File.unlink(opath)
|
65
|
+
tmp.close(true)
|
66
|
+
|
67
|
+
rv
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Disassembles the supplied raw opcodes
|
72
|
+
#
|
73
|
+
def self.disassemble(raw, bits=32)
|
74
|
+
check
|
75
|
+
|
76
|
+
tmp = Tempfile.new('nasmout')
|
77
|
+
tmp.binmode
|
78
|
+
|
79
|
+
tfd = File.open(tmp.path, "wb")
|
80
|
+
|
81
|
+
tfd.write(raw)
|
82
|
+
tfd.flush()
|
83
|
+
tfd.close
|
84
|
+
|
85
|
+
p = ::IO.popen("\"#{@@ndisasm_path}\" -b #{bits} \"#{tmp.path}\"")
|
86
|
+
o = ''
|
87
|
+
|
88
|
+
begin
|
89
|
+
until p.eof?
|
90
|
+
o += p.read
|
91
|
+
end
|
92
|
+
ensure
|
93
|
+
p.close
|
94
|
+
end
|
95
|
+
|
96
|
+
tmp.close(true)
|
97
|
+
|
98
|
+
o
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "rex/bin_tools/version"
|
2
|
+
require 'rex/image_source'
|
3
|
+
require 'rex/elfparsey'
|
4
|
+
require 'rex/elfscan'
|
5
|
+
require 'rex/machparsey'
|
6
|
+
require 'rex/machscan'
|
7
|
+
require 'rex/peparsey'
|
8
|
+
require 'rex/pescan'
|
9
|
+
|
10
|
+
module Rex
|
11
|
+
module BinTools
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
require 'rex/elfparsey/elfbase'
|
4
|
+
require 'rex/elfparsey/exceptions'
|
5
|
+
require 'rex/image_source'
|
6
|
+
|
7
|
+
module Rex
|
8
|
+
module ElfParsey
|
9
|
+
class Elf < ElfBase
|
10
|
+
|
11
|
+
attr_accessor :elf_header, :program_header, :base_addr, :isource
|
12
|
+
|
13
|
+
def initialize(isource)
|
14
|
+
offset = 0
|
15
|
+
base_addr = 0
|
16
|
+
|
17
|
+
# ELF Header
|
18
|
+
elf_header = ElfHeader.new(isource.read(offset, ELF_HEADER_SIZE))
|
19
|
+
|
20
|
+
# Data encoding
|
21
|
+
ei_data = elf_header.e_ident[EI_DATA,1].unpack("C")[0]
|
22
|
+
|
23
|
+
e_phoff = elf_header.e_phoff
|
24
|
+
e_phentsize = elf_header.e_phentsize
|
25
|
+
e_phnum = elf_header.e_phnum
|
26
|
+
|
27
|
+
# Program Header Table
|
28
|
+
program_header = []
|
29
|
+
|
30
|
+
e_phnum.times do |i|
|
31
|
+
offset = e_phoff + (e_phentsize * i)
|
32
|
+
|
33
|
+
program_header << ProgramHeader.new(
|
34
|
+
isource.read(offset, PROGRAM_HEADER_SIZE), ei_data
|
35
|
+
)
|
36
|
+
|
37
|
+
if program_header[-1].p_type == PT_LOAD && program_header[-1].p_flags & PF_EXEC > 0
|
38
|
+
base_addr = program_header[-1].p_vaddr
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
self.elf_header = elf_header
|
44
|
+
self.program_header = program_header
|
45
|
+
self.base_addr = base_addr
|
46
|
+
self.isource = isource
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.new_from_file(filename, disk_backed = false)
|
50
|
+
|
51
|
+
file = ::File.new(filename)
|
52
|
+
# file.binmode # windows... :\
|
53
|
+
|
54
|
+
if disk_backed
|
55
|
+
return self.new(ImageSource::Disk.new(file))
|
56
|
+
else
|
57
|
+
obj = new_from_string(file.read)
|
58
|
+
file.close
|
59
|
+
return obj
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.new_from_string(data)
|
64
|
+
return self.new(ImageSource::Memory.new(data))
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Returns true if this binary is for a 64-bit architecture.
|
69
|
+
#
|
70
|
+
def ptr_64?
|
71
|
+
unless [ ELFCLASS32, ELFCLASS64 ].include?(
|
72
|
+
elf_header.e_ident[EI_CLASS,1].unpack("C*")[0])
|
73
|
+
raise ElfHeaderError, 'Invalid class', caller
|
74
|
+
end
|
75
|
+
|
76
|
+
elf_header.e_ident[EI_CLASS,1].unpack("C*")[0] == ELFCLASS64
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# Returns true if this binary is for a 32-bit architecture.
|
81
|
+
# This check does not take into account 16-bit binaries at the moment.
|
82
|
+
#
|
83
|
+
def ptr_32?
|
84
|
+
ptr_64? == false
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Converts a virtual address to a string representation based on the
|
89
|
+
# underlying architecture.
|
90
|
+
#
|
91
|
+
def ptr_s(rva)
|
92
|
+
(ptr_32?) ? ("0x%.8x" % rva) : ("0x%.16x" % rva)
|
93
|
+
end
|
94
|
+
|
95
|
+
def offset_to_rva(offset)
|
96
|
+
base_addr + offset
|
97
|
+
end
|
98
|
+
|
99
|
+
def rva_to_offset(rva)
|
100
|
+
rva - base_addr
|
101
|
+
end
|
102
|
+
|
103
|
+
def read(offset, len)
|
104
|
+
isource.read(offset, len)
|
105
|
+
end
|
106
|
+
|
107
|
+
def read_rva(rva, len)
|
108
|
+
isource.read(rva_to_offset(rva), len)
|
109
|
+
end
|
110
|
+
|
111
|
+
def index(*args)
|
112
|
+
isource.index(*args)
|
113
|
+
end
|
114
|
+
|
115
|
+
def close
|
116
|
+
isource.close
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,265 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
require 'rex/struct2'
|
4
|
+
|
5
|
+
module Rex
|
6
|
+
module ElfParsey
|
7
|
+
class ElfBase
|
8
|
+
|
9
|
+
# ELF Header
|
10
|
+
|
11
|
+
ELF_HEADER_SIZE = 52
|
12
|
+
|
13
|
+
EI_NIDENT = 16
|
14
|
+
|
15
|
+
ELF32_EHDR_LSB = Rex::Struct2::CStructTemplate.new(
|
16
|
+
[ 'string', 'e_ident', EI_NIDENT, '' ],
|
17
|
+
[ 'uint16v', 'e_type', 0 ],
|
18
|
+
[ 'uint16v', 'e_machine', 0 ],
|
19
|
+
[ 'uint32v', 'e_version', 0 ],
|
20
|
+
[ 'uint32v', 'e_entry', 0 ],
|
21
|
+
[ 'uint32v', 'e_phoff', 0 ],
|
22
|
+
[ 'uint32v', 'e_shoff', 0 ],
|
23
|
+
[ 'uint32v', 'e_flags', 0 ],
|
24
|
+
[ 'uint16v', 'e_ehsize', 0 ],
|
25
|
+
[ 'uint16v', 'e_phentsize', 0 ],
|
26
|
+
[ 'uint16v', 'e_phnum', 0 ],
|
27
|
+
[ 'uint16v', 'e_shentsize', 0 ],
|
28
|
+
[ 'uint16v', 'e_shnum', 0 ],
|
29
|
+
[ 'uint16v', 'e_shstrndx', 0 ]
|
30
|
+
)
|
31
|
+
|
32
|
+
ELF32_EHDR_MSB = Rex::Struct2::CStructTemplate.new(
|
33
|
+
[ 'string', 'e_ident', EI_NIDENT, '' ],
|
34
|
+
[ 'uint16n', 'e_type', 0 ],
|
35
|
+
[ 'uint16n', 'e_machine', 0 ],
|
36
|
+
[ 'uint32n', 'e_version', 0 ],
|
37
|
+
[ 'uint32n', 'e_entry', 0 ],
|
38
|
+
[ 'uint32n', 'e_phoff', 0 ],
|
39
|
+
[ 'uint32n', 'e_shoff', 0 ],
|
40
|
+
[ 'uint32n', 'e_flags', 0 ],
|
41
|
+
[ 'uint16n', 'e_ehsize', 0 ],
|
42
|
+
[ 'uint16n', 'e_phentsize', 0 ],
|
43
|
+
[ 'uint16n', 'e_phnum', 0 ],
|
44
|
+
[ 'uint16n', 'e_shentsize', 0 ],
|
45
|
+
[ 'uint16n', 'e_shnum', 0 ],
|
46
|
+
[ 'uint16n', 'e_shstrndx', 0 ]
|
47
|
+
)
|
48
|
+
|
49
|
+
# e_type This member identifies the object file type
|
50
|
+
|
51
|
+
ET_NONE = 0 # No file type
|
52
|
+
ET_REL = 1 # Relocatable file
|
53
|
+
ET_EXEC = 2 # Executable file
|
54
|
+
ET_DYN = 3 # Shared object file
|
55
|
+
ET_CORE = 4 # Core file
|
56
|
+
ET_LOPROC = 0xff00 # Processor-specific
|
57
|
+
ET_HIPROC = 0xffff # Processor-specific
|
58
|
+
|
59
|
+
#
|
60
|
+
# e_machine This member's value specifies the required architecture for an
|
61
|
+
# individual file.
|
62
|
+
#
|
63
|
+
|
64
|
+
# ET_NONE = 0 # No machine
|
65
|
+
EM_M32 = 1 # AT&T WE 32100
|
66
|
+
EM_SPARC = 2 # SPARC
|
67
|
+
EM_386 = 3 # Intel Architecture
|
68
|
+
EM_68K = 4 # Motorola 68000
|
69
|
+
EM_88K = 5 # Motorola 88000
|
70
|
+
EM_860 = 7 # Intel 80860
|
71
|
+
EM_MIPS = 8 # MIPS RS3000 Big-Endian
|
72
|
+
EM_MIPS_RS4_BE = 10 # MIPS RS4000 Big-Endian
|
73
|
+
|
74
|
+
# e_version This member identifies the object file version
|
75
|
+
|
76
|
+
EV_NONE = 0 # Invalid version
|
77
|
+
EV_CURRENT = 1 # Current version
|
78
|
+
|
79
|
+
|
80
|
+
# ELF Identification
|
81
|
+
|
82
|
+
# e_ident[] Identification indexes
|
83
|
+
|
84
|
+
EI_MAG0 = 0 # File identification
|
85
|
+
EI_MAG1 = 1 # File identification
|
86
|
+
EI_MAG2 = 2 # File identification
|
87
|
+
EI_MAG3 = 3 # File identification
|
88
|
+
EI_CLASS = 4 # File class
|
89
|
+
EI_DATA = 5 # Data encoding
|
90
|
+
EI_VERSION = 6 # File version
|
91
|
+
EI_PAD = 7 # Start of padding bytes
|
92
|
+
# EI_NIDENT = 16 # Size of e_ident[]
|
93
|
+
|
94
|
+
#
|
95
|
+
# EI_MAG0 to EI_MAG3 A file's first 4 bytes hold a "magic number",
|
96
|
+
# identifying the file as an ELF object file.
|
97
|
+
#
|
98
|
+
|
99
|
+
ELFMAG0 = 0x7f # e_ident[EI_MAG0]
|
100
|
+
ELFMAG1 = ?E # e_ident[EI_MAG1]
|
101
|
+
ELFMAG2 = ?L # e_ident[EI_MAG2]
|
102
|
+
ELFMAG3 = ?F # e_ident[EI_MAG3]
|
103
|
+
|
104
|
+
ELFMAG = ELFMAG0.chr + ELFMAG1.chr + ELFMAG2.chr + ELFMAG3.chr
|
105
|
+
|
106
|
+
# EI_CLASS Identifies the file's class, or capacity
|
107
|
+
|
108
|
+
ELFCLASSNONE = 0 # Invalid class
|
109
|
+
ELFCLASS32 = 1 # 32-bit objects
|
110
|
+
ELFCLASS64 = 2 # 64-bit objects
|
111
|
+
|
112
|
+
#
|
113
|
+
# EI_DATA Specifies the data encoding of the processor-specific data in
|
114
|
+
# the object file. The following encodings are currently defined.
|
115
|
+
#
|
116
|
+
|
117
|
+
ELFDATANONE = 0 # Invalid data encoding
|
118
|
+
ELFDATA2LSB = 1 # Least significant byte first
|
119
|
+
ELFDATA2MSB = 2 # Most significant byte first
|
120
|
+
|
121
|
+
class GenericStruct
|
122
|
+
attr_accessor :struct
|
123
|
+
def initialize(_struct)
|
124
|
+
self.struct = _struct
|
125
|
+
end
|
126
|
+
|
127
|
+
# The following methods are just pass-throughs for struct
|
128
|
+
|
129
|
+
# Access a value
|
130
|
+
def v
|
131
|
+
struct.v
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
# Access a value by array
|
136
|
+
def [](*args)
|
137
|
+
struct[*args]
|
138
|
+
end
|
139
|
+
|
140
|
+
# Obtain an array of all fields
|
141
|
+
def keys
|
142
|
+
struct.keys
|
143
|
+
end
|
144
|
+
|
145
|
+
def method_missing(meth, *args)
|
146
|
+
v[meth.to_s] || (raise NoMethodError.new, meth)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class GenericHeader < GenericStruct
|
151
|
+
end
|
152
|
+
|
153
|
+
class ElfHeader < GenericHeader
|
154
|
+
def initialize(rawdata)
|
155
|
+
|
156
|
+
# Identify the data encoding and parse ELF Header
|
157
|
+
elf_header = ELF32_EHDR_LSB.make_struct
|
158
|
+
|
159
|
+
if !elf_header.from_s(rawdata)
|
160
|
+
raise ElfHeaderError, "Couldn't parse ELF Header", caller
|
161
|
+
end
|
162
|
+
|
163
|
+
if elf_header.v['e_ident'][EI_DATA,1].unpack('C')[0] == ELFDATA2MSB
|
164
|
+
elf_header = ELF32_EHDR_MSB.make_struct
|
165
|
+
|
166
|
+
if !elf_header.from_s(rawdata)
|
167
|
+
raise ElfHeaderError, "Couldn't parse ELF Header", caller
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
unless [ ELFDATA2LSB, ELFDATA2MSB ].include?(
|
172
|
+
elf_header.v['e_ident'][EI_DATA,1].unpack('C')[0])
|
173
|
+
raise ElfHeaderError, "Invalid data encoding", caller
|
174
|
+
end
|
175
|
+
|
176
|
+
# Identify the file as an ELF object file
|
177
|
+
unless elf_header.v['e_ident'][EI_MAG0, 4] == ELFMAG
|
178
|
+
raise ElfHeaderError, 'Invalid magic number', caller
|
179
|
+
end
|
180
|
+
|
181
|
+
self.struct = elf_header
|
182
|
+
end
|
183
|
+
|
184
|
+
def e_ident
|
185
|
+
struct.v['e_ident']
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
# Program Header
|
192
|
+
|
193
|
+
PROGRAM_HEADER_SIZE = 32
|
194
|
+
|
195
|
+
ELF32_PHDR_LSB = Rex::Struct2::CStructTemplate.new(
|
196
|
+
[ 'uint32v', 'p_type', 0 ],
|
197
|
+
[ 'uint32v', 'p_offset', 0 ],
|
198
|
+
[ 'uint32v', 'p_vaddr', 0 ],
|
199
|
+
[ 'uint32v', 'p_paddr', 0 ],
|
200
|
+
[ 'uint32v', 'p_filesz', 0 ],
|
201
|
+
[ 'uint32v', 'p_memsz', 0 ],
|
202
|
+
[ 'uint32v', 'p_flags', 0 ],
|
203
|
+
[ 'uint32v', 'p_align', 0 ]
|
204
|
+
)
|
205
|
+
|
206
|
+
ELF32_PHDR_MSB = Rex::Struct2::CStructTemplate.new(
|
207
|
+
[ 'uint32n', 'p_type', 0 ],
|
208
|
+
[ 'uint32n', 'p_offset', 0 ],
|
209
|
+
[ 'uint32n', 'p_vaddr', 0 ],
|
210
|
+
[ 'uint32n', 'p_paddr', 0 ],
|
211
|
+
[ 'uint32n', 'p_filesz', 0 ],
|
212
|
+
[ 'uint32n', 'p_memsz', 0 ],
|
213
|
+
[ 'uint32n', 'p_flags', 0 ],
|
214
|
+
[ 'uint32n', 'p_align', 0 ]
|
215
|
+
)
|
216
|
+
|
217
|
+
# p_flags This member tells which permissions should have the segment
|
218
|
+
|
219
|
+
# Flags
|
220
|
+
|
221
|
+
PF_EXEC = 1
|
222
|
+
PF_WRITE = 2
|
223
|
+
PF_READ = 4
|
224
|
+
|
225
|
+
|
226
|
+
#
|
227
|
+
# p_type This member tells what kind of segment this array element
|
228
|
+
# describes or how to interpret the array element's information.
|
229
|
+
#
|
230
|
+
|
231
|
+
# Segment Types
|
232
|
+
|
233
|
+
PT_NULL = 0
|
234
|
+
PT_LOAD = 1
|
235
|
+
PT_DYNAMIC = 2
|
236
|
+
PT_INTERP = 3
|
237
|
+
PT_NOTE = 4
|
238
|
+
PT_SHLIB = 5
|
239
|
+
PT_PHDR = 6
|
240
|
+
PT_LOPROC = 0x70000000
|
241
|
+
PT_HIPROC = 0x7fffffff
|
242
|
+
|
243
|
+
class ProgramHeader < GenericHeader
|
244
|
+
def initialize(rawdata, ei_data)
|
245
|
+
# Identify the data encoding and parse Program Header
|
246
|
+
if ei_data == ELFDATA2LSB
|
247
|
+
program_header = ELF32_PHDR_LSB.make_struct
|
248
|
+
elsif ei_data == ELFDATA2MSB
|
249
|
+
program_header = ELF32_PHDR_MSB.make_struct
|
250
|
+
else
|
251
|
+
raise ElfHeaderError, "Invalid data encoding", caller
|
252
|
+
end
|
253
|
+
|
254
|
+
if !program_header.from_s(rawdata)
|
255
|
+
raise ProgramHeaderError, "Couldn't parse Program Header", caller
|
256
|
+
end
|
257
|
+
|
258
|
+
self.struct = program_header
|
259
|
+
end
|
260
|
+
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|