def show_me_shellcode(self, buffer):
     try:
         import pylibemu
         shellcode = buffer
         emulator = pylibemu.Emulator()
         offset = emulator.shellcode_getpc_test(shellcode)
         emulator.prepare(shellcode, offset)
         emulator.test()
         return emulator.emu_profile_output
     except ImportError, e:
         return False, e
 def is_it_shellcode(self, buffer):
     try:
         import pylibemu
         shellcode = buffer
         emulator = pylibemu.Emulator()
         offset = emulator.shellcode_getpc_test(shellcode)
         if offset >= 0:
             return True, True
         else:
             return False, str(offset)
     except ImportError, e:
         return False, e
Beispiel #3
0
def init(module_data):
    module_options = { 'proto': [{'tcp': ''}, {'udp': ''}] }

    module_data['emu'] = None
    module_data['cliargs'] = { 'shellprofile': False, 'hexdump': False }

    parse_args(module_data)

    try:
        import pylibemu
        module_data['emu'] = pylibemu.Emulator()
    except ImportError, e:
        module_options['error'] = str(e)
Beispiel #4
0
def main():
    buffer = ""
    try:
        for line in sys.stdin.readlines():
            buffer += line

        print "[+] Testing buffer of size %dB ..." % (len(buffer))

        emulator = pylibemu.Emulator()
        offset = emulator.shellcode_getpc_test(buffer)

        if offset >= 0:
            print "[+] Shellcode I Catch You !"
            emulator.prepare(buffer, offset)
            emulator.test()

            if emulator.emu_profile_output:
                print emulator.emu_profile_output

            with open(file_log, "a+") as logger:
                logger.write("[+] New shellcode detected @ " + get_ma_time())
                logger.write("\nOffset=" + str(offset))
                logger.write("\nShellcode=" + bytearray(buffer))
                logger.write(emulator.emu_profile_output)

        else:
            print "[*] Modifying offset !"
            offset = 0

            with open(file_log, "a+") as logger:
                logger.write("[~] Input @ " + get_ma_time())
                logger.write("\nOffset=" + str(offset))
                logger.write("\nInput detected=" + bytearray(buffer))

            # /!\ /!\ /!\
            emulator.prepare(buffer, offset)
            emulator.test()

            if emulator.emu_profile_output:
                print emulator.emu_profile_output

            emulator.run(
                buffer
            )  # Could be devastating in case of home built encoded shellcodes.

        return 0

    except Excepetion as e:
        print '[-] Error: Shellcode emulation failed!\n{}'.format(e.__class__)
        return 1
Beispiel #5
0
def emu():
    data = ""
    try:
        for line in sys.stdin.readlines():
            data += line
    except e:
        print "error"
    print "[+]testing data of size %dB......" % (len(data))
    emu = pylibemu.Emulator()
    offset = emu.shellcode_getpc_test(data)
    if offset >= 0:
        print "[+] IS SHELLCODE!"
    else:
        print "[-] IS Not A SHELLCODE"
Beispiel #6
0
Datei: DFT.py Projekt: medim/thug
    def check_shellcode(self, shellcode):
        try:
            sc = self.build_shellcode(shellcode)
        except:
            sc = shellcode

        emu = pylibemu.Emulator(enable_hooks = False)
        emu.run(sc)
        
        if emu.emu_profile_output:
            log.ThugLogging.add_code_snippet(emu.emu_profile_output, 'Assembly', 'Shellcode', method = 'Static Analysis')
            log.warning("[Shellcode Profile]\n\n%s" % (emu.emu_profile_output, ))
            self.check_URLDownloadToFile(emu)
        
        self.check_url(sc, shellcode)
        emu.free()
Beispiel #7
0
def emutest():
    emu = pylibemu.Emulator(globs['emuprofilesize'])

    for count, filename in enumerate(globs['binfileslist']):
        fo = open(filename, 'r')
        data = fo.read()
        fo.close()
        offset = emu.shellcode_getpc_test(data)
        if offset >= 0:
            emu.prepare(data, offset)
            emu.test()

            if emu.emu_profile_output:
                print emu.emu_profile_output

            donorm(
                '(%03d/%03d) Testing shellcode file: %s with Libemu: offset = %d'
                % (count + 1, len(globs['binfileslist']), filename, offset))
