@@ -103,13 +103,21 @@ def _human_readable_size(size, precision=0):
103
103
# dirty fix for section names requiring to get their real names from the string table (as lief does not seem to handle
104
104
# this in every case)
105
105
@lru_cache
106
- def _real_section_names (path ):
107
- from subprocess import check_output
106
+ def _real_section_names (path , logger = None , timeout = 10 ):
107
+ from subprocess import Popen , PIPE , TimeoutExpired
108
+ p , names = Popen (["objdump" , "-h" , path ], stdout = PIPE , stderr = PIPE ), []
108
109
try :
109
- names , out = [], check_output (["objdump" , "-h" , path ]).decode ("latin-1" )
110
- except FileNotFoundError :
110
+ out , err = p .communicate (timeout = timeout )
111
+ except TimeoutExpired :
112
+ if logger :
113
+ logger .debug (f"objdump: timeout ({ timeout } seconds)" )
114
+ return
115
+ if err :
116
+ if logger :
117
+ for l in err .decode ("latin-1" ).strip ().split ("\n " ):
118
+ logger .debug (l )
111
119
return
112
- for l in out .split ("\n " ):
120
+ for l in out .decode ( "latin-1" ). strip (). split ("\n " ):
113
121
m = re .match (r"\s+\d+\s(.*?)\s+" , l )
114
122
if m :
115
123
names .append (m .group (1 ))
@@ -176,7 +184,7 @@ def _handle(n, d):
176
184
# special case: for some executables compiled with debug information, some sections may be named
177
185
# with the format "/[N]" where N is the offset in the string table ; in this case, we
178
186
# compute the real section names
179
- if re .match (r"^\/\d+$" , n ) and _real_section_names (path ):
187
+ if re .match (r"^\/\d+$" , n ) and _real_section_names (path , logger = logger ):
180
188
n = _real_section_names (path )[i ]
181
189
_handle (n , d )
182
190
else : # in some cases, packed executables can have no section ; e.g. UPX(/bin/ls)
@@ -263,7 +271,7 @@ def characteristics(executable, n_samples=N_SAMPLES, window_size=lambda s: 2*s,
263
271
name = __secname (section .name )
264
272
# special case: for some executables compiled with debug information, sections may be of the form "/[N]" (where
265
273
# N is the offset in the string table ; in this case, we compute the real section names)
266
- if re .match (r"^\/\d+$" , name ) and _real_section_names (path ):
274
+ if re .match (r"^\/\d+$" , name ) and _real_section_names (path , logger = kwargs . get ( 'logger' ) ):
267
275
name = _real_section_names (path )[i ]
268
276
start = max (data ['sections' ][- 1 ][1 ] if len (data ['sections' ]) > 0 else 0 , int (section .offset // chunksize ))
269
277
max_end = min (max (start + MIN_ZONE_WIDTH , int ((section .offset + section .size ) // chunksize )),
@@ -473,7 +481,7 @@ def plot(*filenames, img_name=None, img_format="png", dpi=200, labels=None, subl
473
481
h .append (Patch (facecolor = "lightgray" )), l .append ("Overlay" )
474
482
if len (h ) > 0 :
475
483
plt .figlegend (h , l , loc = lloc , ncol = 1 if lloc_side else len (l ), prop = {'size' : 7 })
476
- img_name = img_name or os .path .splitext (os .path .basename (filenames [0 ]))[0 ]
484
+ img_name = str ( img_name ) or os .path .splitext (os .path .basename (filenames [0 ]))[0 ]
477
485
# appending the extension to img_name is necessary for avoiding an error when the filename contains a ".[...]" ;
478
486
# e.g. "PortableWinCDEmu-4.0" => this fails with "ValueError: Format '0' is not supported"
479
487
try :
0 commit comments