Skip to content

Python 2.7 compatibility #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 44 additions & 44 deletions BadEntryPointSectionDetector.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,53 @@
from PackerDetector import *

class BadEntryPointSectionDetector(PackerDetector):
def __init__(self, config):
super().__init__(config)
self.acceptableEntrySections = [".text"]
self.alternativeEntrySections = [".code", "text", ".text0", ".text1", ".text2", ".text3"]
self.driverEntrySection = ["INIT"]
self.delphiBssSections = [".BSS", "BSS", ".bss"]
self.delphiEntrySections = [".itext", "CODE"]
def __init__(self, config):
super(BadEntryPointSectionDetector, self).__init__(config)
self.acceptableEntrySections = [".text"]
self.alternativeEntrySections = [".code", "text", ".text0", ".text1", ".text2", ".text3"]
self.driverEntrySection = ["INIT"]
self.delphiBssSections = [".BSS", "BSS", ".bss"]
self.delphiEntrySections = [".itext", "CODE"]

def Run(self, pe, report): # TODO test
if (not self.config["CheckForBadEntryPointSections"]):
return
def Run(self, pe, report): # TODO test
if (not self.config["CheckForBadEntryPointSections"]):
return

entryPoint = pe.OPTIONAL_HEADER.AddressOfEntryPoint
if (entryPoint == 0):
report.IndicateSuspicion("Null entry point")
return
entryPoint = pe.OPTIONAL_HEADER.AddressOfEntryPoint
if (entryPoint == 0):
report.IndicateSuspicion("Null entry point")
return

allSectionNames = []
entryPointSectionNames = []
for section in pe.sections:
try:
secName = GetCleanSectionName(section)
allSectionNames.append(secName)
if (entryPoint >= section.VirtualAddress and entryPoint <= (section.VirtualAddress + section.Misc_VirtualSize)):
entryPointSectionNames.append(secName)
except UnicodeDecodeError:
report.IndicateSuspicion("Section name with invalid characters")
allSectionNames = []
entryPointSectionNames = []
for section in pe.sections:
try:
secName = GetCleanSectionName(section)
allSectionNames.append(secName)
if (entryPoint >= section.VirtualAddress and entryPoint <= (section.VirtualAddress + section.Misc_VirtualSize)):
entryPointSectionNames.append(secName)
except UnicodeDecodeError:
report.IndicateSuspicion("Section name with invalid characters")

entryPointSectionCount = len(entryPointSectionNames)
if (entryPointSectionCount == 0):
report.IndicateSuspicion("Entry point 0x%x doesn't fall in valid section" % entryPoint)
else:
if (entryPointSectionCount > 1):
report.IndicateDetection("Entry point 0x%x falls in overlapping sections: %s" % (entryPoint, FormatStringList(entryPointSectionNames)))
entryPointSectionCount = len(entryPointSectionNames)
if (entryPointSectionCount == 0):
report.IndicateSuspicion("Entry point 0x%x doesn't fall in valid section" % entryPoint)
else:
if (entryPointSectionCount > 1):
report.IndicateDetection("Entry point 0x%x falls in overlapping sections: %s" % (entryPoint, FormatStringList(entryPointSectionNames)))

if (not DoListsIntersect(self.acceptableEntrySections, entryPointSectionNames)):
badEpSec = False
if (DoListsIntersect(self.delphiBssSections, allSectionNames)):
# has bss, see if we have a delphi ep section
badEpSec = not DoListsIntersect(self.delphiEntrySections, entryPointSectionNames)
elif (not DoListsIntersect(self.acceptableEntrySections, allSectionNames)):
# normal entry section doesn't exist anywhere, so check for alternatives
badEpSec = not DoListsIntersect(self.alternativeEntrySections, entryPointSectionNames)
else:
# not regular ep section, not a delphi entry section, not an alternative entry section, and regular entry section name exists,
# so the only possibility left is a driver entry section
badEpSec = not DoListsIntersect(self.driverEntrySection, entryPointSectionNames)
if (not DoListsIntersect(self.acceptableEntrySections, entryPointSectionNames)):
badEpSec = False
if (DoListsIntersect(self.delphiBssSections, allSectionNames)):
# has bss, see if we have a delphi ep section
badEpSec = not DoListsIntersect(self.delphiEntrySections, entryPointSectionNames)
elif (not DoListsIntersect(self.acceptableEntrySections, allSectionNames)):
# normal entry section doesn't exist anywhere, so check for alternatives
badEpSec = not DoListsIntersect(self.alternativeEntrySections, entryPointSectionNames)
else:
# not regular ep section, not a delphi entry section, not an alternative entry section, and regular entry section name exists,
# so the only possibility left is a driver entry section
badEpSec = not DoListsIntersect(self.driverEntrySection, entryPointSectionNames)

