<reponame>YuriyTheDrafter/Malware-analysis<filename>Python/vb_macro_checker.py<gh_stars>0
import  os,re,sys,hashlib,heapq,codecs,platform 
#os

#define user info function
def UserInfo():
    print('---------------------------- Macro checker -------------------------------')
    print('required 3 arguments: <type of work> <olevba log/macro file> <hashes file>')
    print('')
    print('Where:')
    print('1) types of work:')
    print('                 -c check file')
    print('                 -a appdate hash file')
    print('')
    print('! After each update of the hash file, a corresponding entry is created   !')
    print('! in the macro_md5.txt                                                   !')
    print('--------------------------------------------------------------------------')

#define types of work
workType = ['-c','-a']

#check argv sequence
if len(sys.argv) != 4:
    UserInfo()
    exit()
else:
    if  (sys.argv[1] in workType) and (os.path.isfile(sys.argv[2]) and os.path.isfile(sys.argv[3])) == False:
        UserInfo()
        exit()

#type of work:
work = sys.argv[1]

#open log file for reading
 
olevbaLog = open(sys.argv[2],'rb')

#open hashes file for reading
md5Hashes = open(sys.argv[3],'rb')




#read olevba log lines 
_olevbaLog = ['']
for line in olevbaLog: 
    if line != '\n':
        _olevbaLog.append(line)

#close olevba log
olevbaLog.close()

#compile regexp for Functions and Subs 
regex = re.compile('(Function\s+.+?\s*End\s*Function)|(Sub\s+.+?\s*End\s*Sub)',re.IGNORECASE | re.DOTALL)# (Function\s+(.|\s)+?\s*End\s*Function)|(Sub\s+(.|\s)+?\s*End\s*Sub)    
#find all matches in olevba log lines
matches = regex.finditer(''.join(_olevbaLog))

 

#clear olevba log lines
_olevbaLog = None

#read md5 hashes file
checkList = [line[:-1] for line in md5Hashes]

#define resulted macro&md5   
if(platform.system() == 'Windows'):
    macro_md5_path = '\\'.join(os.path.abspath(sys.argv[3]).split('\\')[0:-1])+"\\" +"macro_md5.txt"
if(platform.system() == 'Linux'):
    macro_md5_path = '/'.join(os.path.abspath(sys.argv[3]).split('/')[0:-1])+"/" +"macro_md5.txt"

 

#close md5 hashes file
md5Hashes.close()

#processing "matches" step by step; in each step forming result
result = ''

#work -c (check macro)
if work == '-c':
    state = ["CLEAN","UNKNOWN"]

    for match in matches:
        #get result from match
        result = match.group()

        #calculate md5 hash
        
        _hash  = hashlib.md5(result).hexdigest()
        
        #print result
        if _hash in checkList:
            print("------------------------ " + state[0] + " ------------------------")
        else:
            print("----------------------- " + state[1] + " -----------------------")
        
        print (result)
        print("---------- "+ _hash + " -----------")
        print("")
        
#work -a (add macro) 
if work == '-a':
    state = ["SKIPPED","ADDED"]
    md5Hashes = codecs.open(sys.argv[3],'wb')
    macro_md5 = codecs.open(macro_md5_path,'ab')
    for match in matches:
        #get result from match
        result = match.group()
        #calculate md5 hash
        _hash  = hashlib.md5(result).hexdigest()
        
        #print resultssssss
        if _hash in checkList:
            #macro_md5.write("----------------------- " + state[0] + " -----------------------\n")
            print("----------------------- " + state[0] + " -----------------------")
            #macro_md5.write(result)
            print (result)
            #macro_md5.write("\n---------- "+ _hash + " -----------\n\n\n")
            print("---------- "+ _hash + " -----------\n")
        else:
            macro_md5.write("------------------------ " + state[1] + " ------------------------\n")
            print("------------------------ " + state[1] + " ------------------------")
            checkList.append(_hash)
            macro_md5.write(result)
            print (result)
            macro_md5.write("\n---------- "+ _hash + " -----------\n\n\n")
            print("---------- "+ _hash + " -----------\n")

    #update md5 hashes
    macro_md5.close()
    checkList = [line + "\n" for line in checkList]
    md5Hashes.writelines(checkList)

#clean up
md5Hashes.close()
matches   = None
result    = None
checkList = None

import  os,re,sys,hashlib,heapq,codecs,platform 
#os

#define user info function
def UserInfo():
    print('---------------------------- Macro checker -------------------------------')
    print('required 3 arguments: <type of work> <olevba log/macro file> <hashes file>')
    print('')
    print('Where:')
    print('1) types of work:')
    print('                 -c check file')
    print('                 -a appdate hash file')
    print('')
    print('! After each update of the hash file, a corresponding entry is created   !')
    print('! in the macro_md5.txt                                                   !')
    print('--------------------------------------------------------------------------')

