示例#1
0
def assemble(data,arch):
    """
    assembles a given block of data into bytecodes
    """
    if arch=="X86":
        data=atandtparse.atandtpreprocess(data)
        tokens=atandtscan.scan(data)
        tree=atandtparse.parse(tokens)
        x=atandtparse.x86generate(tree)
        return x.value
    
    print "Unknown arch: %s"%arch
    return None
示例#2
0
文件: mosdef.py 项目: tsondt/Canvas
def assembleEx(data, arch):
    devlog("mosdef", "Assembling with arch %s" % arch)
    if data in ["", None]:
        devlog("mosdef", "assembling nothing!")
        return (None, None)

    if arch.upper() == "X86":
        #write out every assembled file...
        #file("mcode.s","w").write(data)
        if 1:
            devlog("mosdef", "Using new assembler")
            data = x86parse.assemble_x86(data)
        else:
            #old assembler is not compatible with
            #solaris x86 shellcode because we use CPUID
            #and a lot of other stuff it can't handle
            devlog("mosdef", "Using old assembler")
            data = atandtparse.atandtpreprocess(data)
            #print data
            tokens = atandtscan.scan(data)
            #print tokens
            #print "Getting tree"
            try:
                tree = atandtparse.parse(tokens)
            except:
                import traceback
                traceback.print_exc(file=sys.stdout)
                print "Syntax error in: %s" % data
                #change these numbers for sanity when you find
                #the line number...
                lines = data.split("\n")[68:75]
                print "Lines: %s" % ("\n".join(lines))
                name = "parserbug_assembly.txt"
                print "Writing code that generated exception to %s" % name
                o = file(name, "wb")
                o.write(data)
                o.close()
                return (None, None)
            try:
                #print "Getting generation"
                x = atandtparse.x86generate(tree)
            except:
                import traceback
                traceback.print_exc()
                print "syntax error:"
                print data
                return (None, None)
            #print "Done assembling"
            return (x.value, x.metadata)
        return (data, None)

    elif arch.upper() in ["SPARC", "PPC", "ARM"]:
        procparse = __import__('%sparse' % arch.lower())
        parser, yaccer = procparse.getparser()
        lexer = parser.lexer
        #print "pass 1"
        yaccer.parse(data, lexer=lexer, debug=0)
        #print "1: %s"%parser.labelinfo
        parser2, yaccer2 = procparse.getparser(runpass=2)
        parser2.labelinfo = parser.labelinfo  #saved off from runpass 1
        #print "2: %s %s"%(parser2.labelinfo,parser2.runpass)
        lexer2 = parser2.lexer
        #print "pass 2"
        yaccer2.parse(data, lexer=lexer2, debug=0)
        data = "".join(parser2.value)
        #print hexprint(data)
        return (data, None)  #no metadata?

    print "Unknown arch: %s" % arch
    return (None, None)
示例#3
0
def chunkize(shellc, wsize, jsize, arch="X86"):
    MAXINTELOPCODE = 9
    if jsize > 127:
        print "Sorry, this chunksize version only support jmp rel8 (%d) " % jsize
        return ""
    data = atandtparse.atandtpreprocess(shellc)
    tokens = atandtscan.scan(data)
    tree = atandtparse.parse(tokens)
    x = atandtparse.x86generate(tree)
    #print x.metadata
    idx = 0  # memory index
    i = 0  # instruction
    labels = {}
    mark = {}
    result = ""
    chunk = ""
    ilength = 0
    maxchunk = wsize - 2  # 2==sizeof("jmp jsize")
    # look for labels
    for a in range(0, len(x.metadata)):
        if x.metadata[a]["type"] == "label":
            labels[x.metadata[a]["label"]] = x.metadata[a]

    # NOTE FOR TOMORROW:
    #  - Fijate que los marks[] se ponen por name, y en el caso de exit, se setea 2 veces,
    #     pero una sola es la correcta, en cuanto a lo demas, parece que todo se ajusta :D
    #     ya veremos maniana.
    for a in range(0, len(x.metadata)):

        if x.metadata[a].has_key("length"):
            ilength = x.metadata[a]["length"]  # instruction size
            tmp = x.value[i:i + ilength]  # intruction itself
            i += ilength
        elif x.metadata[a]["type"] == "label":
            name = x.metadata[a]["label"]
            # only for possitive "labeled" jmp
            if mark.has_key(name):
                for step in mark[name]:
                    # ok... this is the NASTYest of the whole function (if nastyest exist on english dictionary)
                    tmp2 = mosdef.assemble(
                        "%s $%d" % (step[2], idx - step[0] - 2), arch)
                    tmp2 = tmp2 + "\x90" * (step[1] - len(tmp2))
                    #print "\nset %s mark: %d to %d " % (name,step[3], step[3]+len(tmp2))
                    #for pt in range(0, len(result)):
                    #        print "[%d]" % pt + hex(ord(result[pt])),
                    #tmp2="B" * len(tmp2)
                    result = result[:step[3]] + tmp2 + result[step[3] +
                                                              len(tmp2):]
            # for negative values, we update this
            x.metadata[a]["offset2"] = idx
            labels[x.metadata[a]["label"]] = x.metadata[a]
            continue
        else:
            print "Error: mnemonic without length: %s" % str(x.metadata[a])
        if x.metadata[a].has_key("jumpto"):
            # is int ?
            where = x.metadata[a]["jumpto"]
            # USE LABELS :D (offset mucks everything up!)
            if type(where) == type(0):
                # make things work with integer
                pass
            elif labels.has_key(where):
                # Negative jmp with a label WORKING!!!
                if labels[where]["offset"] < x.metadata[a]["offset"]:
                    noff = labels[where]["offset2"] - idx
                    tmp = mosdef.assemble(
                        "%s $%d" % (x.metadata[a]["type"], noff - ilength),
                        arch)
                    #if ilength+len(chunk) > maxchunk:
                    if len(tmp) + len(chunk) > maxchunk:
                        tmp = mosdef.assemble(
                            "%s $%d" %
                            (x.metadata[a]["type"], noff - len(tmp) - jsize -
                             (wsize - len(chunk))), arch)
                    # it might be possible that size change
                    # jmp 127, so we will check that
                    #if len(tmp) > ilength:
                    #        tmp= mosdef.assemble("%s $%d" % (x.metadata[a]["type"], noff - len(tmp)), arch)
                    #        print "(%d)" % (noff - len(tmp))
                    ilength = len(tmp)
                else:

                    # POSITIVE jmp
                    # We take the maximum possible size
                    #                   jmp value
                    # ORIGINAL
                    psize = (x.metadata[a]["offset"] -
                             labels[where]["offset"]) * (wsize + jsize) / wsize
                    # and then, if its smaller, we will padd with \90
                    maxop = len(
                        mosdef.assemble(
                            "%s $%u" % (x.metadata[a]["type"], psize), arch))

                    ts = len(result) + len(chunk)
                    ilength = maxop
                    tmp = "@" * ilength
                    bu = idx
                    if ilength + len(chunk) > maxchunk:
                        bu += (maxchunk - len(chunk)) + jsize
                        ts += (wsize - len(chunk))
                    if mark.has_key(x.metadata[a]["jumpto"]):
                        mark[x.metadata[a]["jumpto"]].append(
                            (bu, maxop, x.metadata[a]["type"], ts))
                    else:
                        mark[x.metadata[a]["jumpto"]] = [
                            (bu, maxop, x.metadata[a]["type"], ts)
                        ]

        if ilength + len(chunk) > maxchunk:
            result+=chunk+ "\x90" * (maxchunk - len(chunk)) + \
                mosdef.assemble("jmp $%d" % jsize, arch)
            #+ "A" * jsize # THIS IS FOR TEST POURPOSE ONLY
            idx += (maxchunk - len(chunk))  # padding
            idx += jsize  # hole size
            idx += 2  # near jmp
            chunk = tmp
            idx += ilength
        else:
            chunk += tmp
            idx += ilength

    return result + chunk
示例#4
0
def chunkize(shellc, wsize, jsize, arch="X86"):
    MAXINTELOPCODE = 9

    if jsize > 127:
        print "Sorry, this chunksize version only support jmp rel8 (%d) " % jsize
        return ""
    data = atandtparse.atandtpreprocess(shellc)
    tokens = atandtscan.scan(data)
    tree = atandtparse.parse(tokens)
    x = atandtparse.x86generate(tree)
    #print x.metadata
    idx = 0  # memory index
    i = 0  # instruction
    labels = {}
    mark = {}
    result = ""
    chunk = ""
    ilength = 0
    maxchunk = wsize - 2  # 2==sizeof("jmp jsize")

    # look for labels
    for a in range(0, len(x.metadata)):
        if x.metadata[a]["type"] == "label":
            labels[x.metadata[a]["label"]] = x.metadata[a]

    for a in range(0, len(x.metadata)):

        if x.metadata[a].has_key("length"):
            ilength = x.metadata[a]["length"]  # instruction size
            tmp = x.value[i:i + ilength]  # intruction itself
            i += ilength

        elif x.metadata[a]["type"] == "label":
            name = x.metadata[a]["label"]
            # only for possitive "labeled" jmp
            if mark.has_key(name):
                # ok... this is the NASTYest of the whole function (if nastyest exist on english dictionary)
                tmp2 = mosdef.assemble(
                    "%s $%d" % (mark[name][2], idx - mark[name][0] - 2), arch)
                result = result[:mark[name][0]] + tmp2 + result[mark[name][0] +
                                                                len(tmp2):]
            # for negative values, we update this
            x.metadata[a]["offset2"] = idx
            labels[x.metadata[a]["label"]] = x.metadata[a]
            continue

        else:
            print "Error: mnemonic without length: %s" % str(x.metadata[a])

        if x.metadata[a].has_key("jumpto"):
            # is int ?
            where = x.metadata[a]["jumpto"]

            # USE LABELS :D (offset mucks everything up!)
            if type(where) == type(0):
                pass
                # make things work with integer

            elif labels.has_key(where):

                # Negative jmp with a label WORKING!!!
                if labels[where]["offset"] < x.metadata[a]["offset"]:
                    noff = labels[where]["offset2"] - idx
                    tmp = mosdef.assemble(
                        "%s $%d" % (x.metadata[a]["type"], noff - ilength),
                        arch)

                    if ilength + len(chunk) > maxchunk:
                        tmp = mosdef.assemble(
                            "%s $%d" %
                            (x.metadata[a]["type"], noff - len(tmp) - jsize -
                             (maxchunk - len(chunk))), arch)

                    # it might be possible that size change
                    # jmp 127, so we will check that
                    if len(tmp) > ilength:
                        tmp = mosdef.assemble(
                            "%s $%d" %
                            (x.metadata[a]["type"], noff - len(tmp)), arch)
                    ilength = len(tmp)

                else:
                    # POSSITIVE jmp
                    # We take the maximun possible size
                    #                   jmp value
                    psize = (x.metadata[a]["offset"] -
                             labels[where]["offset"]) * (wsize + jsize) / wsize
                    # and then, if its smaller, we will padd with \90
                    maxop = len(
                        mosdef.assemble(
                            "%s $%d" % (x.metadata[a]["type"], psize), arch))
                    tmp = "\x90" * maxop
                    ilength = len(tmp)
                    bu = idx

                    if ilength + len(chunk) > maxchunk:
                        #      nops                  chunk
                        bu += (maxchunk - len(chunk)) + jsize

                    mark[x.metadata[a]["jumpto"]] = (bu, maxop,
                                                     x.metadata[a]["type"])

        if ilength + len(chunk) > maxchunk:
            result+=chunk+ "\x90" * (maxchunk - len(chunk)) + \
                  mosdef.assemble("jmp $%d" % jsize, arch)
            result += "A" * jsize  # THIS IS FOR TEST POURPOSE ONLY
            idx += (maxchunk - len(chunk))  # padding
            idx += jsize  # hole size
            idx += 2  # near jmp
            chunk = tmp
            idx += ilength

        else:
            chunk += tmp
            idx += ilength

    return result + chunk