if (badEpSec):
report.IndicateDetection("Entry point 0x%x in irregular section(s): %s" % (entryPoint, FormatStringList(entryPointSectionNames)))
if (badEpSec):
report.IndicateDetection("Entry point 0x%x in irregular section(s): %s" % (entryPoint, FormatStringList(entryPointSectionNames)))
30 changes: 15 additions & 15 deletions LowImportCountDetector.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
from PackerDetector import *

class LowImportCountDetector(PackerDetector):
def __init__(self, config):
super().__init__(config)
def __init__(self, config):
super(LowImportCountDetector, self).__init__(config)

def Run(self, pe, report): # TODO test
if (not self.config["CheckForLowImportCount"]):
return
try:
importCount = 0
for library in pe.DIRECTORY_ENTRY_IMPORT:
if (GetCleanStringFromBytes(library.dll).lower() == "mscoree.dll"):
return # .NET assembly, counting imports is misleading as they will have a low number
importCount += len(library.imports)
if (importCount <= self.config["LowImportThreshold"]):
report.IndicateDetection("Too few imports (total: %d)" % importCount)
except AttributeError:
pass
def Run(self, pe, report): # TODO test
if (not self.config["CheckForLowImportCount"]):
return
try:
importCount = 0
for library in pe.DIRECTORY_ENTRY_IMPORT:
if (GetCleanStringFromBytes(library.dll).lower() == "mscoree.dll"):
return # .NET assembly, counting imports is misleading as they will have a low number
importCount += len(library.imports)
if (importCount <= self.config["LowImportThreshold"]):
report.IndicateDetection("Too few imports (total: %d)" % importCount)
except AttributeError:
pass
71 changes: 36 additions & 35 deletions NonStandardSectionNameDetector.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,43 @@
from PackerDetector import *

class NonStandardSectionNameDetector(PackerDetector):
def __init__(self, config):
super().__init__(config)
self.knownSectionNames = [
".00cfg", ".arch", ".autoload_text", ".bindat", ".bootdat", ".bss", ".BSS",
".buildid", ".CLR_UEF", ".code", ".cormeta", ".complua", ".CRT", ".cygwin_dll_common",
".data", ".DATA", ".data1", ".data2", ".data3", ".debug", ".debug$F",
".debug$P", ".debug$S", ".debug$T", ".drectve ", ".didat", ".didata", ".edata",
".eh_fram", ".export", ".fasm", ".flat", ".gfids", ".giats", ".gljmp",
".glue_7t", ".glue_7", ".idata", ".idlsym", ".impdata", ".itext", ".ndata",
".orpc", ".pdata", ".rdata", ".reloc", ".rodata", ".rsrc", ".sbss",
".script", ".shared", ".sdata", ".srdata", ".stab", ".stabstr", ".sxdata",
".text", ".text0", ".text1", ".text2", ".text3", ".textbss", ".tls",
".tls$", ".udata", ".vsdata", ".xdata", ".wixburn", ".wpp_sf ", "BSS",
"CODE", "DATA", "DGROUP", "edata", "idata", "INIT", "minATL",
"PAGE", "rdata", "sdata", "shared", "Shared", "testdata", "text",
"nv_fatb", "nv_FatBi"
]
def __init__(self, config):
super(NonStandardSectionNameDetector, self).__init__(config)

self.knownSectionNames = [
".00cfg", ".arch", ".autoload_text", ".bindat", ".bootdat", ".bss", ".BSS",
".buildid", ".CLR_UEF", ".code", ".cormeta", ".complua", ".CRT", ".cygwin_dll_common",
".data", ".DATA", ".data1", ".data2", ".data3", ".debug", ".debug$F",
".debug$P", ".debug$S", ".debug$T", ".drectve ", ".didat", ".didata", ".edata",
".eh_fram", ".export", ".fasm", ".flat", ".gfids", ".giats", ".gljmp",
".glue_7t", ".glue_7", ".idata", ".idlsym", ".impdata", ".itext", ".ndata",
".orpc", ".pdata", ".rdata", ".reloc", ".rodata", ".rsrc", ".sbss",
".script", ".shared", ".sdata", ".srdata", ".stab", ".stabstr", ".sxdata",
".text", ".text0", ".text1", ".text2", ".text3", ".textbss", ".tls",
".tls$", ".udata", ".vsdata", ".xdata", ".wixburn", ".wpp_sf ", "BSS",
"CODE", "DATA", "DGROUP", "edata", "idata", "INIT", "minATL",
"PAGE", "rdata", "sdata", "shared", "Shared", "testdata", "text",
"nv_fatb", "nv_FatBi"
]


def Run(self, pe, report): # TODO test
if (not self.config["CheckForNonStandardSections"]):
return
unknownSections = []
badSectionNameCount = 0
for section in pe.sections:
try:
secName = GetCleanSectionName(section)
if (secName not in self.knownSectionNames):
unknownSections.append(secName)
except UnicodeDecodeError:
badSectionNameCount += 1
report.IndicateSuspicion("Section name with invalid characters")
def Run(self, pe, report): # TODO test
if (not self.config["CheckForNonStandardSections"]):
return
unknownSections = []
badSectionNameCount = 0
for section in pe.sections:
try:
secName = GetCleanSectionName(section)
if (secName not in self.knownSectionNames):
unknownSections.append(secName)
except UnicodeDecodeError:
badSectionNameCount += 1
report.IndicateSuspicion("Section name with invalid characters")