Beispiel #8
0
    def check_shellcode_pylibemu(self, shellcode, sc):
        if not PYLIBEMU_MODULE:
            return # pragma: no cover

        emu = pylibemu.Emulator(enable_hooks = False)
        emu.run(sc)

        if emu.emu_profile_output:
            profile = emu.emu_profile_output.decode()

            if self.snippet is None:
                self.snippet = self.build_snippet(shellcode)

            self.log_shellcode_profile("LIBEMU", profile)

            self.check_URLDownloadToFile(emu)
            self.check_WinExec(emu)

        emu.free()
Beispiel #9
0
    def check_shellcode(self, shellcode):
        if not shellcode:
            return

        enc = cchardet.detect(shellcode)
        if enc['encoding']:
            try:
                shellcode = shellcode.decode(enc['encoding']).encode('latin1')
            except Exception:
                pass
        else:
            shellcode = shellcode.encode('latin1')

        try:
            sc = self.build_shellcode(shellcode)
        except Exception:
            sc = shellcode

        emu = pylibemu.Emulator(enable_hooks=False)
        emu.run(sc)

        if emu.emu_profile_output:
            # try:
            #    encoded_sc = shellcode.encode('unicode-escape')
            # except:  # pylint:disable=bare-except
            #    encoded_sc = "Unable to encode shellcode"

            snippet = log.ThugLogging.add_shellcode_snippet(
                sc, "Assembly", "Shellcode", method="Static Analysis")

            log.ThugLogging.add_behavior_warn(
                description="[Shellcode Profile] {}".format(
                    emu.emu_profile_output),
                snippet=snippet,
                method="Static Analysis")

            self.check_URLDownloadToFile(emu, snippet)
            self.check_WinExec(emu, snippet)

        self.check_url(sc, shellcode)
        emu.free()
Beispiel #10
0
class Shellcode(object):
    emu = pylibemu.Emulator(enable_hooks=False)

    def __init__(self, window, ctxt, ast, script):
        self.window = window
        self.script = script
        self.ctxt = ctxt
        self.ast = ast
        self.offsets = set()

    def check_URLDownloadToFile(self, emu):
        profile = emu.emu_profile_output

        while True:
            offset = profile.find('URLDownloadToFile')
            if offset < 0:
                break

            profile = profile[offset:]

            p = profile.split(';')
            if len(p) < 2:
                profile = profile[1:]
                continue

            p = p[1].split('"')
            if len(p) < 3:
                profile = profile[1:]
                continue

            url = p[1]
            if url in log.ThugLogging.shellcode_urls:
                return

            try:
                self.window._navigator.fetch(
                    p[1], redirect_type="Found URLDownloadToFile")
                log.ThugLogging.shellcode_urls.add(url)
            except:  #pylint:disable=bare-except
                pass

            profile = profile[1:]

    def search_url(self, sc):
        offset = sc.find('http')

        if offset > 0:
            url = sc[offset:].split()[0]
            if url.endswith("'") or url.endswith('"'):
                url = url[:-1]

            if url in log.ThugLogging.shellcode_urls:
                return

            log.info('[Shellcode Analysis] URL Detected: %s', url)

            try:
                self.window._navigator.fetch(url, redirect_type="URL found")
                log.ThugLogging.shellcode_urls.add(url)
            except:  #pylint:disable=bare-except
                pass

    def run(self):
        trace = None

        with Debugger() as dbg:
            dbg._context = self.ctxt
            _vars = self.ctxt.locals
            #dbg.debugBreak()

            try:
                result = self.ctxt.eval(self.script)
            except (UnicodeDecodeError, TypeError):
                try:
                    enc = log.Encoding.detect(self.script)
                    result = self.ctxt.eval(self.script.decode(
                        enc['encoding']))
                except:  #pylint:disable=bare-except
                    trace = traceback.format_exc()
            except:  #pylint:disable=bare-except
                trace = traceback.format_exc()
            finally:
                if trace:
                    log.ThugLogging.log_warning(trace)
                    return None  ##pylint:disable=lost-exception

            for name in self.ast.names:
                s = None

                if name in _vars.keys():
                    s = _vars[name]

                if not s:
                    continue

                if not isinstance(s, six.string_types):
                    continue

                log.debug("[Shellcode] Testing variable: %s", name)
                self.emu.run(s)

                if self.emu.emu_profile_output:
                    log.ThugLogging.add_code_snippet(
                        self.emu.emu_profile_output, 'Assembly', 'Shellcode')
                    log.warning("[Shellcode Profile]\n\n%s",
                                self.emu.emu_profile_output)
                    self.check_URLDownloadToFile(self.emu)

                self.emu.free()
                self.search_url(s)

        return result
