1212import sys
1313import os
1414
15+ from typing import List , Optional
16+
1517READELF_CMD = os .getenv ('READELF' , '/usr/bin/readelf' )
1618OBJDUMP_CMD = os .getenv ('OBJDUMP' , '/usr/bin/objdump' )
1719OTOOL_CMD = os .getenv ('OTOOL' , '/usr/bin/otool' )
1820
19- def run_command (command ):
21+ def run_command (command ) -> str :
2022 p = subprocess .run (command , stdout = subprocess .PIPE , check = True , universal_newlines = True )
2123 return p .stdout
2224
23- def check_ELF_PIE (executable ):
25+ def check_ELF_PIE (executable ) -> bool :
2426 '''
2527 Check for position independent executable (PIE), allowing for address space randomization.
2628 '''
2729 stdout = run_command ([READELF_CMD , '-h' , '-W' , executable ])
2830
2931 ok = False
3032 for line in stdout .splitlines ():
31- line = line .split ()
32- if len (line )>= 2 and line [0 ] == 'Type:' and line [1 ] == 'DYN' :
33+ tokens = line .split ()
34+ if len (line )>= 2 and tokens [0 ] == 'Type:' and tokens [1 ] == 'DYN' :
3335 ok = True
3436 return ok
3537
@@ -60,7 +62,7 @@ def get_ELF_program_headers(executable):
6062 count += 1
6163 return headers
6264
63- def check_ELF_NX (executable ):
65+ def check_ELF_NX (executable ) -> bool :
6466 '''
6567 Check that no sections are writable and executable (including the stack)
6668 '''
@@ -73,7 +75,7 @@ def check_ELF_NX(executable):
7375 have_wx = True
7476 return have_gnu_stack and not have_wx
7577
76- def check_ELF_RELRO (executable ):
78+ def check_ELF_RELRO (executable ) -> bool :
7779 '''
7880 Check for read-only relocations.
7981 GNU_RELRO program header must exist
@@ -99,7 +101,7 @@ def check_ELF_RELRO(executable):
99101 have_bindnow = True
100102 return have_gnu_relro and have_bindnow
101103
102- def check_ELF_Canary (executable ):
104+ def check_ELF_Canary (executable ) -> bool :
103105 '''
104106 Check for use of stack canary
105107 '''
@@ -126,14 +128,14 @@ def get_PE_dll_characteristics(executable) -> int:
126128IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040
127129IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100
128130
129- def check_PE_DYNAMIC_BASE (executable ):
131+ def check_PE_DYNAMIC_BASE (executable ) -> bool :
130132 '''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)'''
131133 bits = get_PE_dll_characteristics (executable )
132134 return (bits & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE ) == IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
133135
134136# Must support high-entropy 64-bit address space layout randomization
135137# in addition to DYNAMIC_BASE to have secure ASLR.
136- def check_PE_HIGH_ENTROPY_VA (executable ):
138+ def check_PE_HIGH_ENTROPY_VA (executable ) -> bool :
137139 '''PIE: DllCharacteristics bit 0x20 signifies high-entropy ASLR'''
138140 bits = get_PE_dll_characteristics (executable )
139141 return (bits & IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA ) == IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA
@@ -147,12 +149,12 @@ def check_PE_RELOC_SECTION(executable) -> bool:
147149 return True
148150 return False
149151
150- def check_PE_NX (executable ):
152+ def check_PE_NX (executable ) -> bool :
151153 '''NX: DllCharacteristics bit 0x100 signifies nxcompat (DEP)'''
152154 bits = get_PE_dll_characteristics (executable )
153155 return (bits & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT ) == IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
154156
155- def get_MACHO_executable_flags (executable ):
157+ def get_MACHO_executable_flags (executable ) -> List [ str ] :
156158 stdout = run_command ([OTOOL_CMD , '-vh' , executable ])
157159
158160 flags = []
@@ -240,7 +242,7 @@ def check_MACHO_Canary(executable) -> bool:
240242]
241243}
242244
243- def identify_executable (executable ):
245+ def identify_executable (executable ) -> Optional [ str ] :
244246 with open (filename , 'rb' ) as f :
245247 magic = f .read (4 )
246248 if magic .startswith (b'MZ' ):
0 commit comments