unknownSectionCount = len(unknownSections)
if (unknownSectionCount >= self.config["NonStandardSectionThreshold"]):
report.IndicateDetection("Detected %d non-standard sections: %s" % (unknownSectionCount, FormatStringList(unknownSections)))
if (badSectionNameCount >= self.config["BadSectionNameThreshold"]):
report.IndicateDetection("Detected %d sections with invalid names" % badSectionNameCount);
unknownSectionCount = len(unknownSections)
if (unknownSectionCount >= self.config["NonStandardSectionThreshold"]):
report.IndicateDetection("Detected %d non-standard sections: %s" % (unknownSectionCount, FormatStringList(unknownSections)))
if (badSectionNameCount >= self.config["BadSectionNameThreshold"]):
report.IndicateDetection("Detected %d sections with invalid names" % badSectionNameCount);

31 changes: 17 additions & 14 deletions PEIDDetector.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@
from PackerDetector import *

class PEIDDetector(PackerDetector):
def __init__(self, config):
super().__init__(config)
if (self.config["UseLargePEIDDatabase"]):
self.signatures = peutils.SignatureDatabase('deps/peid/signatures_long.txt')
else:
self.signatures = peutils.SignatureDatabase('deps/peid/signatures_short.txt')
def __init__(self, config):

def Run(self, pe, report):
if (not self.config["CheckForPEIDSignatures"]):
return
super(PEIDDetector, self).__init__(config)

if (self.config["UseLargePEIDDatabase"]):
self.signatures = peutils.SignatureDatabase('deps/peid/signatures_long.txt')
else:
self.signatures = peutils.SignatureDatabase('deps/peid/signatures_short.txt')

matches = self.signatures.match_all(pe, ep_only=self.config["OnlyPEIDEntryPointSignatures"])
if (not matches):
return
for match in matches:
report.IndicateDetection("Found PEID signature: %s" % match)
def Run(self, pe, report):
if (not self.config["CheckForPEIDSignatures"]):
return

matches = self.signatures.match_all(pe, ep_only=self.config["OnlyPEIDEntryPointSignatures"])
if (not matches):
return

for match in matches:
report.IndicateDetection("Found PEID signature: %s" % match)
10 changes: 5 additions & 5 deletions PackerDetector.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from Utils import *

class PackerDetector:
def __init__(self, config):
self.config = config
class PackerDetector(object):
def __init__(self, config):
self.config = config

def Run(self, pe, report):
raise NotImplementedError
def Run(self, pe, report):
raise NotImplementedError
87 changes: 46 additions & 41 deletions PackerReport.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,48 @@
from __future__ import print_function
from Utils import *

class PackerReport:
def __init__(self, name):
self.name = name
self.detections = 0
self.suspicions = 0
self.failed = False
self.error = ""
self.logs = []

def IndicateDetection(self, message):
self.logs.append("[DETECTION] %s" % message)
self.detections += 1

def IndicateSuspicion(self, message):
self.logs.append("[SUSPICION] %s" % message)
self.suspicions += 1

def IndicateParseFailed(self, message):
self.error = message
self.failed = True

def GetDetections(self):
return self.detections

def GetSuspicions(self):
return self.suspicions

def GetParseFailed(self):
return self.failed

def Print(self, outfn=print):
outfn("Packer report for: %s" % self.name)
if (self.failed):
outfn("\tError: %s" % self.error)
else:
outfn("\tDetections: %d" % self.detections)
outfn("\tSuspicions: %d" % self.suspicions)
outfn("\tLog:")

for log in self.logs:
outfn("\t\t%s" % log)

def default_outfn(msg):
print(msg)

class PackerReport(object):
def __init__(self, name):
self.name = name
self.detections = 0
self.suspicions = 0
self.failed = False
self.error = ""
self.logs = []

def IndicateDetection(self, message):
self.logs.append("[DETECTION] %s" % message)
self.detections += 1

def IndicateSuspicion(self, message):
self.logs.append("[SUSPICION] %s" % message)
self.suspicions += 1

def IndicateParseFailed(self, message):
self.error = message
self.failed = True

def GetDetections(self):
return self.detections

def GetSuspicions(self):
return self.suspicions

def GetParseFailed(self):
return self.failed

def Print(self, outfn=default_outfn):
outfn("Packer report for: %s" % self.name)
if (self.failed):
outfn("\tError: %s" % self.error)
else:
outfn("\tDetections: %d" % self.detections)
outfn("\tSuspicions: %d" % self.suspicions)
outfn("\tLog:")

for log in self.logs:
outfn("\t\t%s" % log)
Loading