Skip to content

Commit 221ff3d

Browse files
committed
Fixed issue with real section names
1 parent 769f461 commit 221ff3d

File tree

2 files changed

+27
-22
lines changed

2 files changed

+27
-22
lines changed

src/pypackerdetect/VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.1.1
1+
1.1.2

src/pypackerdetect/__init__.py

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# -*- coding: UTF-8 -*-
22
import json
33
import os
4-
import pefile
54
import peid
65
import re
7-
from functools import cached_property
6+
from functools import lru_cache
7+
from pefile import PE
88

99

1010
__all__ = ["PyPackerDetect", "PACKERS", "SECTIONS"]
@@ -16,21 +16,26 @@
1616
SECTIONS = json.load(f)['sections']
1717

1818

19-
# dirty fix for section names requiring to get their real names from the string table (as pefile does not seem to handle
20-
# this in every case)
21-
class PE(pefile.PE):
22-
@cached_property
23-
def real_section_names(self):
24-
from subprocess import check_output
25-
try:
26-
names, out = [], check_output(["objdump", "-h", self.path]).decode()
27-
except FileNotFoundError:
28-
return
29-
for l in out.split("\n"):
30-
m = re.match(r"\s+\d+\s(.*?)\s+", l)
31-
if m:
32-
names.append(m.group(1))
33-
return names
19+
@lru_cache
20+
def _real_section_names(path, logger=None, timeout=10):
21+
from subprocess import Popen, PIPE, TimeoutExpired
22+
p, names = Popen(["objdump", "-h", path], stdout=PIPE, stderr=PIPE), []
23+
try:
24+
out, err = p.communicate(timeout=timeout)
25+
except TimeoutExpired:
26+
if logger:
27+
logger.debug(f"objdump: timeout ({timeout} seconds)")
28+
return
29+
if err:
30+
if logger:
31+
for l in err.decode("latin-1").strip().split("\n"):
32+
logger.debug(l)
33+
return
34+
for l in out.decode("latin-1").strip().split("\n"):
35+
m = re.match(r"\s+\d+\s(.*?)\s+", l)
36+
if m:
37+
names.append(m.group(1))
38+
return names
3439

3540

3641
class PyPackerDetect:
@@ -56,7 +61,7 @@ def __add(i, msg):
5661
if self.logger:
5762
self.logger.debug("%s:%s" % (['DETECTION', 'SUSPICION'][i], msg))
5863
r[['detections', 'suspicions'][i]].append(msg)
59-
if not isinstance(pe, pefile.PE):
64+
if not isinstance(pe, PE):
6065
path = pe
6166
pe = PE(path)
6267
pe.path = path
@@ -70,8 +75,8 @@ def __add(i, msg):
7075
# the format "/[N]" where N is the offset in the string table ; in this case, we compute
7176
# the real section names and map them to the shortened ones to compare the relevant names
7277
# with the database of known section names
73-
if re.match(r"^\/\d+$", n) and pe.real_section_names:
74-
n = pe.real_section_names[i]
78+
if re.match(r"^\/\d+$", n) and _real_section_names(pe.path, logger=self.logger):
79+
n = _real_section_names[i]
7580
d['all'].append(n)
7681
if ep >= s.VirtualAddress and ep <= (s.VirtualAddress + s.Misc_VirtualSize):
7782
d['ep'].append(n)
@@ -147,7 +152,7 @@ def __add(i, msg):
147152
@staticmethod
148153
def report(pe, findings):
149154
""" Report findings like the original project. """
150-
print("Packer report for: %s" % (getattr(pe, "path", "unknown path") if isinstance(pe, pefile.PE) else pe))
155+
print("Packer report for: %s" % (getattr(pe, "path", "unknown path") if isinstance(pe, PE) else pe))
151156
print("\tDetections: %d" % len(findings['detections']))
152157
print("\tSuspicions: %d" % len(findings['suspicions']))
153158
if len(findings['detections']) > 0 or len(findings['suspicions']) > 0:

0 commit comments

Comments
 (0)