Beispiel #11
0
import pylibemu

# Enter the Shellcode here
shellcode = ".....\x\x\x\x\x\x....."

emulator = pylibemu.Emulator()
offset = emulator.shellcode_getpc_test(shellcode)

if offset >= 0:
  print "[+] IS SHELLCODE!"
else:
  print "[-] NOT SHELLCODE!"

emulator.prepare(shellcode, offset)
emulator.test()
print emulator.emu_profile_output
Beispiel #12
0
class Shellcode:
    emu = pylibemu.Emulator(enable_hooks=False)

    def __init__(self, window, ctxt, ast, script):
        self.window = window
        self.script = script
        self.ctxt = ctxt
        self.ast = ast
        self.offsets = set()

    def _fetch(self, url):
        try:
            response, content = self.window._navigator.fetch(url)
        except:
            return

        if response.status == 404:
            return

        m = hashlib.md5()
        m.update(content)
        h = m.hexdigest()

        log.warning('Saving remote content at %s (MD5: %s)' % (
            url,
            h,
        ))
        with open(os.path.join(log.baseDir, h), 'wb') as fd:
            fd.write(content)

    def check_URLDownloadToFile(self, emu):
        profile = emu.emu_profile_output

        while True:
            offset = profile.find('URLDownloadToFile')
            if offset < 0:
                break

            profile = profile[offset:]

            p = profile.split(';')
            if len(p) < 2:
                profile = profile[1:]
                continue

            p = p[1].split('"')
            if len(p) < 3:
                profile = profile[1:]
                continue

            self._fetch(p[1])
            profile = profile[1:]

    def search_url(self, sc):
        offset = sc.find('http')

        if offset > 0:
            url = sc[offset:].split()[0]
            log.info('[Shellcode Analysis] URL Detected: %s' % (url, ))
            self._fetch(url)

    def run(self):
        result = None

        with Debugger() as dbg:
            dbg._context = self.ctxt
            vars = self.ctxt.locals
            #dbg.debugBreak()

            try:
                result = self.ctxt.eval(self.script)
                PyV8.JSEngine.collect()
            except UnicodeDecodeError:
                enc = chardet.detect(self.script)
                result = self.ctxt.eval(self.script.decode(enc['encoding']))
                PyV8.JSEngine.collect()
            except:
                log.debug(traceback.format_exc())
                return result

            for name in self.ast.names:
                s = None

                if name in vars.keys():
                    s = vars[name]

                if not s:
                    continue

                if not isinstance(s, basestring):
                    continue

                log.debug("[Shellcode] Testing variable: %s" % (name, ))
                self.emu.run(s)

                if self.emu.emu_profile_output:
                    log.ThugLogging.add_code_snippet(
                        self.emu.emu_profile_output, 'Assembly', 'Shellcode')
                    log.warning("[Shellcode Profile]\n\n%s" %
                                (emu.emu_profile_output, ))
                    self.check_URLDownloadToFile(emu)

                self.emu.free()
                #self.search_url(s)

        return result
