Skip to content

Commit bf7abc0

Browse files
authored
Add ELF.stripped and ELF.debuginfo properties (#2336)
* Add `ELF.stripped` and `ELF.debuginfo` Show status in checksec output too. * Update CHANGELOG * Show stripped and debuginfo status in red in checksec
1 parent 27bc31e commit bf7abc0

File tree

2 files changed

+36
-18
lines changed

2 files changed

+36
-18
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ The table below shows which release corresponds to each branch, and what date th
8686
- [#2339][2339] Fix: Allow setting attributes on gdb Breakpoints
8787
- [#2323][2323] Retry failed lookups after one week in libcdb
8888
- [#2325][2325] Match against local system libc first in libcdb
89+
- [#2336][2336] Add `ELF.stripped` and `ELF.debuginfo` properties
8990

9091
[2242]: https://github.com/Gallopsled/pwntools/pull/2242
9192
[2277]: https://github.com/Gallopsled/pwntools/pull/2277
@@ -103,6 +104,7 @@ The table below shows which release corresponds to each branch, and what date th
103104
[2339]: https://github.com/Gallopsled/pwntools/pull/2339
104105
[2323]: https://github.com/Gallopsled/pwntools/pull/2323
105106
[2325]: https://github.com/Gallopsled/pwntools/pull/2325
107+
[2336]: https://github.com/Gallopsled/pwntools/pull/2336
106108

107109
## 4.12.0 (`beta`)
108110

pwnlib/elf/elf.py

+34-18
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ def debug(self, argv=[], *a, **kw):
448448

449449
def _describe(self, *a, **kw):
450450
log.info_once(
451-
'%s\n%-10s%s-%s-%s\n%s',
451+
'%s\n%-12s%s-%s-%s\n%s',
452452
repr(self.path),
453453
'Arch:',
454454
self.arch,
@@ -2002,6 +2002,16 @@ def packed(self):
20022002
""":class:`bool`: Whether the current binary is packed with UPX."""
20032003
return b'UPX!' in self.get_data()[:0xFF]
20042004

2005+
@property
2006+
def stripped(self):
2007+
""":class:`bool`: Whether the current binary has been stripped of symbols"""
2008+
return not any(section['sh_type'] == 'SHT_SYMTAB' for section in self.iter_sections())
2009+
2010+
@property
2011+
def debuginfo(self):
2012+
""":class:`bool`: Whether the current binary has debug information"""
2013+
return self.get_section_by_name('.debug_info') is not None
2014+
20052015
@property
20062016
def pie(self):
20072017
""":class:`bool`: Whether the current binary is position-independent."""
@@ -2045,68 +2055,74 @@ def checksec(self, banner=True, color=True):
20452055

20462056
# Kernel version?
20472057
if self.version and self.version != (0,):
2048-
res.append('Version:'.ljust(10) + '.'.join(map(str, self.version)))
2058+
res.append('Version:'.ljust(12) + '.'.join(map(str, self.version)))
20492059
if self.build:
2050-
res.append('Build:'.ljust(10) + self.build)
2060+
res.append('Build:'.ljust(12) + self.build)
20512061

20522062
res.extend([
2053-
"RELRO:".ljust(10) + {
2063+
"RELRO:".ljust(12) + {
20542064
'Full': green("Full RELRO"),
20552065
'Partial': yellow("Partial RELRO"),
20562066
None: red("No RELRO")
20572067
}[self.relro],
2058-
"Stack:".ljust(10) + {
2068+
"Stack:".ljust(12) + {
20592069
True: green("Canary found"),
20602070
False: red("No canary found")
20612071
}[self.canary],
2062-
"NX:".ljust(10) + {
2072+
"NX:".ljust(12) + {
20632073
True: green("NX enabled"),
20642074
False: red("NX disabled"),
20652075
None: yellow("NX unknown - GNU_STACK missing"),
20662076
}[self.nx],
2067-
"PIE:".ljust(10) + {
2077+
"PIE:".ljust(12) + {
20682078
True: green("PIE enabled"),
20692079
False: red("No PIE (%#x)" % self.address)
20702080
}[self.pie],
20712081
])
20722082

20732083
# Execstack may be a thing, even with NX enabled, because of glibc
20742084
if self.execstack and self.nx is not False:
2075-
res.append("Stack:".ljust(10) + red("Executable"))
2085+
res.append("Stack:".ljust(12) + red("Executable"))
20762086

20772087
# Are there any RWX areas in the binary?
20782088
#
20792089
# This will occur if NX is disabled and *any* area is
20802090
# RW, or can expressly occur.
20812091
if self.rwx_segments or (not self.nx and self.writable_segments):
2082-
res += [ "RWX:".ljust(10) + red("Has RWX segments") ]
2092+
res += [ "RWX:".ljust(12) + red("Has RWX segments") ]
20832093

20842094
if self.rpath:
2085-
res += [ "RPATH:".ljust(10) + red(repr(self.rpath)) ]
2095+
res += [ "RPATH:".ljust(12) + red(repr(self.rpath)) ]
20862096

20872097
if self.runpath:
2088-
res += [ "RUNPATH:".ljust(10) + red(repr(self.runpath)) ]
2098+
res += [ "RUNPATH:".ljust(12) + red(repr(self.runpath)) ]
20892099

20902100
if self.packed:
2091-
res.append('Packer:'.ljust(10) + red("Packed with UPX"))
2101+
res.append('Packer:'.ljust(12) + red("Packed with UPX"))
20922102

20932103
if self.fortify:
2094-
res.append("FORTIFY:".ljust(10) + green("Enabled"))
2104+
res.append("FORTIFY:".ljust(12) + green("Enabled"))
20952105

20962106
if self.asan:
2097-
res.append("ASAN:".ljust(10) + green("Enabled"))
2107+
res.append("ASAN:".ljust(12) + green("Enabled"))
20982108

20992109
if self.msan:
2100-
res.append("MSAN:".ljust(10) + green("Enabled"))
2110+
res.append("MSAN:".ljust(12) + green("Enabled"))
21012111

21022112
if self.ubsan:
2103-
res.append("UBSAN:".ljust(10) + green("Enabled"))
2113+
res.append("UBSAN:".ljust(12) + green("Enabled"))
21042114

21052115
if self.shadowstack:
2106-
res.append("SHSTK:".ljust(10) + green("Enabled"))
2116+
res.append("SHSTK:".ljust(12) + green("Enabled"))
21072117

21082118
if self.ibt:
2109-
res.append("IBT:".ljust(10) + green("Enabled"))
2119+
res.append("IBT:".ljust(12) + green("Enabled"))
2120+
2121+
if not self.stripped:
2122+
res.append("Stripped:".ljust(12) + red("No"))
2123+
2124+
if self.debuginfo:
2125+
res.append("Debuginfo:".ljust(12) + red("Yes"))
21102126

21112127
# Check for Linux configuration, it must contain more than
21122128
# just the version.

0 commit comments

Comments
 (0)