#define types of work
workType = ['-c','-a']

#check argv sequence
if len(sys.argv) != 4:
    UserInfo()
    exit()
else:
    if  (sys.argv[1] in workType) and (os.path.isfile(sys.argv[2]) and os.path.isfile(sys.argv[3])) == False:
        UserInfo()
        exit()

#type of work:
work = sys.argv[1]

#open log file for reading
 
olevbaLog = open(sys.argv[2],'rb')

#open hashes file for reading
md5Hashes = open(sys.argv[3],'rb')




#read olevba log lines 
_olevbaLog = ['']
for line in olevbaLog: 
    if line != '\n':
        _olevbaLog.append(line)

#close olevba log
olevbaLog.close()

#compile regexp for Functions and Subs 
regex = re.compile('(Function\s+.+?\s*End\s*Function)|(Sub\s+.+?\s*End\s*Sub)',re.IGNORECASE | re.DOTALL)# (Function\s+(.|\s)+?\s*End\s*Function)|(Sub\s+(.|\s)+?\s*End\s*Sub)    
#find all matches in olevba log lines
matches = regex.finditer(''.join(_olevbaLog))

 

#clear olevba log lines
_olevbaLog = None

#read md5 hashes file
checkList = [line[:-1] for line in md5Hashes]

#define resulted macro&md5   
if(platform.system() == 'Windows'):
    macro_md5_path = '\\'.join(os.path.abspath(sys.argv[3]).split('\\')[0:-1])+"\\" +"macro_md5.txt"
if(platform.system() == 'Linux'):
    macro_md5_path = '/'.join(os.path.abspath(sys.argv[3]).split('/')[0:-1])+"/" +"macro_md5.txt"

 

#close md5 hashes file
md5Hashes.close()

#processing "matches" step by step; in each step forming result
result = ''

#work -c (check macro)
if work == '-c':
    state = ["CLEAN","UNKNOWN"]

    for match in matches:
        #get result from match
        result = match.group()

        #calculate md5 hash
        
        _hash  = hashlib.md5(result).hexdigest()
        
        #print result
        if _hash in checkList:
            print("------------------------ " + state[0] + " ------------------------")
        else:
            print("----------------------- " + state[1] + " -----------------------")
        
        print (result)
        print("---------- "+ _hash + " -----------")
        print("")
        
#work -a (add macro) 
if work == '-a':
    state = ["SKIPPED","ADDED"]
    md5Hashes = codecs.open(sys.argv[3],'wb')
    macro_md5 = codecs.open(macro_md5_path,'ab')
    for match in matches:
        #get result from match
        result = match.group()
        #calculate md5 hash
        _hash  = hashlib.md5(result).hexdigest()
        
        #print resultssssss
        if _hash in checkList:
            #macro_md5.write("----------------------- " + state[0] + " -----------------------\n")
            print("----------------------- " + state[0] + " -----------------------")
            #macro_md5.write(result)
            print (result)
            #macro_md5.write("\n---------- "+ _hash + " -----------\n\n\n")
            print("---------- "+ _hash + " -----------\n")
        else:
            macro_md5.write("------------------------ " + state[1] + " ------------------------\n")
            print("------------------------ " + state[1] + " ------------------------")
            checkList.append(_hash)
            macro_md5.write(result)
            print (result)
            macro_md5.write("\n---------- "+ _hash + " -----------\n\n\n")
            print("---------- "+ _hash + " -----------\n")

    #update md5 hashes
    macro_md5.close()
    checkList = [line + "\n" for line in checkList]
    md5Hashes.writelines(checkList)

#clean up
md5Hashes.close()
matches   = None
result    = None
checkList = None
#os #define user info function #define types of work #check argv sequence #type of work: #open log file for reading #open hashes file for reading #read olevba log lines #close olevba log #compile regexp for Functions and Subs # (Function\s+(.|\s)+?\s*End\s*Function)|(Sub\s+(.|\s)+?\s*End\s*Sub) #find all matches in olevba log lines #clear olevba log lines #read md5 hashes file #define resulted macro&md5 #close md5 hashes file #processing "matches" step by step; in each step forming result #work -c (check macro) #get result from match #calculate md5 hash #print result #work -a (add macro) #get result from match #calculate md5 hash #print resultssssss #macro_md5.write("----------------------- " + state[0] + " -----------------------\n") #macro_md5.write(result) #macro_md5.write("\n---------- "+ _hash + " -----------\n\n\n") #update md5 hashes #clean up