Beispiel #13
0
class Shellcode(object):
    emu = pylibemu.Emulator(enable_hooks=False)

    def __init__(self, window, ctxt, ast, script):
        self.window = window
        self.script = script
        self.ctxt = ctxt
        self.ast = ast
        self.offsets = set()

    def check_URLDownloadToFile(self, emu):
        profile = emu.emu_profile_output

        while True:
            offset = profile.find('URLDownloadToFile')
            if offset < 0:
                break

            profile = profile[offset:]

            p = profile.split(';')
            if len(p) < 2:
                profile = profile[1:]
                continue

            p = p[1].split('"')
            if len(p) < 3:
                profile = profile[1:]
                continue

            url = p[1]
            if url in log.ThugLogging.shellcode_urls:
                return

            try:
                self.window._navigator.fetch(
                    p[1], redirect_type="Found URLDownloadToFile")
                log.ThugLogging.shellcode_urls.add(url)
            except Exception:
                pass

            profile = profile[1:]

    def search_url(self, sc):
        from thug.DOM.W3C import w3c
        from thug.DOM.Window import Window
        from thug.DOM.DFT import DFT

        offset = sc.find('http')

        if offset > 0:
            url = sc[offset:].split()[0]
            if url.endswith("'") or url.endswith('"'):
                url = url[:-1]

            if url in log.ThugLogging.shellcode_urls:
                return

            log.info('[Shellcode Analysis] URL Detected: %s', url)

            try:
                response = self.window._navigator.fetch(
                    url, redirect_type="URL found")
                log.ThugLogging.shellcode_urls.add(url)
            except Exception:
                return

            if response is None:
                return

            if not response.ok:
                return

            doc = w3c.parseString(response.content)
            window = Window(url, doc, personality=log.ThugOpts.useragent)

            dft = DFT(window)
            dft.run()

    @property
    def dump_url(self):
        if log.ThugOpts.local:
            return log.ThugLogging.url

        url = getattr(log, 'last_url_fetched', None)
        return url if url else self.window.url

    def dump_eval(self):
        name, saved = log.ThugLogging.eval_symbol

        scripts = getattr(self.ctxt.locals, name, None)
        if scripts is None:
            return

        for script in scripts:
            if not isinstance(script, six.string_types):
                continue

            if log.ThugOpts.features_logging:
                log.ThugLogging.Features.increase_eval_count()

            try:
                log.warning("[eval] Deobfuscated argument: %s", script)
            except Exception:
                pass

            log.JSClassifier.classify(self.dump_url, script)
            log.ThugLogging.add_code_snippet(script,
                                             language='Javascript',
                                             relationship='eval argument',
                                             check=True,
                                             force=True)

        delattr(self.ctxt.locals, name)
        delattr(self.ctxt.locals, saved)

    def dump_write(self):
        name, saved = log.ThugLogging.write_symbol

        htmls = getattr(self.ctxt.locals, name, None)
        if htmls is None:
            return

        for html in htmls:
            if not isinstance(html, six.string_types):
                continue

            try:
                log.warning("[document.write] Deobfuscated argument: %s", html)
            except Exception:
                pass

            log.HTMLClassifier.classify(self.dump_url, html)
            log.ThugLogging.add_code_snippet(
                html,
                language='HTML',
                relationship='document.write argument',
                check=True,
                force=True)

        delattr(self.ctxt.locals, name)
        delattr(self.ctxt.locals, saved)

    def dump(self):
        self.dump_eval()
        self.dump_write()

    def run(self):
        with Debugger() as dbg:
            dbg._context = self.ctxt
            # dbg.debugBreak()

            try:
                result = self.ctxt.eval(self.script)
            except (UnicodeDecodeError, TypeError):
                try:
                    enc = log.Encoding.detect(self.script)
                    result = self.ctxt.eval(self.script.decode(
                        enc['encoding']))
                except Exception:
                    self.dump()
                    log.ThugLogging.log_warning(traceback.format_exc())
                    return None
            except Exception:
                self.dump()
                log.ThugLogging.log_warning(traceback.format_exc())
                return None

            self.dump()

            names = [p['name'] for p in self.ast.names]
            for name in names:
                s = getattr(self.ctxt.locals, name, None)

                if not s:
                    continue

                if not isinstance(s, six.string_types):
                    continue

                log.debug("[Shellcode] Testing variable: %s", name)
                self.emu.run(s)

                if self.emu.emu_profile_output:
                    try:
                        encoded_sc = s.encode('unicode-escape')
                    except Exception:
                        encoded_sc = "Unable to encode shellcode"

                    snippet = log.ThugLogging.add_shellcode_snippet(
                        encoded_sc, "Assembly", "Shellcode")

                    log.ThugLogging.add_behavior_warn(
                        "[Shellcode Profile] {}".format(
                            self.emu.emu_profile_output),
                        snippet=snippet,
                        method="Static Analysis")

                    self.check_URLDownloadToFile(self.emu)

                self.emu.free()
                self.search_url(s)

        return result
Beispiel #14
0
class Shellcode(object):
    emu = pylibemu.Emulator(enable_hooks = False)

    def __init__(self, window, ctxt, ast, script):
        self.window  = window
        self.script  = script
        self.ctxt    = ctxt
        self.ast     = ast
        self.offsets = set()

    def check_URLDownloadToFile(self, emu):
        profile = emu.emu_profile_output

        while True:
            offset = profile.find('URLDownloadToFile')
            if offset < 0:
                break

            profile = profile[offset:]

            p = profile.split(';')
            if len(p) < 2:
                profile = profile[1:]
                continue

            p = p[1].split('"')
            if len(p) < 3:
                profile = profile[1:]
                continue

            url = p[1]
            if url in log.ThugLogging.shellcode_urls:
                return

            try:
                self.window._navigator.fetch(p[1], redirect_type = "Found URLDownloadToFile")
                log.ThugLogging.shellcode_urls.add(url)
            except Exception:
                pass

            profile = profile[1:]

    def search_url(self, sc):
        offset = sc.find('http')

        if offset > 0:
            url = sc[offset:].split()[0]
            if url.endswith("'") or url.endswith('"'):
                url = url[:-1]

            if url in log.ThugLogging.shellcode_urls:
                return

            log.info('[Shellcode Analysis] URL Detected: %s', url)

            try:
                self.window._navigator.fetch(url, redirect_type = "URL found")
                log.ThugLogging.shellcode_urls.add(url)
            except Exception:
                pass

    def run(self):
        with Debugger() as dbg:
            dbg._context = self.ctxt
            # dbg.debugBreak()

            try:
                result = self.ctxt.eval(self.script)
            except (UnicodeDecodeError, TypeError):
                try:
                    enc = log.Encoding.detect(self.script)
                    result = self.ctxt.eval(self.script.decode(enc['encoding']))
                except Exception:
                    log.ThugLogging.log_warning(traceback.format_exc())
                    return None
            except Exception:
                log.ThugLogging.log_warning(traceback.format_exc())
                return None

            names = [p['name'] for p in self.ast.names]
            for name in names:
                s = getattr(self.ctxt.locals, name, None)

                if not s:
                    continue

                if not isinstance(s, six.string_types):
                    continue

                log.debug("[Shellcode] Testing variable: %s", name)
                self.emu.run(s)

                if self.emu.emu_profile_output:
                    try:
                        encoded_sc = s.encode('unicode-escape')
                    except Exception:
                        encoded_sc = "Unable to encode shellcode"

                    snippet = log.ThugLogging.add_shellcode_snippet(encoded_sc,
                                                                    "Assembly",
                                                                    "Shellcode")

                    log.ThugLogging.add_behavior_warn("[Shellcode Profile] {}".format(self.emu.emu_profile_output),
                                                      snippet = snippet,
                                                      method  = "Static Analysis")

                    self.check_URLDownloadToFile(self.emu)

                self.emu.free()
                self.search_url(s)

        return result
