Created
November 12, 2017 17:47
-
-
Save DiabloHorn/79d12b5541c862416018743692d1a076 to your computer and use it in GitHub Desktop.
Split file while preserving PE format
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# DiabloHorn https://diablohorn.com | |
# blank out bytes taking into account the PE file format | |
# input file: base64 malware.exe | rev > enc.txt | |
import sys | |
import os | |
#pip install pefile | |
import pefile | |
import argparse | |
import logging | |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
class PeModifier: | |
def __init__(self, bindata, outputpath): | |
self.bindata = bindata | |
self.opath = outputpath | |
self.pe = pefile.PE(data=self.bindata) | |
self.filename = 'split.{}.exe' | |
self.namecounter = -1 | |
def genName(self): | |
self.namecounter +=1 | |
return self.filename.format(self.namecounter) | |
def writePE(self): | |
finalpath = os.path.join(self.opath, self.genName()) | |
logging.info("File written {}".format(finalpath)) | |
self.pe.write(finalpath) | |
def getSection(self, sectionname): | |
for section in self.pe.sections: | |
if sectionname in section.Name: | |
return section.get_data() | |
def writeSection(self, sectionname, bindata): | |
for section in self.pe.sections: | |
if sectionname in section.Name: | |
section_file_offset = section.PointerToRawData | |
self.pe.set_bytes_at_offset(section_file_offset, bindata) | |
def blankSectionData(self): | |
for section in self.pe.sections: | |
logging.info("blanking secion {}".format(section.Name)) | |
bindata = self.getSection(section.Name) | |
bindatalen = len(bindata) | |
self.writeSection(section.Name,'\x00'*bindatalen) | |
self.writePE() | |
#restores in memory pe file to original state | |
self.writeSection(section.Name,bindata) | |
def blankSectionDataBytes(self, sectionname, blanklen): | |
bindata = self.getSection(sectionname) | |
bindatalen = len(bindata) | |
logging.info("blanking byte in {}".format(sectionname)) | |
for i in range(0,bindatalen,blanklen): | |
moddata = bindata[0:i] | |
moddata += ('\x00' * (bindatalen - i)) | |
self.writeSection(sectionname,moddata) | |
self.writePE() | |
#restores in memory pe file to original state | |
self.writeSection(sectionname,bindata) | |
moddata = '' | |
self.writeSection(sectionname,bindata) | |
def enc2bin(filepath): | |
memfile = "" | |
with open(filepath,'rb') as encfile: | |
for line in encfile: | |
memfile += line.strip()[::-1] | |
return memfile.decode('base64') | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser(description='split file in a PE aware manner') | |
parser.add_argument('targetfile',type=str,help='target file to split') | |
parser.add_argument('outputfolder',type=str,help='output folder for splitted files') | |
parser.add_argument('--bytes',type=int,help='amount of bytes to blank') | |
parser.add_argument('--section',type=str,help='section to blank bytes') | |
myargs = parser.parse_args() | |
if myargs.bytes is None: | |
myargs.bytes = 1000 | |
if myargs.section is None: | |
myargs.section = '.text' | |
bindata = enc2bin(myargs.targetfile) | |
logging.info("Creating in memory binary data") | |
pemod = PeModifier(bindata,myargs.outputfolder) | |
logging.info("Blanking sections") | |
pemod.blankSectionData() | |
logging.info("Blanking bytes in section") | |
pemod.blankSectionDataBytes(myargs.section,blanklen=myargs.bytes) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment