Esempio n. 1
0
def main(filepath):
    if check_strip() and check_exe():
        clear_code()
        init = Init(filepath)
        init.disassemble()
        init.process()
        init.ailProcess()
    else:
        sys.stderr.write(
            'Error: binary is not stripped or is a shared library\n')
def main():
    if not check_exe():
        with open('final.s') as f:
            contents = f.readlines()

        task1()
        task2()
        contents = task3_4()
        # task5()

        # write back
        with open('final.s', 'w') as f:
            f.writelines(contents)
Esempio n. 3
0
def main(filepath, is_32):
    global step
    step = 1
    if is_32:
        if check_exe():  # executable
            t = text_process_strip(filepath)
            while t == False:
                t = text_process_strip(filepath)
        else:
            # shared object don't translate target addrs into
            # GLOBAL_OFFSET_TABLE, instead, dump the thunk addr for
            # analysis in share_lib_helper.ml
            addr = thunk_identify(filepath).strip()
            with open('pic_thunk.info', 'w') as f:
                f.write(addr + '\n')
Esempio n. 4
0
def check(filepath, assumptions):
    if not assumptions: assumptions = []

    if not os.path.isfile(filepath):
        print "cannot find input binary"
        return False

    if os.path.dirname(filepath) != os.getcwd():
        shutil.copy(filepath, '.')

    os.system('file ' + filepath + ' > elf.info')
    if not check_exe():
        print "Uroboros doesn't support shared library"
        return False

    # if assumption three is utilized, then input binary must be unstripped.
    if '3' in assumptions and not check_strip():
        print 'Uroboros does not support stripped binaries when using assumption three'
        return False

    return True
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 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)