Example #1
0
def _mov_thumb(dst, src):
    if not pwn.isint(src):
        return "mov %s, %s" % (dst, src)

    srcu = src & 0xffffffff
    srcs = srcu - 2 * (srcu & 0x80000000)

    if srcu == 0:
        return 'eor %s, %s' % (dst, dst)

    if srcu < 256:
        return 'mov %s, #%d' % (dst, src)

    if -256 < srcs < 0:
        return 'eor %s, %s\nsub %s, #%d' % (dst, dst, dst, -srcs)

    shift1 = 0
    while (1 << shift1) & src == 0:
        shift1 += 1

    if (0xff << shift1) & src == src:
        if shift1 < 4:
            return 'mov %s, #%d\nlsl %s, #4\nlsr %s, #%d' % (
                dst, src >> shift1, dst, dst, 4 - shift1)
        return 'mov %s, #%d\nlsl %s, #%d' % (dst, src >> shift1, dst, shift1)

    shift2 = 8
    while (1 << shift2) & src == 0:
        shift2 += 1

    if ((0xff << shift2) | 0xff) & src == src:
        return 'mov %s, #%d\nlsl %s, #%d\nadd %s, #%d' % (
            dst, src >> shift2, dst, shift2, dst, src & 0xff)

    shift3 = shift1 + 8
    while (1 << shift3) & src == 0:
        shift3 += 1

    if ((0xff << shift1) | (0xff << shift3)) & src == src:
        return 'mov %s, #%d\nlsl %s, #%d\nadd %s, #%d\nlsl %s, #%d' % (
            dst, src >> shift3, dst, shift3 - shift1, dst,
            (src >> shift1) & 0xff, dst, shift1)

    id = pwn.randoms(32, only=string.ascii_lowercase)

    if (src & 0xFF000000 == 0x0):
        src = src | 0xFF000000

        extra = ''.join([
            "lsl %s, #8" % dst,
            "lsr %s, #8" % dst,
        ])

    return '\n'.join([
        "ldr %s, %s" % (dst, id),
        "b %s_after" % id,
        "%s: .word %d" % (id, src),
        "%s_after:" % id, extra
    ])
Example #2
0
def _mov_thumb(dst, src):
    if not pwn.isint(src):
        return "mov %s, %s" % (dst, src)

    srcu = src & 0xffffffff
    srcs = srcu - 2 * (srcu & 0x80000000)

    if srcu == 0:
        return 'eor %s, %s' % (dst, dst)

    if srcu < 256:
        return 'mov %s, #%d' % (dst, src)

    if -256 < srcs < 0:
        return 'eor %s, %s\nsub %s, #%d' % (dst, dst, dst, -srcs)

    shift1 = 0
    while (1 << shift1) & src == 0:
        shift1 += 1

    if (0xff << shift1) & src == src:
        if shift1 < 4:
            return 'mov %s, #%d\nlsl %s, #4\nlsr %s, #%d' % (dst, src >> shift1, dst, dst, 4-shift1)
        return 'mov %s, #%d\nlsl %s, #%d' % (dst, src >> shift1, dst, shift1)

    shift2 = 8
    while (1 << shift2) & src == 0:
        shift2 += 1

    if ((0xff << shift2) | 0xff) & src == src:
        return 'mov %s, #%d\nlsl %s, #%d\nadd %s, #%d' % (dst, src >> shift2, dst, shift2, dst, src & 0xff)

    shift3 = shift1 + 8
    while (1 << shift3) & src == 0:
        shift3 += 1

    if ((0xff << shift1) | (0xff << shift3)) & src == src:
        return 'mov %s, #%d\nlsl %s, #%d\nadd %s, #%d\nlsl %s, #%d' % (dst, src >> shift3, dst, shift3 - shift1, dst, (src >> shift1) & 0xff, dst, shift1)

    id = pwn.randoms(32, only = string.ascii_lowercase)

    if (src & 0xFF000000 == 0x0):
        src = src | 0xFF000000

        extra = ''.join([
        "lsl %s, #8" % dst,
        "lsr %s, #8" % dst,
        ])

    return '\n'.join([
        "ldr %s, %s" % (dst, id),
        "b %s_after" % id,
        "%s: .word %d" % (id, src),
        "%s_after:" % id,
		extra])
Example #3
0
def _clookup_real(consts):
    import string
    magic = pwn.randoms(32, only = string.ascii_lowercase)
    magic_ = '\n%s\n' % magic
    dat = magic_.join([''] + consts)

    output = pwn.asm(dat, emit_asm = 1)
    output_ = [line.strip() for line in output.split(magic)]

    if len(output_) != len(consts) + 1:
        raise Exception("Unknown output format:\n%s" % output)

    return output_[1:]
Example #4
0
def _mov_thumb(dst, src):
    if not isinstance(src, int):
        return "mov %s, %s" % (dst, src)

    srcu = src & 0xffffffff
    srcs = srcu - 2 * (srcu & 0x80000000)

    if srcu == 0:
        return 'eor %s, %s' % (dst, dst)

    if srcu < 256:
        return 'mov %s, #%d' % (dst, src)

    if -256 < srcs < 0:
        return 'eor %s, %s\nsub %s, #%d' % (dst, dst, dst, -srcs)

    shift1 = 0
    while (1 << shift1) & src == 0:
        shift1 += 1

    if (0xff << shift1) & src == src:
        if shift1 < 4:
            return 'mov %s, #%d\nlsl %s, #4\nlsr %s, #%d' % (dst, src >> shift1, dst, dst, 4-shift1)
        return 'mov %s, #%d\nlsl %s, #%d' % (dst, src >> shift1, dst, shift1)

    shift2 = 8
    while (1 << shift2) & src == 0:
        shift2 += 1

    if ((0xff << shift2) | 0xff) & src == src:
        return 'mov %s, #%d\nlsl %s, #%d\nadd %s, #%d' % (dst, src >> shift2, dst, shift2, dst, src & 0xff)

    shift3 = shift1 + 8
    while (1 << shift3) & src == 0:
        shift3 += 1

    if ((0xff << shift1) | (0xff << shift3)) & src == src:
        return 'mov %s, #%d\nlsl %s, #%d\nadd %s, #%d\nlsl %s, #%d' % (dst, src >> shift3, dst, shift3 - shift1, dst, (src >> shift1) & 0xff, dst, shift1)

    id = pwn.randoms(32, only = string.ascii_lowercase)
Example #5
0
def _mov_arm(dst, src):
    import string

    if not pwn.isint(src):
        return "mov %s, %s" % (dst, src)

    if len(asm("ldr %s, =%d" % (dst, src))) == 4:
        return "ldr %s, =%d" % (dst, src)

    srcu = src & 0xffffffff
    srcn = ~src & 0xffffffff

    for n, op in zip([srcu, srcn], ['mov', 'mvn']):
        shift1 = 0
        while (0x03 << shift1) & n == 0:
            shift1 += 2

        shift2 = shift1 + 8

        while (0x03 << shift2) & n == 0:
            shift2 += 2

        if n == (n & (0xff << shift1)) + (n & (0xff << shift2)):
            return '\n'.join([
                "// mov %s, #%d" % (dst, src),
                "%s %s, #%d" % (op, dst, (n & (0xff << shift1))),
                "%s %s, #%d" % ("eor", dst, (n & (0xff << shift2)))
            ])

    id = pwn.randoms(32, only=string.ascii_lowercase)

    return '\n'.join([
        "ldr %s, %s" % (dst, id),
        "b %s_after" % id,
        "%s: .word %d" % (id, src),
        "%s_after:" % id
    ])
Example #6
0
def _mov_arm(dst, src):
    import string

    if not isinstance(src, int):
        return "mov %s, %s" % (dst, src)

    if len(asm("ldr %s, =%d" % (dst, src))) == 4:
        return "ldr %s, =%d" % (dst, src)

    srcu =  src & 0xffffffff
    srcn = ~src & 0xffffffff

    for n, op in zip([srcu, srcn], ['mov', 'mvn']):
        shift1 = 0
        while (0x03 << shift1) & n == 0:
            shift1 += 2

        shift2 = shift1 + 8

        while (0x03 << shift2) & n == 0:
            shift2 += 2

        if n == (n & (0xff << shift1)) + (n & (0xff << shift2)):
            return '\n'.join([
                "// mov %s, #%d" % (dst, src),
                "%s %s, #%d" % (op,    dst, (n & (0xff << shift1))),
                "%s %s, #%d" % ("eor", dst, (n & (0xff << shift2)))
            ])

    id = pwn.randoms(32, only = string.ascii_lowercase)

    return '\n'.join([
        "ldr %s, %s" % (dst, id),
        "b %s_after" % id,
        "%s: .word %d" % (id, src),
        "%s_after:" % id])
Example #7
0
def _asm(target_arch, target_os, code_blocks, emit_asm=0, keep_tmp=False):
    import pwn.internal.shellcode_helper as H
    import os.path, tempfile, subprocess, string, shutil

    if target_arch == None:
        raise Exception('You need to set the architecture with context')

    tmpdir = tempfile.mkdtemp(prefix='pwn-asm-')

    def path(s):
        return os.path.join(tmpdir, s)

    try:
        magic = pwn.randoms(32, only=string.ascii_lowercase)

        code = []

        cpp = ['cpp', '-nostdinc', '-undef', '-w']
        if pwn.DEBUG:
            cpp += ['-D', 'DEBUG']

        if target_os != None:
            include = os.path.join(pwn.installpath, 'pwn', 'include',
                                   target_os)
            cpp += ['-I', include]

        if target_os == 'linux':
            if os.path.isfile(os.path.join(include, target_arch + '.h')):
                cpp += ['-I', os.path.join(include, 'diet')]
                code += ['#include <%s.h>' % target_arch]
        elif target_os == 'freebsd':
            code += ['#include <common.h>']

        code += [magic]
        if target_arch not in ['i386', 'amd64']:
            code += ['.section .shellcode,"ax"']

        asm_extra = []
        if target_arch == 'arm':
            code += ['.arm']
        elif target_arch == 'thumb':
            code += ['.thumb']
            target_arch = 'arm'
        elif target_arch == 'i386':
            code += ['bits 32']
        elif target_arch == 'amd64':
            code += ['bits 64']
        elif target_arch in ['mips', 'mipsel']:
            code += ['.set mips2']
            code += ['.set noreorder']
            if target_arch == 'mips':
                asm_extra += ['--EB']
            else:
                asm_extra += ['--EL']
            target_arch = 'mips'

        code += code_blocks
        code = '\n'.join(code)

        if target_arch in ['i386', 'amd64']:
            assembler = ['nasm', '-Ox'] + asm_extra
            objcopy = ['objcopy']
        else:
            assembler = [
                os.path.join(pwn.installpath, 'binutils', target_arch + '-as')
            ] + asm_extra
            if not os.path.isfile(assembler[0]):
                raise Exception(
                    'Could not find the gnu assembler for this architecture: %s'
                    % target_arch)
            objcopy = [
                os.path.join(pwn.installpath, 'binutils', 'promisc-objcopy')
            ]
        objcopy += ['-j.shellcode', '-Obinary']

        if emit_asm == 2:
            output = []

            output += [
                "/*", "   Assemble with:",
                "   %s [input] -o [input].tmp1" % ' '.join(cpp),
                "   sed -e '0,/^%s$/d' [input].tmp1 > [input].tmp2" % magic,
                "   %s [input].tmp2 -o [input].tmp3" % ' '.join(assembler)
            ]
            if target_arch not in ['i386', 'amd64']:
                output += ["   %s [input].tmp3 [output]" % ' '.join(objcopy)]
            output += ["*/", "", code]
            return '\n'.join(output)

        pwn.write(path('step1'), code)
        _run(cpp + [path('step1'), path('step2')])
        code = pwn.read(path('step2'))

        _code = code.split('\n' + magic + '\n')

        if len(_code) != 2:
            raise Exception("The output from cpp was weird:\n%s" % code)

        code = _code[1]

        if emit_asm == 1:
            output = []

            if target_arch in ['i386', 'amd64']:
                output += [
                    ';; Assemble with:',
                    ';;   %s <input> -o <output>' % ' '.join(assembler)
                ]
            else:
                output += [
                    "/*",
                    "   Assemble with:",
                    '   %s <input> -o <input>.tmp' % ' '.join(assembler),
                    '   %s [input].tmp [output]' % ' '.join(objcopy),
                    '*/',
                ]
            output += ["", code]
            return '\n'.join(output)

        pwn.write(path('step3'), code)
        _run(assembler + ['-o', path('step4'), path('step3')])

        if target_arch in ['i386', 'amd64']:
            return pwn.read(path('step4'))

        # Sanity check for seeing if the output has relocations
        relocs = subprocess.check_output(['readelf', '-r',
                                          path('step4')]).strip()
        if len(relocs.split('\n')) > 1:
            raise Exception('There were relocations in the shellcode:\n\n%s' %
                            relocs)

        _run(objcopy + [path('step4'), path('step5')])

        return pwn.read(path('step5'))
    finally:
        if not keep_tmp:
            try:
                shutil.rmtree(tmpdir)
            except:
                pass
Example #8
0
def _asm(target_arch, target_os, code_blocks, emit_asm = 0, keep_tmp = False):
    import pwn.internal.shellcode_helper as H
    import os.path, tempfile, subprocess, string, shutil

    if target_arch == None:
        raise Exception('You need to set the architecture with context')

    tmpdir = tempfile.mkdtemp(prefix = 'pwn-asm-')
    def path(s):
        return os.path.join(tmpdir, s)
    try:
        magic = pwn.randoms(32, only = string.ascii_lowercase)

        code = []

        cpp = ['cpp', '-nostdinc', '-undef', '-w']
        if pwn.DEBUG:
            cpp += ['-D', 'DEBUG']

        if target_os != None:
            include = os.path.join(pwn.installpath, 'pwn', 'include', target_os)
            cpp += ['-I', include]

        if target_os == 'linux':
            if os.path.isfile(os.path.join(include, target_arch + '.h')):
                cpp += ['-I', os.path.join(include, 'diet')]
                code += ['#include <%s.h>' % target_arch]
        elif target_os == 'freebsd':
            code += ['#include <common.h>']

        code += [magic]
        if target_arch not in ['i386', 'amd64']:
            code += ['.section .shellcode,"ax"']

        asm_extra = []
        if target_arch == 'arm':
            code += ['.arm']
        elif target_arch == 'thumb':
            code += ['.thumb']
            target_arch = 'arm'
        elif target_arch == 'i386':
            code += ['bits 32']
        elif target_arch == 'amd64':
            code += ['bits 64']
        elif target_arch in ['mips', 'mipsel']:
            code += ['.set mips2']
            code += ['.set noreorder']
            if target_arch == 'mips':
                asm_extra += ['--EB']
            else:
                asm_extra += ['--EL']
            target_arch = 'mips'

        code += code_blocks
        code = '\n'.join(code)

        if target_arch in ['i386', 'amd64']:
            assembler = ['nasm', '-Ox'] + asm_extra
            objcopy = ['objcopy']
        else:
            assembler = [os.path.join(pwn.installpath, 'binutils', target_arch + '-as')] + asm_extra
            if not os.path.isfile(assembler[0]):
                raise Exception('Could not find the gnu assembler for this architecture: %s' % target_arch)
            objcopy = [os.path.join(pwn.installpath, 'binutils', 'promisc-objcopy')]
        objcopy += ['-j.shellcode', '-Obinary']

        if emit_asm == 2:
            output = []

            output += [
                "/*",
                "   Assemble with:",
                "   %s [input] -o [input].tmp1"                       % ' '.join(cpp),
                "   sed -e '0,/^%s$/d' [input].tmp1 > [input].tmp2"   % magic,
                "   %s [input].tmp2 -o [input].tmp3"                  % ' '.join(assembler)
                ]
            if target_arch not in ['i386', 'amd64']:
                output += ["   %s [input].tmp3 [output]"              % ' '.join(objcopy)]
            output += ["*/", "", code]
            return '\n'.join(output)

        pwn.write(path('step1'), code)
        _run(cpp + [path('step1'), path('step2')])
        code = pwn.read(path('step2'))

        _code = code.split('\n' + magic + '\n')

        if len(_code) != 2:
            raise Exception("The output from cpp was weird:\n%s" % code)

        code = _code[1]

        if emit_asm == 1:
            output = []

            if target_arch in ['i386', 'amd64']:
                output += [
                    ';; Assemble with:',
                    ';;   %s <input> -o <output>'    % ' '.join(assembler)
                    ]
            else:
                output += [
                    "/*",
                    "   Assemble with:",
                    '   %s <input> -o <input>.tmp'   % ' '.join(assembler),
                    '   %s [input].tmp [output]'     % ' '.join(objcopy),
                    '*/',
                    ]
            output += ["", code]
            return '\n'.join(output)

        pwn.write(path('step3'), code)
        _run(assembler + ['-o', path('step4'), path('step3')])

        if target_arch in ['i386', 'amd64']:
            return pwn.read(path('step4'))

        # Sanity check for seeing if the output has relocations
        relocs = subprocess.check_output(['readelf', '-r', path('step4')]).strip()
        if len(relocs.split('\n')) > 1:
            raise Exception('There were relocations in the shellcode:\n\n%s' % relocs)

        _run(objcopy + [path('step4'), path('step5')])

        return pwn.read(path('step5'))
    finally:
        if not keep_tmp:
            try:
                shutil.rmtree(tmpdir)
            except:
                pass