Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
PoroCYon
LZMA-Vizualizer
Commits
7506329c
Commit
7506329c
authored
Nov 11, 2021
by
PoroCYon
Browse files
hackyelf: update
parent
dcac53cf
Changes
1
Hide whitespace changes
Inline
Side-by-side
contrib/hackyelf.py
View file @
7506329c
...
...
@@ -17,17 +17,43 @@ PT_LOAD = 1
PT_DYNAMIC
=
2
PT_INTERP
=
3
DT_NULL
=
0
DT_NEEDED
=
1
DT_STRTAB
=
5
DT_SYMTAB
=
6
DT_NULL
=
0
DT_NEEDED
=
1
DT_PLTGOT
=
3
DT_STRTAB
=
5
DT_SYMTAB
=
6
DT_RELA
=
7
DT_RELASZ
=
8
DT_RELAENT
=
9
DT_STRSZ
=
10
DT_SYMENT
=
11
DT_SONAME
=
14
DT_REL
=
17
DT_RELSZ
=
18
DT_RELENT
=
19
DT_PLTREL
=
20
DT_DEBUG
=
21
DT_TEXTREL
=
22
DT_JMPREL
=
23
DT_BIND_NOW
=
24
SHT_NULL
=
0
SHT_PROGBITS
=
1
SHT_SYMTAB
=
2
SHT_STRTAB
=
3
SHT_RELA
=
4
SHT_DYNAMIC
=
6
SHT_NOBITS
=
8
SHT_REL
=
9
SHT_DYNSYM
=
11
SHF_WRITE
=
1
<<
0
SHF_ALLOC
=
1
<<
1
SHF_EXECINSTR
=
1
<<
2
SHF_MERGE
=
1
<<
4
SHF_STRINGS
=
1
<<
5
SHF_INFO_LINK
=
1
<<
6
STB_LOCAL
=
0
STB_GLOBAL
=
1
STB_WEAK
=
2
...
...
@@ -81,6 +107,17 @@ class Sym(NamedTuple):
visibility
:
int
shndx
:
int
class
Rel
(
NamedTuple
):
offset
:
int
symbol
:
Sym
type
:
int
class
Rela
(
NamedTuple
):
offset
:
int
symbol
:
Sym
type
:
int
addend
:
int
Reloc
=
Union
[
Rel
,
Rela
]
class
ELF
(
NamedTuple
):
data
:
bytes
ident
:
bytes
...
...
@@ -92,6 +129,7 @@ class ELF(NamedTuple):
shdrs
:
Sequence
[
Shdr
]
symtab
:
Sequence
[
Sym
]
dynsym
:
Sequence
[
Sym
]
relocs
:
Sequence
[
Reloc
]
is32bit
:
bool
def
readstr
(
data
:
bytes
,
off
:
int
)
->
str
:
...
...
@@ -127,6 +165,19 @@ def parse_dyn32(data: bytes, dynp: Phdr) -> Dyn:
return
ds
def
parse_reloc32
(
data
:
bytes
,
reloff
:
int
,
nrel
:
int
,
entsz
:
int
,
syms
:
Sequence
[
Sym
],
rela
:
bool
)
->
Reloc
:
rr
=
[]
for
off
in
range
(
reloff
,
reloff
+
entsz
*
nrel
,
entsz
):
off
,
inf
,
add
=
unpack
(
'<IIi'
,
data
[
off
:(
off
+
12
)])
if
rela
\
else
(
*
unpack
(
'<Ii'
,
data
[
off
:(
off
+
8
)]),
0
)
sym
=
syms
[
inf
>>
8
]
type
=
inf
&
0xff
rr
.
append
(
Rela
(
off
,
sym
,
type
,
add
)
if
rela
else
Rel
(
off
,
sym
,
type
))
return
rr
def
parse_shdr32
(
data
:
bytes
,
shoff
:
int
,
shentsz
:
int
,
shnum
:
int
,
shstrndx
:
int
)
->
Sequence
[
Shdr
]:
if
shnum
*
shentsz
+
shoff
>
len
(
data
)
or
shentsz
==
0
or
shnum
==
0
or
shoff
==
0
:
...
...
@@ -165,7 +216,7 @@ def parse_sym32(data: bytes, sym: Shdr, strt: Shdr) -> Sequence[Sym]:
if
noff
<
strt
.
size
else
None
s
=
Sym
(
sn
,
val
,
sz
,
(
info
&
15
),
(
info
>>
4
),
other
,
shndx
)
ss
.
append
(
s
)
return
sorted
(
ss
,
key
=
lambda
x
:
x
.
value
)
return
ss
#
sorted(ss, key=lambda x:x.value)
def
parse_32
(
data
:
bytes
)
->
ELF
:
ident
=
data
[:
16
]
...
...
@@ -181,7 +232,7 @@ def parse_32(data: bytes) -> ELF:
shnum
=
unpack
(
'<H'
,
data
[
48
:
48
+
2
])[
0
]
shstrndx
=
unpack
(
'<H'
,
data
[
50
:
50
+
2
])[
0
]
phdrs
=
parse_phdr32
(
data
,
phoff
,
phentsz
,
phnum
)
phdrs
=
[]
if
phentsz
==
0
else
parse_phdr32
(
data
,
phoff
,
phentsz
,
phnum
)
dyn
=
None
for
p
in
phdrs
:
...
...
@@ -196,6 +247,8 @@ def parse_32(data: bytes) -> ELF:
strtabsh
=
[
s
for
s
in
shdrs
if
s
.
type
==
SHT_STRTAB
and
s
.
name
==
".strtab"
]
dynsymsh
=
[
s
for
s
in
shdrs
if
s
.
type
==
SHT_SYMTAB
and
s
.
name
==
".dynsym"
]
dynstrsh
=
[
s
for
s
in
shdrs
if
s
.
type
==
SHT_STRTAB
and
s
.
name
==
".dynstr"
]
relash
=
[
s
for
s
in
shdrs
if
s
.
type
==
SHT_RELA
]
relsh
=
[
s
for
s
in
shdrs
if
s
.
type
==
SHT_REL
]
#print("symtab",symtabsh)
#print("strtab",strtabsh)
...
...
@@ -213,8 +266,19 @@ def parse_32(data: bytes) -> ELF:
dynsym
=
parse_sym32
(
data
,
symtabsh
[
0
],
strtabsh
[
0
])
\
if
len
(
shdrs
)
>
0
else
[]
relocs
=
[]
# TODO: use sh.link to use the correct symbol table
for
sh
in
relash
:
relocs
+=
parse_reloc32
(
data
,
sh
.
offset
,
sh
.
size
//
sh
.
entsize
,
sh
.
entsize
,
symtab
,
True
)
for
sh
in
relsh
:
relocs
+=
parse_reloc32
(
data
,
sh
.
offset
,
sh
.
size
//
sh
.
entsize
,
sh
.
entsize
,
symtab
,
False
)
# TODO: relocs from DT_RELA, DT_REL
return
ELF
(
data
,
ident
,
eclass
,
mach
,
entry
,
phdrs
,
dyn
,
shdrs
,
symtab
,
dynsym
,
True
)
symtab
,
dynsym
,
relocs
,
True
)
def
parse_phdr64
(
data
:
bytes
,
phoff
:
int
,
phentsz
:
int
,
phnum
:
int
)
->
Sequence
[
Phdr
]:
ps
=
[]
...
...
@@ -240,9 +304,23 @@ def parse_dyn64(data: bytes, dynp: Phdr) -> Dyn:
return
ds
def
parse_reloc64
(
data
:
bytes
,
reloff
:
int
,
nrel
:
int
,
entsz
:
int
,
syms
:
Sequence
[
Sym
],
rela
:
bool
)
->
Reloc
:
rr
=
[]
for
off
in
range
(
reloff
,
reloff
+
entsz
*
nrel
,
entsz
):
off
,
inf
,
add
=
unpack
(
'<QQq'
,
data
[
off
:(
off
+
24
)])
if
rela
\
else
(
*
unpack
(
'<Qq'
,
data
[
off
:(
off
+
16
)]),
0
)
sym
=
syms
[
inf
>>
32
]
type
=
inf
&
0xffffffff
rr
.
append
(
Rela
(
off
,
sym
,
type
,
add
)
if
rela
else
Rel
(
off
,
sym
,
type
))
return
rr
def
parse_shdr64
(
data
:
bytes
,
shoff
:
int
,
shentsz
:
int
,
shnum
:
int
,
shstrndx
:
int
)
->
Sequence
[
Shdr
]:
if
shnum
*
shentsz
+
shoff
>=
len
(
data
)
or
shentsz
==
0
or
shnum
==
0
or
shoff
==
0
:
if
shnum
*
shentsz
+
shoff
>
len
(
data
)
or
shentsz
==
0
or
shnum
==
0
or
shoff
==
0
:
return
[]
ss
=
[]
...
...
@@ -271,9 +349,9 @@ def parse_sym64(data: bytes, sym: Shdr, strt: Shdr) -> Sequence[Sym]:
sn
=
readstr
(
data
,
strt
.
offset
+
noff
)
\
if
noff
<
strt
.
size
else
None
s
=
Sym
(
sn
,
val
,
sz
,
(
info
&
15
),
(
info
>>
4
),
other
,
shndx
)
s
=
Sym
(
sn
,
val
ue
,
sz
,
(
info
&
15
),
(
info
>>
4
),
other
,
shndx
)
ss
.
append
(
s
)
return
sorted
(
ss
,
key
=
lambda
x
:
x
.
value
)
return
ss
#
sorted(ss, key=lambda x:x.value)
def
parse_64
(
data
:
bytes
)
->
ELF
:
ident
=
data
[:
16
]
...
...
@@ -289,7 +367,7 @@ def parse_64(data: bytes) -> ELF:
shnum
=
unpack
(
'<H'
,
data
[
60
:
60
+
2
])[
0
]
shstrndx
=
unpack
(
'<H'
,
data
[
62
:
62
+
2
])[
0
]
phdrs
=
parse_phdr64
(
data
,
phoff
,
phentsz
,
phnum
)
phdrs
=
[]
if
phentsz
==
0
else
parse_phdr64
(
data
,
phoff
,
phentsz
,
phnum
)
dyn
=
None
for
p
in
phdrs
:
...
...
@@ -297,12 +375,14 @@ def parse_64(data: bytes) -> ELF:
dyn
=
parse_dyn64
(
data
,
p
)
break
shdrs
=
parse_shdr64
(
data
,
shoff
,
shentsz
,
shnum
,
shstrndx
)
shdrs
=
[]
if
shentsz
==
0
else
parse_shdr64
(
data
,
shoff
,
shentsz
,
shnum
,
shstrndx
)
symtabsh
=
[
s
for
s
in
shdrs
if
s
.
type
==
SHT_SYMTAB
and
s
.
name
==
".symtab"
]
strtabsh
=
[
s
for
s
in
shdrs
if
s
.
type
==
SHT_STRTAB
and
s
.
name
==
".strtab"
]
dynsymsh
=
[
s
for
s
in
shdrs
if
s
.
type
==
SHT_SYMTAB
and
s
.
name
==
".dynsym"
]
dynstrsh
=
[
s
for
s
in
shdrs
if
s
.
type
==
SHT_STRTAB
and
s
.
name
==
".dynstr"
]
relash
=
[
s
for
s
in
shdrs
if
s
.
type
==
SHT_RELA
]
relsh
=
[
s
for
s
in
shdrs
if
s
.
type
==
SHT_REL
]
assert
len
(
symtabsh
)
<
2
assert
len
(
strtabsh
)
<
2
...
...
@@ -317,8 +397,19 @@ def parse_64(data: bytes) -> ELF:
dynsym
=
parse_sym64
(
data
,
symtabsh
[
0
],
strtabsh
[
0
])
\
if
len
(
shdrs
)
>
0
else
[]
relocs
=
[]
# TODO: use sh.link to use the correct symbol table
for
sh
in
relash
:
relocs
+=
parse_reloc32
(
data
,
sh
.
offset
,
sh
.
size
//
sh
.
entsize
,
sh
.
entsize
,
symtab
,
True
)
for
sh
in
relsh
:
relocs
+=
parse_reloc32
(
data
,
sh
.
offset
,
sh
.
size
//
sh
.
entsize
,
sh
.
entsize
,
symtab
,
False
)
# TODO: relocs from DT_RELA, DT_REL
return
ELF
(
data
,
ident
,
eclass
,
mach
,
entry
,
phdrs
,
dyn
,
shdrs
,
symtab
,
dynsym
,
False
)
symtab
,
dynsym
,
relocs
,
False
)
def
parse
(
data
:
bytes
)
->
ELF
:
assert
data
[:
4
]
==
b
'
\x7F
ELF'
,
"Not a valid ELF file"
# good enough
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment