Advertisement
opexxx

exe_pe_xor.py

Sep 5th, 2014
306
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.43 KB | None | 0 0
  1.  
  2. ## detects single byte xor encoding by searching for the
  3. ## encoded MZ, lfanew and PE, then XORs the data and
  4. ## uses pefile to extract the decoded executable.
  5. ## written quickly/poorly by alexander hanel
  6.  
  7. import sys
  8. import struct
  9. import pefile
  10. import re
  11. from StringIO import StringIO
  12.  
  13. def get_xor():
  14.     # read file into a bytearray
  15.     byte = bytearray(open(sys.argv[1], 'rb').read())
  16.  
  17.     # for each byte in the file stream, excluding the last 256 bytes
  18.     for i in range(0, len(byte) - 256):
  19.             # KEY ^ VALUE ^ KEY = VALUE; Simple way to get the key
  20.             key = byte[i] ^ ord('M')
  21.             # verify the two bytes contain 'M' & 'Z'
  22.             if chr(byte[i] ^ key) == 'M' and  chr(byte[i+1] ^ key) == 'Z':
  23.                     # skip non-XOR encoded MZ
  24.                     if key == 0:
  25.                             continue
  26.                     # read four bytes into temp, offset to PE aka lfanew
  27.                     temp = byte[(i + 0x3c) : (i + 0x3c + 4)]
  28.                     # decode values with key
  29.                     lfanew = []
  30.                     for x in temp:
  31.                             lfanew.append( x ^ key)
  32.                     # convert from bytearray to int value, probably a better way to do this
  33.                     pe_offset  = struct.unpack( '<i', str(bytearray(lfanew)))[0]
  34.                      # verify results are not negative or read is bigger than file
  35.                     if pe_offset < 0 or pe_offset > len(byte):
  36.                             continue
  37.                     # verify the two decoded bytes are 'P' & 'E'
  38.                     if byte[pe_offset + i ] ^ key == ord('P') and byte[pe_offset + 1 + i] ^ key == ord('E'):
  39.                             print " * Encoded PE Found, Key 0x%x, Offset 0x%x" % (key, i)
  40.                             return (key, i)
  41.     return (None, None)
  42.  
  43. def getExt(pe):
  44.         if pe.is_dll() == True:
  45.             return 'dll'
  46.         if pe.is_driver() == True:
  47.             return 'sys'
  48.         if pe.is_exe() == True:
  49.             return 'exe'
  50.         else:
  51.             return 'bin'
  52.            
  53. def writeFile(count, ext, pe):
  54.         try:
  55.             out  = open(str(count)+ '.' + ext, 'wb')
  56.         except:
  57.             print '\t[FILE ERROR] could not write file'
  58.             sys.exit()
  59.         # remove overlay or junk in the trunk
  60.         out.write(pe.trim())
  61.         out.close()
  62.                        
  63. def xor_data(key, offset):
  64.         byte = bytearray(open(sys.argv[1], 'rb').read())
  65.         temp = ''
  66.         for x in byte:
  67.             temp += chr(x ^ key)
  68.         return temp
  69.        
  70. def carve(fileH):
  71.         if type(fileH) is str:
  72.             fileH = StringIO(fileH)
  73.         c = 1
  74.         # For each address that contains MZ
  75.         for y in [tmp.start() for tmp in re.finditer('\x4d\x5a', fileH.read())]:
  76.             fileH.seek(y)
  77.             try:
  78.                 pe = pefile.PE(data=fileH.read())
  79.             except:
  80.                 continue
  81.             # determine file ext
  82.             ext = getExt(pe)
  83.             print ' *', ext , 'found at offset', hex(y)
  84.             writeFile(c,ext,pe)
  85.             c += 1
  86.             ext = ''
  87.             fileH.seek(0)
  88.             pe.close
  89.  
  90. def run():
  91.     if len(sys.argv) < 2:
  92.         print "Usage: ex_pe_xor.py <xored_data>"
  93.         return
  94.     key, offset = get_xor()
  95.     if key == None:
  96.         return
  97.     data = xor_data(key, offset)
  98.     carve(data)
  99.    
  100. run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement