def main(filepath):
    # no need in 32 bit binaries
    if not check_32():
        lines = []

        with open(filepath + '.temp') as f:
            lines = f.readlines()

        # symbols = []

        pat_d = r'0x[0-9a-f]+\(%rip\)'
        pat_s = r'<(.*)>'

        for i in range(len(lines)):
            l = lines[i]
            if "#" in l and not "+" in l:
                m_s = re.search(pat_s, l)
                m_d = re.search(pat_d, l)
                try:
                    src = m_s.group(1) # let it crash it not
                    des = m_d.group(0) # let it crash it not
                    l = l.split('#')[0]
                    l = l.replace(des, src)
                    lines[i] = l+"\n"
                except Exception:
                    print "exception in external symbols processing of 64-bit ELF"
                    print l
        with open(filepath + '.temp', 'w') as f:
            f.writelines(lines)
def main():
    if not check_32():
        lines = []
        with open('instrs.info') as f:
            lines = f.readlines()

        for i in range(len(lines)):
            l = lines[i]
            l = l.strip()
            if 'nop' in l:
                items = l.split()
                if 'nop' == items[-1]:
                    #l = l.split(':')[0] + " :"
                    l = l
            lines[i] = l + "\n"

        with open('instrs.info', 'w') as f:
            f.writelines(lines)
def main():
    with open("final.s") as f:
        lines = f.readlines()

    is_32 = check_32()
    ll = len(lines)
    main_symbol = ""

    find_text = False

    for i in range(ll):
        l = lines[i]
        if ".text" in l:
            if find_text == False:
                find_text = True
            else:
                l = l.replace(".text:", "")
        if "lea 0x0(%esi," in l:
            if ':' in l:
                label = l.split(':')[0]  # label:  lea 0x0....
                l = label + " : nop;nop;nop;nop;nop;nop;nop;\n"
            else:
                l = "nop;nop;nop;nop;nop;nop;nop;\n"
        elif "lea 0x0(%edi," in l:
            if ':' in l:
                label = l.split(':')[0]  # label:  lea 0x0....
                l = label + " : nop;nop;nop;nop;nop;nop;nop;\n"
            else:
                label = ""
                l = "nop;nop;nop;nop;nop;nop;nop;\n"
        # __gmon_start__ symbol is resolved by the linked program itself, it surely can not be resolved
        # in our final.s code, just remove it
        elif "__gmon_start__" in l:
            l = ""
        elif "lea 0x7FFFFFFC(,%ebx,0x4),%edi" in l:
            l = l.replace('0x7FFFFFFC', '0x7FFFFFFFFFFFFFFC')
        elif "repz retq" in l:
            l = l.replace("repz retq", "repz\nretq\n")
        elif "repz ret" in l:
            l = l.replace("repz ret", "repz\nret\n")
        elif "repz pop" in l:
            l = l.replace("repz pop", "repz\npop")
        elif "movzbl $S_" in l:
            l = l.replace("movzbl $S_", "movzbl S_")
        #  Warning: indirect jmp without `*'
        # the exe crashes at this instruction
        # adjust it into jmp S_0x4006C1
        elif "jmpq " in l and "*" not in l:
            l = l.replace('jmpq ', 'jmp ')
        elif "__libc_start_main" in l and is_32 == True:
            main_symbol = lines[i - 1].split()[1]
            lines[i - 1] = lines[i - 1].replace(main_symbol, "main")
            main_symbol = main_symbol[1:].strip()
        elif is_32 == False and "__libc_start_main" in l:
            main_symbol = lines[i - 1].split()[-1].split(',')[0]
            lines[i - 1] = lines[i - 1].replace(main_symbol, "main")
            main_symbol = main_symbol[1:].strip()

        lines[i] = l
        #print main_symbol

        ## Some of the PIC code/module rely on typical pattern to locate
        ## such as:

        ##    804c460: push   %ebx
        ##    804c461: call   804c452 <__i686.get_pc_thunk.bx>
        ##    804c466: add    $0x2b8e,%ebx
        ##    804c46c: sub    $0x18,%esp

        ## What we can do this pattern match `<__i686.get_pc_thunk.bx>` and calculate
        ## the address by plusing 0x2b8e and  0x804c466, which equals to the begin address of GOT.PLT table

        ## symbols can be leveraged in re-assemble are
        ##    _GLOBAL_OFFSET_TABLE_   ==    ** .got.plt **
        ##    ....

    if check_exe():
        mains = []
        main_symbol1 = ""

        with open('main.info') as f:
            mains = f.readlines()

        main_symbol1 = mains[0].strip()

        def helpf(l):
            if main_symbol1 != "" and main_symbol1 in l:
                #main_s1 = "S"+main_symbol
                #if main_s1 in l:
                #l = l.replace(main_s1, ".globl main\nmain")
                l = ".globl main\nmain:\n" + l
            #else:
            #l = l.replace(main_symbol, ".globl main\nmain")
            #    l = ".globl main\nmain:\n"+l
            return l

        #print lines
        lines = map(helpf, lines)

    #branch_routine :pop global_des
    #jmp *branch_des
    #lines.append('switch_bb: jmp *branch_des\n')

    with open("final.s", 'w') as f:
        f.writelines(lines)

    if os.path.isfile('inline_symbols.txt'):
        inline_update.main()
def reassemble(saveerr=False):
    os.system('gcc final.s -lm -lrt -lpthread -lcrypt' +
              (' -m32' if check_32() else '') +
              (' 2> final.error' if saveerr else ''))
def post_process_data():

    if not check_32():
        # for 64-bit binaries, remember to align data sections with 16.
        if check_exe():
            with open("final_data.s") as f:
                lines = f.readlines()
            ll = len(lines)

            for i in range(ll - 1):
                l = lines[i]
                if ".data" in l or ".bss" in l or ".rodata" in l:
                    ln = lines[i + 1]
                    if "align" not in ln:
                        # add the align macro
                        lines[i + 1] = ".align 16\n" + ln
            with open('final_data.s', 'w') as f:
                f.writelines(lines)
    else:
        if check_exe():
            with open("final_data.s") as f:
                lines = f.readlines()

            ll = len(lines)
            in_rodata = False
            in_data = False

            #if ".section .rodata" in l:
            #    for j in range(i+1, i+10):
            #          lines[j] = ""
            #if ".section .data" in l:
            #    for j in range(i+1, i+10):
            #          lines[j] = ""

            # this variable is used by basic block flattern diverisfy

            #        lines[i+1] = "global_des:\n"
            #        lines[i+2] = ".byte 0x00\n"
            #        lines[i+3] = ".byte 0x00\n"
            #        lines[i+4] = ".byte 0x00\n"
            #        lines[i+5] = ".byte 0x00\n"
            #        lines[i+6] = "branch_des:\n"
            #        lines[i+7] = ".byte 0x00\n"
            #        lines[i+8] = ".byte 0x00\n"
            #        lines[i+9] = ".byte 0x00\n"
            #        lines[i+10] = ".byte 0x00\n"

            for i in range(ll):
                l = lines[i]
                if in_data == False and ".data" in l:
                    in_data = True
                    #lines[i+2] = ""
                    #lines[i+3] = ""
                    #lines[i+4] = ""
                    #lines[i+5] = ""
                    #lines[i+6] = ""
                    #lines[i+7] = ""
                    #lines[i+8] = ""
                    #lines[i+9] = ""
            # this variable is used by basic block flattern diversify
            # please comment these lines if no bb flattern diversifying used
            #        lines[i+1] = "global_des:\n"
            #        lines[i+2] = ".byte 0x00\n"
            #        lines[i+3] = ".byte 0x00\n"
            #        lines[i+4] = ".byte 0x00\n"
            #        lines[i+5] = ".byte 0x00\n"
            #        lines[i+6] = "branch_des:\n.byte 0x00\n"
            #        lines[i+7] = ".byte 0x00\n"
            #        lines[i+8] = ".byte 0x00\n"
            #        lines[i+9] = ".byte 0x00\n"

                elif in_rodata == False and ".rodata" in l:
                    # add two instructions
                    # branch_routine :pop global_des
                    # jmp *branch_des
                    in_rodata = True
                    #lines[i+2] = ""
                    #lines[i+3] = ""
                    #lines[i+4] = ""
                    #lines[i+5] = ""
                    #lines[i+6] = ""
                    #lines[i+7] = ""
                    #lines[i+8] = ""
                    #lines[i+9] = ""
                    #lines[i+10] = ""
                elif ".bss" in l:
                    #for j in range(i+2,i+44+2):
                    #    lines[j] = ""
                    break

            with open('final_data.s', 'w') as f:
                f.writelines(lines)
Esempio n. 6
0
 def __init__(self, filepath):
     self.file = filepath
     self.is_32 = check_32()