Beispiel #15
0
def inspect(proto, data, datalen, regexes, fuzzpatterns, yararuleobjects, addrkey, direction, directionflag):
    if configopts['regexengine'] == 're':
        import re
    if configopts['fuzzengine']:
        from fuzzywuzzy import fuzz
    if configopts['yaraengine']:
        import yara
    if configopts['shellcodeengine']:
        import pylibemu as emu

    skip = False
    matched = False

    ((src, sport), (dst, dport)) = addrkey

    if proto == 'TCP':
        ipct = opentcpflows[addrkey]['ipct']
        id = opentcpflows[addrkey]['id']
    elif proto == 'UDP':
        for key in openudpflows.keys():
            skey = '%s:%s' % (src, sport)
            dkey = '%s:%s' % (dst, dport)
            if skey == key:
                ipct = openudpflows[key]['ipct']
                id = openudpflows[key]['id']
                addrkey = skey
            elif dkey == key:
                ipct = openudpflows[key]['ipct']
                id = openudpflows[key]['id']
                addrkey = dkey

    if configopts['verbose'] and configopts['verboselevel'] >= 1:
        doinfo('[IP#%d.%s#%d] Received %dB for inspection from %s:%s %s %s:%s' % (
                ipct,
                proto,
                id,
                datalen,
                src,
                sport,
                directionflag,
                dst,
                dport))

    if 'regex' in configopts['inspectionmodes']:
        for regex in regexes:
            matchstats['match'] = regex.search(data)

            if direction == configopts['ctsdirectionstring']:
                regexpattern = configopts['ctsregexes'][regex]['regexpattern']
            elif direction == configopts['stcdirectionstring']:
                regexpattern = configopts['stcregexes'][regex]['regexpattern']

            if matchstats['match'] and not configopts['invertmatch']:
                matchstats['detectiontype'] = 'regex'
                matchstats['regex'] = regex
                matchstats['start'] = matchstats['match'].start()
                matchstats['end'] = matchstats['match'].end()
                matchstats['matchsize'] = matchstats['end'] - matchstats['start']
                if configopts['verbose'] and configopts['verboselevel'] >= 1:
                    doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s matches regex: \'%s\'' % (
                            ipct,
                            proto,
                            id,
                            src,
                            sport,
                            directionflag,
                            dst,
                            dport,
                            regexpattern))
                return True

            if not matchstats['match'] and configopts['invertmatch']:
                matchstats['detectiontype'] = 'regex'
                matchstats['regex'] = regex
                matchstats['start'] = 0
                matchstats['end'] = datalen
                matchstats['matchsize'] = matchstats['end'] - matchstats['start']
                if configopts['verbose'] and configopts['verboselevel'] >= 1:
                    doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s matches regex (invert): \'%s\'' % (
                            ipct,
                            proto,
                            id,
                            src,
                            sport,
                            directionflag,
                            dst,
                            dport,
                            regexpattern))
                return True

            if configopts['verbose'] and configopts['verboselevel'] >= 1:
                if configopts['invertmatch']:
                    invertstatus = " (invert)"
                else:
                    invertstatus = ""

                doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s did not match regex%s: \'%s\'' % (
                        ipct,
                        proto,
                        id,
                        src,
                        sport,
                        directionflag,
                        dst,
                        dport,
                        invertstatus,
                        regexpattern))

    if 'fuzzy' in configopts['inspectionmodes']:
        for pattern in fuzzpatterns:
            partialratio = fuzz.partial_ratio(data, pattern)

            if partialratio >= configopts['fuzzminthreshold']:
                if not configopts['invertmatch']:
                    matched = True
                    matchstr = 'matches'
                    matchreason = '>='
                else:
                    matched = False
                    matchstr = 'doesnot match'
                    matchreason = '|'
            else:
                if configopts['invertmatch']:
                    matched = True
                    matchstr = 'matches'
                    matchreason = '|'
                else:
                    matched = False
                    matchstr = 'doesnot match'
                    matchreason = '<'

            fuzzmatchdetails = "(ratio: %d %s threshold: %d)" % (partialratio, matchreason, configopts['fuzzminthreshold'])

            if configopts['verbose'] and configopts['verboselevel'] >= 1:
                doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s %s \'%s\' (ratio: %d %s threshold: %d)' % (
                        ipct,
                        proto,
                        id,
                        src,
                        sport,
                        directionflag,
                        dst,
                        dport,
                        matchstr,
                        pattern,
                        partialratio,
                        matchreason,
                        configopts['fuzzminthreshold']))

            if matched:
                matchstats['detectiontype'] = 'fuzzy'
                matchstats['fuzzpattern'] = pattern
                matchstats['start'] = 0
                matchstats['end'] = datalen
                matchstats['matchsize'] = matchstats['end'] - matchstats['start']
                matchstats['fuzzmatchdetails'] = fuzzmatchdetails
                return True

    if 'shellcode' in configopts['inspectionmodes']:
        emulator = emu.Emulator(configopts['emuprofileoutsize'])
        offset = emulator.shellcode_getpc_test(data)
        if offset < 0: offset = 0
        emulator.prepare(data, offset)
        emulator.test()

        matched = False
        invert = False
        invertstatus = ""

        if emulator.emu_profile_output: # shellcode found!
            if configopts['invertmatch']:
                matched = True
                invert = False
                invertstatus = ""
            else:
                matched = True
                invert = False
                invertstatus = ""
        else: # shellcode not found!
            if configopts['invertmatch']:
                matched = True
                invert = True
                invertstatus = " (invert)"
            else:
                matched = False
                invert = False
                invertstatus = ""

        if matched:
            emulator.free()
            matchstats['detectiontype'] = 'shellcode'
            matchstats['shellcodeoffset'] = offset
            matchstats['start'] = offset
            matchstats['end'] = datalen
            matchstats['matchsize'] = matchstats['end'] - matchstats['start']
            if configopts['verbose'] and configopts['verboselevel'] >= 1:
                doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s contains shellcode%s' % (
                        ipct,
                        proto,
                        id,
                        src,
                        sport,
                        directionflag,
                        dst,
                        dport,
                        invertstatus))

            if configopts['emuprofile'] and not invert:
                filename = '%s-%08d-%s.%s-%s.%s-%s.emuprofile' % (
                            proto,
                            id,
                            src,
                            sport,
                            dst,
                            dport,
                            direction)

                data = emulator.emu_profile_output.decode('utf8')

                if emulator.emu_profile_truncated and configopts['verbose'] and configopts['verboselevel'] >= 1:
                    doinfo('[IP#%d.%s#%d] Skipping emulator profile output generation as its truncated' % (ipct, proto, id))
                else:
                    fo = open(filename, 'w')
                    fo.write(data)
                    fo.close()
                    if configopts['verbose'] and configopts['verboselevel'] >= 1:
                        doinfo('[IP#%d.%s#%d] Wrote %d byte emulator profile output to %s' % (ipct, proto, id, len(data), filename))

            return True

        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s doesnot contain shellcode%s' % (
                            ipct,
                            proto,
                            id,
                            src,
                            sport,
                            directionflag,
                            dst,
                            dport,
                            invertstatus))

    if 'yara' in configopts['inspectionmodes']:
       for ruleobj in yararuleobjects:
            matchstats['start'] = -1
            matchstats['end'] = -1
            matchstats['yararulenamespace'] = None
            matchstats['yararulename'] = None
            matchstats['yararulemeta'] = None

            matches = ruleobj.match(data=data, callback=yaramatchcallback)

            if matches:
                if not configopts['invertmatch']: matched = True
                else: matched = False
            else:
                if configopts['invertmatch']: matched = True
                else: matched = False

            if matched:
                matchstats['detectiontype'] = 'yara'

                for rule in configopts['ctsyararules']:
                    if rule == ruleobj: matchstats['yararulefilepath'] = configopts['ctsyararules'][rule]['filepath']
                for rule in configopts['stcyararules']:
                    if rule == ruleobj: matchstats['yararulefilepath'] = configopts['stcyararules'][rule]['filepath']

                if matchstats['start'] == -1 and matchstats['end'] == -1:
                    matchstats['start'] = 0
                    matchstats['end'] = len(data)

                matchstats['matchsize'] = matchstats['end'] - matchstats['start']
                return True

            if configopts['verbose'] and configopts['verboselevel'] >= 1:
                if ruleobj in configopts['ctsyararules']:
                    filepath = configopts['ctsyararules'][ruleobj]['filepath']
                elif ruleobj in configopts['stcyararules']:
                    filepath = configopts['stcyararules'][ruleobj]['filepath']

                doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s doesnot match any rule in %s' % (
                            ipct,
                            proto,
                            id,
                            src,
                            sport,
                            directionflag,
                            dst,
                            dport,
                            filepath))

    return False