Advertisement
opexxx

peid_to_yara.py

May 5th, 2014
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.50 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. #
  4. # Tested on Linux (Ubuntu), Windows XP/7, and Mac OS X
  5. #
  6. """
  7. untitled.py
  8.  
  9. Created by Matthew Richard on 2010-03-12.
  10. Copyright (c) 2010. All rights reserved.
  11. """
  12.  
  13. import sys
  14. import os
  15. import re
  16. from optparse import OptionParser
  17.  
  18. def main():
  19.     parser = OptionParser()
  20.     parser.add_option("-f", "--file", action="store", dest="filename",
  21.                  type="string", help="scanned FILENAME")
  22.     parser.add_option("-o", "--output-file", action="store", dest="outfile",
  23.             type="string", help="output filename")
  24.     parser.add_option("-v", "--verbose", action="store_true", default=False,
  25.                     dest="verbose", help="verbose")
  26.     parser.add_option("-n", "--no-ep", action="store_true", default=False,
  27.                     dest="no_ep", help="no entry point restriction")
  28.  
  29.     (opts, args) = parser.parse_args()
  30.  
  31.     if opts.filename == None:
  32.         parser.print_help()
  33.         parser.error("You must supply a filename!")
  34.     if not os.path.isfile(opts.filename):
  35.         parser.error("%s does not exist" % opts.filename)
  36.        
  37.     if opts.outfile == None:
  38.         parser.print_help()
  39.         parser.error("You must specify an output filename!")
  40.        
  41.     # yara rule template from which rules will be created
  42.     yara_rule = """
  43. rule %s
  44. {
  45. strings:
  46.     %s
  47. condition:
  48.     %s
  49. }
  50.    
  51.     """
  52.     rules = {}
  53.    
  54.     # read the PEiD signature file as the first argument
  55.     data = open(opts.filename, 'rb').read()
  56.  
  57.     # every signature takes the form of
  58.     # [signature_name]
  59.     # signature = hex signature
  60.     # ep_only = (true|false)
  61.     signature = re.compile('\[(.+?)\]\r\nsignature = (.+?)\r\nep_only = (.+?)\r\n', re.M|re.S)
  62.    
  63.     matches = signature.findall(data)
  64.     if opts.verbose:
  65.         print "Found %d signatures in PEiD input file" % len(matches)
  66.     for match in matches:
  67.  
  68.         # yara rules can only contain alphanumeric + _
  69.         rulename_regex = re.compile('(\W)')
  70.         rulename = rulename_regex.sub('', match[0])
  71.  
  72.         # and cannot start with a number
  73.         rulename_regex = re.compile('(^[0-9]{1,})')
  74.         rulename = rulename_regex.sub('', rulename)
  75.  
  76.         # if the rule doesn't exist, create a dict entry
  77.         if rulename not in rules:
  78.             rules[rulename] = []
  79.        
  80.         signature = match[1]
  81.  
  82.         # add the rule to the list
  83.         rules[rulename].append((signature, match[2]))
  84.  
  85.     output = ''
  86.    
  87.     for rule in rules.keys():
  88.         detects = ''
  89.         mod_ep = False
  90.         conds = '\t'
  91.         x = 0
  92.         for (detect, ep) in rules[rule]:
  93.             # check for rules that start with wildcards
  94.             # this is not allowed in yara, nor is it particularly useful
  95.             # though it does goof up signatures that need a few wildcards
  96.             # at EP
  97.             while detect[:3] == '?? ':
  98.                 detect = detect[3:]
  99.                 if opts.no_ep == True:
  100.                     if opts.verbose:
  101.                         print "\t\tSince you said no_ep, I'll skip the ep."
  102.                     mod_ep == True
  103.                 if opts.verbose:
  104.                     print "\tTrimming %s due to wildcard at start" % rule
  105.             # create each new rule using a unique numeric value
  106.             # to allow for multiple criteria and no collisions
  107.             detects += "\t$a%d = { %s }\r\n" % (x, detect)
  108.  
  109.             if x > 0:
  110.                 conds += " or "
  111.            
  112.             # if the rule specifies it should be at EP we add
  113.             # the yara specifier 'at entrypoint'
  114.             if ep == 'true' and mod_ep == False:
  115.                 conds += "$a%d at entrypoint" % x
  116.             else:
  117.                 conds += "$a%d" % x
  118.             x += 1
  119.  
  120.         # add the rule to the output
  121.         output += yara_rule % (rule, detects, conds)
  122.  
  123.     # could be written to an output file
  124.     fout = open(opts.outfile, 'wb')
  125.     fout.write(output)
  126.     fout.close()
  127.     if opts.verbose:
  128.         print "Wrote %d rules to %s" % (len(rules), opts.outfile)
  129.  
  130. if __name__ == '__main__':
  131.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement