Ejemplo n.º 1
0
def main(instrument=False):
    """
    Transform malformed code and add main symbol
    :param instrument: True to insert instrumentation code
    """

    with open("final.s") as f:
        lines = f.readlines()

    if ELF_utils.elf_exe():
        main_symbol1 = ''

        with open('main.info') as f:
            main_symbol1 = f.readline().strip()

        if main_symbol1 != '':

            def helpf(l):
                if '__gmon_start__' in l:
                    l = ''
                elif 'lea 0x7FFFFFFC(,%ebx,0x4),%edi' in l:
                    l = l.replace('0x7FFFFFFC', '0x7FFFFFFFFFFFFFFC')
                elif 'movzbl $S_' in l:
                    l = l.replace('movzbl $S_', 'movzbl S_')
                elif 'jmpq ' in l and '*' not in l:
                    l = l.replace('jmpq ', 'jmp ')
                elif 'repz retq' in l:
                    # to solve the error of 'expecting string instruction after `repz'
                    l = l.replace('repz retq', 'retq')
                elif 'repz ret' in l:
                    l = l.replace('repz ret', 'ret')
                elif 'nop' in l:
                    l = l.replace('nop', ' ')
                if main_symbol1 + ' :' in l:
                    rep = '.globl main\nmain : '
                    if instrument:
                        rep += '\n'.join(
                            map(lambda e: e['plain'].beforemain,
                                config.instrumentors)) + '\n'
                    l = l.replace(main_symbol1 + ' : ', rep)
                elif main_symbol1 in l:
                    l = l.replace(main_symbol1, 'main')
                return l

            lines = map(helpf, lines)

    with open("final.s", 'w') as f:
        f.writelines(lines)
        if instrument:
            f.write('\n'.join(
                map(lambda e: e['plain'].aftercode, config.instrumentors)) +
                    '\n')

    if os.path.isfile('inline_symbols.txt'):
        inline_update.main()
Ejemplo n.º 2
0
def picprocess32(filepath):
    """
    PC relative operation in x86 32 bit code such as:
     call   804c452 <__x86.get_pc_thunk.bx>
     add    $0x2b8e,%ebx
     mov    $0x10, (%ebx)
    This operation usually loads into %ebx the address of the _GLOBAL_OFFSET_TABLE_
    Further adjustments are operated in the analysis phase
    :param filepath: path to target executable
    """
    if ELF_utils.elf_32() and ELF_utils.elf_exe() and not ELF_utils.elf_arm():
        text_process_strip(filepath)
Ejemplo n.º 3
0
def main(filepath, instrument=False):
    """
    Init processing
    :param filepath: path to executable
    :param instrument: True to apply instrumentation
    """
    if ELF_utils.elf_strip() and ELF_utils.elf_exe():
        init = Init(filepath)
        init.disassemble()
        init.process()
        init.ailProcess(instrument)
    else:
        sys.stderr.write(
            'Error: binary is not stripped or is a shared library\n')
Ejemplo n.º 4
0
def main_discover(filename):
    """
    Find main function address and store it to file
    :param filename: path to target executable
    """
    os.system('file ' + filename + ' > elf.info')
    if ELF_utils.elf_exe():

        os.system(config.objdump + ' -Dr -j .text ' + filename + ' > ' +
                  filename + '.temp')

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

        ll = len(lines)
        main_symbol = ""

        if config.arch == config.ARCH_X86:
            for i in xrange(ll):
                l = lines[i]
                # when not using O2 to compile the original binary, we will remove all the _start code,
                # including the routine attached on the original program. In that case, we can not discover the
                # main function
                if "<__libc_start_main@plt>" in l:
                    main_symbol = lines[i-1].split()[-1] if ELF_utils.elf_32() \
                        else lines[i-1].split()[-1].split(',')[0]
                    if main_symbol == '%eax':
                        # to fit gcc-4.8 -m32, the address is mov to %eax, then push to stack
                        main_symbol = lines[i - 2].split()[-1].split(
                            ',')[0].split('0x')[1]
                    else:
                        main_symbol = main_symbol.split('0x')[1]
                    break
                #lines[i-1] = lines[i-1].replace(main_symbol, "main")
                #main_symbol = main_symbol[1:].strip()
                #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 **
            ##	....
        elif config.arch == config.ARCH_ARMT:
            ## 1035c:       4803            ldr     r0, [pc, #12]   ; (1036c <_start+0x28>)
            ## 1035e:       4b04            ldr     r3, [pc, #16]   ; (10370 <_start+0x2c>)
            ## 10360:       f7ff efde       blx     10320 <__libc_start_main@plt>
            ## 10364:       f7ff efe8       blx     10338 <abort@plt>
            ## ...
            ## 1036c:       0001052d
            for i in xrange(ll):
                l = lines[i]
                if '<__libc_start_main@plt>' in l:
                    j = i - 1
                    while j > 0:
                        if 'ldr' in lines[j] and 'r0' in lines[j]:
                            pcraddr = lines[j].split(
                                ';')[1].strip().split()[0][1:]
                            break
                        j -= 1
                    j = i + 1
                    while j < ll:
                        if lines[j].strip().startswith(pcraddr):
                            main_symbol = lines[j].split()[1]
                            if len(main_symbol) < 8:
                                main_symbol = lines[j +
                                                    1].split()[1] + main_symbol
                            main_symbol = int(main_symbol.lstrip('0'),
                                              16) & (-2)
                            main_symbol = '%X' % main_symbol
                            break
                        j += 1
                    break
        else:
            raise Exception('Unknown arch')

        with open("main.info", 'w') as f:
            f.write('S_0x' + main_symbol.upper() + '\n')