├── .gitignore ├── README.txt ├── goodimps.db └── imphash-gen.py /.gitignore: -------------------------------------------------------------------------------- 1 | goodimps - Copy.db -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | # 2 | # IMPHash Generator 3 | # by Florian Roth 4 | # February 2014 5 | # 6 | 7 | This tool generates "PE import hashes" for all executables it finds in the given 8 | directory and marks every import hash as unusable that can also be found in the 9 | goodware-hash-database. 10 | 11 | The goodware hash database contains hash values from: 12 | - Windows 7 64bit system folder 13 | - Cygwin 32 bit 14 | - Office 2012 15 | - Python 2.7 16 | 17 | Typical use cases: 18 | ================================================================================ 19 | 20 | Scan a directory and generate the PE import hashes for all executables in this 21 | directory 22 | 23 | python imphash-gen.py -p X:\MAL\Virus1 24 | 25 | Generate a goodware hash database from my Windows directory: 26 | 27 | python imphash-gen.py --createdb -r -p C:\Windows 28 | 29 | Update the goodware hash database with PE import hashes generated from 30 | executables from the programs folder. 31 | 32 | python imphash-gen.py --updatedb -r -p "C:\Program Files" -------------------------------------------------------------------------------- /goodimps.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo23x0/ImpHash-Generator/62180beb7b2a4037ee9f3344c50f9082219884c6/goodimps.db -------------------------------------------------------------------------------- /imphash-gen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: iso-8859-1 -*- 3 | # -*- coding: utf-8 -*- 4 | # 5 | # ImpHash Generator 6 | # A Simple PE Import Hash Generator 7 | # 8 | # Florian Roth 9 | # February 2014 10 | # v0.1 11 | 12 | import os 13 | import sys 14 | import argparse 15 | import traceback 16 | import pefile 17 | import pickle 18 | import gzip 19 | from collections import Counter 20 | from hashlib import md5 21 | 22 | sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) 23 | 24 | def getFiles(dir, recursive): 25 | # Recursive 26 | if recursive: 27 | for root, directories, files in os.walk(dir, followlinks=False): 28 | for filename in files: 29 | filePath = os.path.join(root, filename) 30 | yield filePath 31 | # Non recursive 32 | else: 33 | for filename in os.listdir(dir): 34 | filePath = os.path.join(dir, filename) 35 | yield filePath 36 | 37 | 38 | def createGoodImps(dir, recursive=False): 39 | imps = [] 40 | for filePath in getFiles(dir, recursive): 41 | # print filePath 42 | try: 43 | if args.debug: 44 | print "Processing %s ..." % filePath 45 | p = pefile.PE(filePath) 46 | imphash = p.get_imphash() 47 | 48 | imps.append(imphash) 49 | sys.stdout.write(".") 50 | 51 | except Exception, e: 52 | # traceback.print_exc() 53 | pass 54 | 55 | return imps 56 | 57 | 58 | def getMd5(filePath): 59 | md5sum = "-" 60 | try: 61 | f = open(filePath, 'rb') 62 | filedata = f.read() 63 | f.close() 64 | # Generate md5 65 | md5sum = md5(filedata).hexdigest() 66 | return md5sum 67 | except Exception, e: 68 | print traceback.print_exc() 69 | return "-" 70 | pass 71 | return md5sum 72 | 73 | 74 | def parseDir(dir, goodimps, recursive): 75 | imps = {} 76 | implist = [] 77 | 78 | for filePath in getFiles(dir, recursive): 79 | # print filePath 80 | try: 81 | p = pefile.PE(filePath) 82 | imphash = p.get_imphash() 83 | 84 | print "%s %s" % (imphash, filePath) 85 | 86 | if imphash in goodimps: 87 | print "GOOD IMPS - do not use -------------------------------------------" 88 | 89 | # If already known 90 | if imphash in implist: 91 | # Check for imphash in list 92 | for file in imps: 93 | # print imps[file]," ",imphash 94 | if imps[file] == imphash: 95 | print " MATCH with FILE: %s" % (md5, file) 96 | else: 97 | # Add to list 98 | # print "add" 99 | implist.append(imphash) 100 | # print implist 101 | 102 | imps[imphash].append(file) 103 | 104 | except Exception, e: 105 | # traceback.print_exc() 106 | pass 107 | 108 | 109 | def save(object, filename, protocol=0): 110 | file = gzip.GzipFile(filename, 'wb') 111 | file.write(pickle.dumps(object, protocol)) 112 | file.close() 113 | 114 | 115 | def load(filename): 116 | file = gzip.GzipFile(filename, 'rb') 117 | buffer = "" 118 | while 1: 119 | data = file.read() 120 | if data == "": 121 | break 122 | buffer += data 123 | object = pickle.loads(buffer) 124 | del (buffer) 125 | file.close() 126 | return object 127 | 128 | 129 | def isAscii(b): 130 | if ord(b) < 127 and ord(b) > 31: 131 | return 1 132 | return 0 133 | 134 | 135 | def get_abs_path(filename): 136 | return os.path.join(os.path.dirname(os.path.abspath(__file__)), filename) 137 | 138 | 139 | def printWelcome(): 140 | print "###############################################################################" 141 | print " " 142 | print " IMPHASH Generator" 143 | print " by Florian Roth" 144 | print " July 2017" 145 | print " Version 0.7.0" 146 | print " " 147 | print "###############################################################################" 148 | 149 | 150 | # MAIN ################################################################ 151 | if __name__ == '__main__': 152 | 153 | # Parse Arguments 154 | parser = argparse.ArgumentParser(description='ImpHash Generator') 155 | parser.add_argument('-p', help='Path to scan', metavar='path-to-scan', required=True) 156 | parser.add_argument('-d', help='Imphash Database File (default: goodimps.db)', metavar='dbfile', 157 | default="goodimps.db") 158 | parser.add_argument('-r', action='store_true', default=False, help='recursive scan') 159 | parser.add_argument('--createdb', action='store_true', default=False, help='Create good imphashes database') 160 | parser.add_argument('--updatedb', action='store_true', default=False, help='Update good imphashes database') 161 | parser.add_argument('--debug', action='store_true', default=False, help='Debug output') 162 | 163 | args = parser.parse_args() 164 | 165 | # Print Welcome 166 | printWelcome() 167 | 168 | # Create DB with good imphashes 169 | if args.createdb and args.p: 170 | print "Checking %s" % args.p 171 | imps = createGoodImps(args.p, args.r) 172 | print "New DB item count: %s" % str(len(imps)) 173 | save(imps, args.d) 174 | 175 | # Update DB with good imphashes 176 | if args.updatedb and args.p: 177 | good_imps_db = Counter() 178 | good_imps = load(get_abs_path(args.d)) 179 | good_imps_db.update(good_imps) 180 | 181 | print "Old DB item count: %s" % str(len(good_imps)) 182 | 183 | new_imps = createGoodImps(args.p, args.r) 184 | new_imps = good_imps + new_imps 185 | 186 | save(new_imps, args.d) 187 | print "New DB item count: %s" % str(len(new_imps)) 188 | 189 | # Create useful Import hashes 190 | else: 191 | # Read Good Imps 192 | good_imps_db = Counter() 193 | good_imps = load(get_abs_path(args.d)) 194 | good_imps_db.update(good_imps) 195 | 196 | print "Reading DB: %s imphashes found" % str(len(good_imps)) 197 | 198 | # Parse Directory 199 | parseDir(args.p, good_imps, args.r) 200 | --------------------------------------------------------------------------------