コード例 #1
0
ファイル: Pwn.py プロジェクト: Freebien/ropgenerator
def pwn(args):
    global OUTPUT, OUTPUT_CONSOLE, OUTPUT_PYTHON
    global EXPLOIT_LMAX
    
    
    if( not args ):
        print_help()
        return 
        
    # Check if gadgets have been loaded in the DB 
    if( not Database.gadgets ):
        error("Oops. You have to load gadgets before pwning ;) ")
        return 
        
    # Set default output format 
    OUTPUT = OUTPUT_CONSOLE
    clmax = EXPLOIT_LMAX
    
    seenOutput = False
    seenLmax = False
    seenBadBytes = False
    seenVerbose = False
    seenOutfile = False
    seenPaddingByte = False
    seenPaddingLen = False

    constraint = Constraint()
    assertion = Assertion()
    subcommand = None
    outfile = None
    paddingByteStr = None 
    paddingLen = 0
    
    i = 0 
    while i < len(args):
        # Parse options     
        if( args[i][0] == '-' ):
            if( args[i] in [OPTION_BAD_BYTES, OPTION_BAD_BYTES_SHORT]):
                if( seenBadBytes ):
                    error("Error. '" + args[i] + "' option should be used only once")
                    return 
                if( i+1 >= len(args)):
                    error("Error. Missing bad bytes after option '"+args[i]+"'")
                    return 
                seenBadBytes = True
                (success, res) = parse_bad_bytes(args[i+1])
                if( not success ):
                    error(res)
                    return
                i = i+2
                constraint = constraint.add(BadBytes(res))
            elif( args[i] == OPTION_LMAX or args[i] == OPTION_LMAX_SHORT ):
                if( seenLmax ):
                    error("Error. '" + arg + "' option should be used only once.")
                    return 
                if( i+1 >= len(args)):
                    error("Error. Missing output format after option '"+arg+"'")
                    return 
                try:
                    clmax = int(args[i+1])
                    if( clmax < Arch.octets() ):
                        raise Exception()
                    # Convert number of bytes into number of ropchain elements
                    clmax /= Arch.octets()
                except:
                    error("Error. '" + args[i+1] +"' bytes is not valid")
                    return 
                i = i +2
                seenLmax = True
                       
            elif( args[i] in [OPTION_OUTPUT, OPTION_OUTPUT_SHORT]):
                if( seenOutput ):
                    error("Option '{}' should be used only once".format(args[i]))
                    return 
                if( i+1 >= len(args)):
                    error("Error. Missing output format after option '"+args[i]+"'")
                    return 
                if( args[i+1] in [OUTPUT_CONSOLE, OUTPUT_PYTHON]):
                    OUTPUT = args[i+1]
                    seenOutput = True
                    i += 2
                else:
                    error("Error. Unknown output format: {}".format(args[i+1]))
                    return 
            elif( args[i] in [OPTION_OUTFILE_SHORT, OPTION_OUTFILE] ):
                if( seenOutfile ):
                    error("Option '{}' should be used only once".format(args[i]))
                    return 
                if( i+1 >= len(args)):
                    error("Error. Missing file name after option '"+args[i]+"'")
                    return 
                seenOutfile = True
                outfile = args[i+1]
                i += 2
            elif( args[i] in [OPTION_PADDING_BYTE, OPTION_PADDING_BYTE_SHORT] ):
                if( seenPaddingByte ):
                    error("Option '{}' should be used only once".format(args[i]))
                    return 
                if( i+1 >= len(args)):
                    error("Error. Missing byte after option '"+args[i]+"'")
                    return 
                seenPaddingByte = True
                try:
                    paddingByte = int(args[i+1], 16)
                except:
                    error("Error. '{}' is not a valid byte".format(args[i+1]))
                    return 
                if( paddingByte > 0xff ):
                    error("Error. '{}' can't be stored in one byte".format(args[i+1]))
                    return
                paddingByteStr = "\\x"+format(paddingByte, "02x")
                i += 2
            elif( args[i] in [OPTION_PADDING_LEN, OPTION_PADDING_LEN_SHORT] ):
                if( seenPaddingLen ):
                    error("Option '{}' should be used only once".format(args[i]))
                    return 
                if( i+1 >= len(args)):
                    error("Error. Missing length after option '"+args[i]+"'")
                    return 
                seenPaddingLen = True
                try:
                    paddingLen = int(args[i+1], 10)
                except:
                    try:
                        paddingLen = int(args[i+1], 16)
                    except:
                        error("Error. '{}' is not a valid byte".format(args[i+1]))
                        return 
                if( paddingLen < 0 ):
                    error("Error. Padding length must be > 0")
                    return 
                i += 2
            elif( args[i] in [OPTION_HELP, OPTION_HELP_SHORT]):
                print_help()
                return 
            elif( args[i] in [OPTION_VERBOSE, OPTION_VERBOSE_SHORT]):
                seenVerbose = True
                i += 1
            else:
                error("Error. Unknown option '{}'".format(args[i]))
                return 
                
        # Parse a subcommand
        else:
            # Before parsing, check arguments 
            # Check arguments 
            if( seenPaddingByte and not seenPaddingLen ):
                error("Error. You have to specify padding length if you provide a padding byte. See the '-pl,--padding-length' option")
                return 
            # Parse subcommand 
            verbose_mode(seenVerbose)
            payload = None
            if( args[i] == CMD_DELIVER_SHELLCODE ):
                payload = dshell(args[i+1:], constraint, assertion, lmax=clmax)
            else:
                error("Error. Unknown subcommand : '{}'".format(args[i]))
                verbose_mode(False)
                return 
                
            verbose_mode(False)
            # Print result 
            if( payload == "help"):
                return 
            elif( not payload is None ):
                print(string_bold("\n\tBuilt exploit - {} bytes\n".format(payload.len_bytes)))
                # Normal output 
                if( OUTPUT == OUTPUT_CONSOLE ):
                    payload_string = payload.strConsole(Arch.bits(), constraint.getBadBytes())
                elif( OUTPUT == OUTPUT_PYTHON ):
                    payload_string = payload.strPython(Arch.bits(), constraint.getBadBytes(), \
                        noTab=seenOutfile, paddingByteStr=paddingByteStr, paddingLen=paddingLen)
                # Output to file
                if( outfile ):
                    try: 
                        f = open(outfile, "w")
                        f.write(remove_colors(payload_string))
                        f.close()
                        print(string_bold("\n\tWrote payload in file '{}'\n".format(outfile)))
                    except:
                        error("Error. Couldn't not write payload in file '{}'".format(outfile))
                else:
                    print(payload_string)
            else:
                error("Couldn't generate exploit")
            return 
                
    # Test parsing result 
    if( subcommand is None ):
        error("Missing subcommand")
        return
コード例 #2
0
ファイル: Pwn.py プロジェクト: kuteminh11/ropgenerator
def pwn(args):
    global OUTPUT, OUTPUT_CONSOLE, OUTPUT_PYTHON
    global EXPLOIT_LMAX

    if (not args):
        print_help()
        return

    # Check if gadgets have been loaded in the DB
    if (not Database.gadgets):
        error("Oops. You have to load gadgets before pwning ;) ")
        return

    # Set default output format
    OUTPUT = OUTPUT_CONSOLE
    clmax = EXPLOIT_LMAX

    seenOutput = False
    seenLmax = False
    seenBadBytes = False
    seenVerbose = False

    constraint = Constraint()
    assertion = Assertion()
    subcommand = None

    i = 0
    while i < len(args):
        # Parse options
        if (args[i][0] == '-'):
            if (args[i] in [OPTION_BAD_BYTES, OPTION_BAD_BYTES_SHORT]):
                if (seenBadBytes):
                    error("Error. '" + args[i] +
                          "' option should be used only once")
                    return
                if (i + 1 >= len(args)):
                    error("Error. Missing bad bytes after option '" + args[i] +
                          "'")
                    return
                seenBadBytes = True
                (success, res) = parse_bad_bytes(args[i + 1])
                if (not success):
                    error(res)
                    return
                i = i + 2
                constraint = constraint.add(BadBytes(res))
            elif (args[i] == OPTION_LMAX or args[i] == OPTION_LMAX_SHORT):
                if (seenLmax):
                    error("Error. '" + arg +
                          "' option should be used only once.")
                    return
                if (i + 1 >= len(args)):
                    error("Error. Missing output format after option '" + arg +
                          "'")
                    return
                try:
                    clmax = int(args[i + 1])
                    if (clmax < Arch.octets()):
                        raise Exception()
                    # Convert number of bytes into number of ropchain elements
                    clmax /= Arch.octets()
                except:
                    error("Error. '" + args[i + 1] + "' bytes is not valid")
                    return
                i = i + 2
                seenLmax = True

            elif (args[i] in [OPTION_OUTPUT, OPTION_OUTPUT_SHORT]):
                if (seenOutput):
                    error("Option '{}' should be used only once".format(
                        args[i]))
                    return
                if (i + 1 >= len(args)):
                    error("Error. Missing output format after option '" +
                          args[i] + "'")
                    return
                if (args[i + 1] in [OUTPUT_CONSOLE, OUTPUT_PYTHON]):
                    OUTPUT = args[i + 1]
                    seenOutput = True
                    i += 2
                else:
                    error("Error. Unknown output format: {}".format(args[i +
                                                                         1]))
                    return
            elif (args[i] in [OPTION_HELP, OPTION_HELP_SHORT]):
                print_help()
                return
            elif (args[i] in [OPTION_VERBOSE, OPTION_VERBOSE_SHORT]):
                seenVerbose = True
                i += 1
            else:
                error("Error. Unknown option '{}'".format(args[i]))
                return
        # Parse a subcommand
        else:
            verbose_mode(seenVerbose)
            payload = None
            if (args[i] == CMD_DELIVER_SHELLCODE):
                payload = dshell(args[i + 1:],
                                 constraint,
                                 assertion,
                                 lmax=clmax)
            else:
                error("Error. Unknown subcommand : '{}'".format(args[i]))
                verbose_mode(False)
                return

            verbose_mode(False)
            # Print result
            if (payload):
                print(
                    string_bold("\n\tBuilt exploit - {} bytes\n".format(
                        payload.len_bytes)))
                if (OUTPUT == OUTPUT_CONSOLE):
                    print(
                        payload.strConsole(Arch.bits(),
                                           constraint.getBadBytes()))
                elif (OUTPUT == OUTPUT_PYTHON):
                    print(
                        payload.strPython(Arch.bits(),
                                          constraint.getBadBytes()))
            else:
                error("Couldn't generate exploit")
            return

    # Test parsing result
    if (subcommand is None):
        error("Missing subcommand")
        return
コード例 #3
0
ファイル: Syscall.py プロジェクト: ufwt/ropgenerator
def syscall(args):
    global OUTPUT, OUTPUT_CONSOLE, OUTPUT_PYTHON
    # Parsing arguments
    if( not args):
        print_help()
        return
    OUTPUT = OUTPUT_CONSOLE
    funcName = None
    offset = 0
    i = 0
    seenOutput = False
    seenFunction = False
    seenBadBytes = False
    seenKeepRegs = False
    seenOffset = False
    
    constraint = Constraint()
    assertion = getBaseAssertion()
    while i < len(args):
        if( args[i] in [OPTION_LIST, OPTION_LIST_SHORT]):
            listSyscalls(args[1:])
            return 
        if( args[i] in [OPTION_BAD_BYTES, OPTION_BAD_BYTES_SHORT]):
            if( seenBadBytes ):
                error("Error. '" + args[i] + "' option should be used only once")
                return 
            if( i+1 >= len(args)):
                error("Error. Missing bad bytes after option '"+args[i]+"'")
                return 
            seenBadBytes = True
            (success, res) = parse_bad_bytes(args[i+1])
            if( not success ):
                error(res)
                return
            i = i+2
            constraint = constraint.add(BadBytes(res))
        elif( args[i] in [OPTION_KEEP_REGS, OPTION_KEEP_REGS_SHORT]):
            if( seenKeepRegs ):
                error("Error. '" + args[i] + "' option should be used only once")
                return 
            if( i+1 >= len(args)):
                error("Error. Missing register after option '"+args[i]+"'")
                return 
            seenKeepRegs = True
            (success, res) = parse_keep_regs(args[i+1])
            if( not success ):
                error(res)
                return
            i = i+2
            constraint = constraint.add(RegsNotModified(res))
        elif( args[i] == OPTION_OFFSET or args[i] == OPTION_OFFSET_SHORT ):
            if( seenOffset ):
                error("Error. '"+ args[i] + "' option should be used only once")
                return 
            if( i+1 >= len(args)):
                error("Error. Missing offset after option '"+args[i]+"'")
                return 
            try:
                offset = int(args[i+1])
                if( offset < 0 ):
                    raise Exception()
            except:
                try:
                    offset = int(args[i+1], 16)
                    if( offset < 0 ):
                        raise Exception()
                except: 
                    error("Error. '" + args[i+1] +"' is not a valid offset")
                    return 
            i += 2 
            seenOffset = True
        elif( args[i] in [OPTION_FUNCTION, OPTION_FUNCTION_SHORT] ):
            if( not loadedBinary() ):
                error("Error. You should load a binary before building ROPChains")
                return 
            elif( seenFunction ):
                error("Option '{}' should be used only once".format(args[i]))
                return  
            userInput = ''
            i +=1
            while( i < len(args) and args[i][0] != "-"):
                userInput += args[i]
                i += 1
            (funcName, funcArgs ) = parseFunction(userInput)
            if( not funcName):
                return 
            seenFunction = True
        elif( args[i] in [OPTION_OUTPUT, OPTION_OUTPUT_SHORT]):
            if( seenOutput ):
                error("Option '{}' should be used only once".format(args[i]))
                return 
            if( i+1 >= len(args)):
                error("Error. Missing output format after option '"+args[i]+"'")
                return 
            if( args[i+1] in [OUTPUT_CONSOLE, OUTPUT_PYTHON]):
                OUTPUT = args[i+1]
                seenOutput = True
                i += 2
            else:
                error("Error. Unknown output format: {}".format(args[i+1]))
                return 
        elif( args[i] in [OPTION_HELP, OPTION_HELP_SHORT]):
            print_help()
            return 
        else:
            error("Error. Unknown option '{}'".format(args[i]))
            return 
    
    if( not funcName ):
        error("Missing function to call")
    else:
        # Set offset 
        if ( not set_offset(offset) ):
            error("Error. Your offset is too big :'(")
            return 
        try:
            call(funcName, funcArgs, constraint, assertion)
        except Exception, e:
            reset_offset()
            import sys
            raise sys.exc_info()[1], None, sys.exc_info()[2]
        # Reset offset 
        reset_offset()
コード例 #4
0
def syscall(args):
    global OUTPUT, OUTPUT_CONSOLE, OUTPUT_PYTHON
    # Parsing arguments
    if (not args):
        print_help()
        return
    OUTPUT = OUTPUT_CONSOLE
    funcName = None
    i = 0
    seenOutput = False
    seenFunction = False
    seenBadBytes = False
    seenKeepRegs = False

    constraint = Constraint()
    assertion = Assertion()
    while i < len(args):
        if (args[i] in [OPTION_LIST, OPTION_LIST_SHORT]):
            listSyscalls(args[1:])
            return
        if (args[i] in [OPTION_BAD_BYTES, OPTION_BAD_BYTES_SHORT]):
            if (seenBadBytes):
                error("Error. '" + args[i] +
                      "' option should be used only once")
                return
            if (i + 1 >= len(args)):
                error("Error. Missing bad bytes after option '" + args[i] +
                      "'")
                return
            seenBadBytes = True
            (success, res) = parse_bad_bytes(args[i + 1])
            if (not success):
                error(res)
                return
            i = i + 2
            constraint = constraint.add(BadBytes(res))
        elif (args[i] in [OPTION_KEEP_REGS, OPTION_KEEP_REGS_SHORT]):
            if (seenKeepRegs):
                error("Error. '" + args[i] +
                      "' option should be used only once")
                return
            if (i + 1 >= len(args)):
                error("Error. Missing register after option '" + args[i] + "'")
                return
            seenKeepRegs = True
            (success, res) = parse_keep_regs(args[i + 1])
            if (not success):
                error(res)
                return
            i = i + 2
            constraint = constraint.add(RegsNotModified(res))
        elif (args[i] in [OPTION_FUNCTION, OPTION_FUNCTION_SHORT]):
            if (not loadedBinary()):
                error(
                    "Error. You should load a binary before building ROPChains"
                )
                return
            elif (seenFunction):
                error("Option '{}' should be used only once".format(args[i]))
                return
            userInput = ''
            i += 1
            while (i < len(args) and args[i][0] != "-"):
                userInput += args[i]
                i += 1
            (funcName, funcArgs) = parseFunction(userInput)
            if (not funcName):
                return
            seenFunction = True
        elif (args[i] in [OPTION_OUTPUT, OPTION_OUTPUT_SHORT]):
            if (seenOutput):
                error("Option '{}' should be used only once".format(args[i]))
                return
            if (i + 1 >= len(args)):
                error("Error. Missing output format after option '" + args[i] +
                      "'")
                return
            if (args[i + 1] in [OUTPUT_CONSOLE, OUTPUT_PYTHON]):
                OUTPUT = args[i + 1]
                seenOutput = True
                i += 2
            else:
                error("Error. Unknown output format: {}".format(args[i + 1]))
                return
        elif (args[i] in [OPTION_HELP, OPTION_HELP_SHORT]):
            print_help()
            return
        else:
            error("Error. Unknown option '{}'".format(args[i]))
            return

    if (not funcName):
        error("Missing function to call")
    else:
        call(funcName, funcArgs, constraint, assertion)
コード例 #5
0
def parse_args(args):
    """
    Parse the user supplied arguments to the 'find' function
    Returns either a tuple (True, GadgetType, x, y, constraint, nb_res, clmax )
    Or if not supported or invalid arguments, returns a tuple (False, msg)
    
    ---> See parse_user_request() specification for the list of possible tuples
         and values/types of x and y     
    """
    global OUTPUT

    seenExpr = False
    seenBadBytes = False
    seenKeepRegs = False
    seenOutput = False
    seenNbResults = False
    seenLmax = False

    i = 0  # Argument counter
    constraint = Constraint()
    nbResults = 1  # Default 1 result
    clmax = LMAX  # Max length
    OUTPUT = OUTPUT_CONSOLE
    while (i < len(args)):
        arg = args[i]
        # Look for options
        if (arg[0] == '-' and arg[1] != '>'):
            if (seenExpr):
                return (False,
                        "Error. Options must come before the search request")
            # bad bytes option
            if (arg == OPTION_BAD_BYTES or arg == OPTION_BAD_BYTES_SHORT):
                if (seenBadBytes):
                    return (False, "Error. '" + arg +
                            "' option should be used only once")
                if (i + 1 >= len(args)):
                    return (False, "Error. Missing bad bytes after option '" +
                            arg + "'")
                seenBadBytes = True
                (success, res) = parse_bad_bytes(args[i + 1])
                if (not success):
                    return (False, res)
                i = i + 1
                constraint = constraint.add(BadBytes(res))
            # Keep regs option
            elif (arg == OPTION_KEEP_REGS or arg == OPTION_KEEP_REGS_SHORT):
                if (seenKeepRegs):
                    return (False, "Error. '" + arg +
                            "' option should be used only once.")
                if (i + 1 >= len(args)):
                    return (False, "Error. Missing registers after option '" +
                            arg + "'")
                seenKeepRegs = True
                (success, res) = parse_keep_regs(args[i + 1])
                if (not success):
                    return (False, res)
                i = i + 1
                constraint = constraint.add(RegsNotModified(res))
            # Output option
            elif (arg == OPTION_OUTPUT or arg == OPTION_OUTPUT_SHORT):
                if (seenOutput):
                    return (False, "Error. '" + arg +
                            "' option should be used only once.")
                if (i + 1 >= len(args)):
                    return (False,
                            "Error. Missing output format after option '" +
                            arg + "'")
                if (args[i + 1] in [OUTPUT_CONSOLE, OUTPUT_PYTHON]):
                    OUTPUT = args[i + 1]
                    seenOutput = True
                    i = i + 1
                else:
                    return (False, "Error. '" + args[i + 1] +
                            "' output format is not supported")
            # Nb of results option
            elif (arg == OPTION_NB_RESULTS or arg == OPTION_NB_RESULTS_SHORT):
                if (seenNbResults):
                    return (False, "Error. '" + arg +
                            "' option should be used only once.")
                if (i + 1 >= len(args)):
                    return (False,
                            "Error. Missing output format after option '" +
                            arg + "'")
                try:
                    nbResults = int(args[i + 1])
                    if (nbResults <= 0):
                        raise Exception()
                except:
                    return (False, "Error. '" + args[i + 1] +
                            "' is not a valid number")
                i = i + 1
                seenNbResults = True
            elif (arg == OPTION_LMAX or arg == OPTION_LMAX_SHORT):
                if (seenLmax):
                    return (False, "Error. '" + arg +
                            "' option should be used only once.")
                if (i + 1 >= len(args)):
                    return (False,
                            "Error. Missing output format after option '" +
                            arg + "'")
                try:
                    clmax = int(args[i + 1])
                    if (clmax < Arch.octets()):
                        raise Exception()
                    # Convert number of bytes into number of ropchain elements
                    clmax /= Arch.octets()
                except:
                    return (False,
                            "Error. '" + args[i + 1] + "' bytes is not valid")
                i = i + 1
                seenLmax = True

            # Otherwise Ignore
            else:
                return (False, "Error. Unknown option: '{}' ".format(arg))
        # If not option it should be a request expr=expr
        else:
            if (seenExpr):
                return (False, "Error. Unexpected extra expression: '" +
                        ' '.join(args[i:]) + "'")
            else:
                seenExpr = True
                parsed_query = parse_query(''.join(args[i:]))
                if (not parsed_query[0]):
                    return (False, parsed_query[1])
                else:
                    i = len(args)
        i = i + 1
    if (not seenExpr):
        return (False, "Error. Missing specification of gadget to find")
    else:
        return parsed_query + (constraint, nbResults, clmax)
コード例 #6
0
def call(args):
    global OUTPUT, OUTPUT_CONSOLE, OUTPUT_PYTHON
    # Parsing arguments
    if( not args):
        print_help()
        return
    OUTPUT = OUTPUT_CONSOLE
    funcName = None
    i = 0
    seenOutput = False
    seenFunction = False
    seenBadBytes = False
    seenKeepRegs = False
    seenShortest = False
    seenLmax = False
    seenOffset = False
    clmax = None
    offset = 0 
    
    constraint = Constraint()
    assertion = getBaseAssertion()
    while i < len(args):
        if( args[i] in [OPTION_LIST, OPTION_LIST_SHORT]):
            func_list = getAllFunctions()
            print_functions(func_list)
            return 
        if( args[i] in [OPTION_BAD_BYTES, OPTION_BAD_BYTES_SHORT]):
            if( seenBadBytes ):
                error("Error. '" + args[i] + "' option should be used only once")
                return 
            if( i+1 >= len(args)):
                error("Error. Missing bad bytes after option '"+args[i]+"'")
                return 
            seenBadBytes = True
            (success, res) = parse_bad_bytes(args[i+1])
            if( not success ):
                error(res)
                return
            i = i+2
            constraint = constraint.add(BadBytes(res))
        elif( args[i] in [OPTION_KEEP_REGS, OPTION_KEEP_REGS_SHORT]):
            if( seenKeepRegs ):
                error("Error. '" + args[i] + "' option should be used only once")
                return 
            if( i+1 >= len(args)):
                error("Error. Missing register after option '"+args[i]+"'")
                return 
            seenKeepRegs = True
            (success, res) = parse_keep_regs(args[i+1])
            if( not success ):
                error(res)
                return
            i = i+2
            constraint = constraint.add(RegsNotModified(res))
        elif( args[i] in [OPTION_CALL, OPTION_CALL_SHORT] ):
            if( not loadedBinary() ):
                error("Error. You should load a binary before building ROPChains")
                return 
            elif( seenFunction ):
                error("Option '{}' should be used only once".format(args[i]))
                return  
            userInput = ''
            i +=1
            while( i < len(args) and args[i][0] != "-"):
                userInput += args[i]
                i += 1
            (funcName, funcArgs ) = parseFunction(userInput)
            if( not funcName):
                return 
            seenFunction = True
        elif( args[i] in [OPTION_OUTPUT, OPTION_OUTPUT_SHORT]):
            if( seenOutput ):
                error("Option '{}' should be used only once".format(args[i]))
                return 
            if( i+1 >= len(args)):
                error("Error. Missing output format after option '"+args[i]+"'")
                return 
            if( args[i+1] in [OUTPUT_CONSOLE, OUTPUT_PYTHON]):
                OUTPUT = args[i+1]
                seenOutput = True
                i += 2
            else:
                error("Error. Unknown output format: {}".format(args[i+1]))
                return 
        elif( args[i] in [OPTION_SHORTEST, OPTION_SHORTEST_SHORT]):
            if( seenShortest ):
                error("Option '{}' should be used only once".format(args[i]))
                return 
            seenShortest = True
            i += 1
        elif( args[i] == OPTION_LMAX or args[i] == OPTION_LMAX_SHORT ):
            if( seenLmax ):
                error("Option '{}' should be used only once".format(args[i]))
                return 
            if( i+1 >= len(args)):
                error("Error. Missing length after option '"+args[i]+"'")
                return 
            try:
                clmax = int(args[i+1])
                if( clmax < Arch.octets() ):
                    raise Exception()
                # Convert number of bytes into number of ropchain elements
                clmax /= Arch.octets()
            except:
                error("Error. '" + args[i+1] +"' bytes is not valid")
                return 
            i += 2 
            seenLmax = True
        elif( args[i] == OPTION_OFFSET or args[i] == OPTION_OFFSET_SHORT ):
            if( seenOffset ):
                error("Option '{}' should be used only once".format(args[i]))
                return 
            if( i+1 >= len(args)):
                error("Error. Missing offset after option '"+args[i]+"'")
                return 
            try:
                offset = int(args[i+1])
                if( offset < 0 ):
                    raise Exception()
            except:
                try:
                    offset = int(args[i+1], 16)
                    if( offset < 0 ):
                        raise Exception()
                except: 
                    error("Error. '" + args[i+1] +"' is not a valid offset")
                    return 
            i += 2 
            seenOffset = True
        elif( args[i] in [OPTION_HELP, OPTION_HELP_SHORT]):
            print_help()
            return 
        else:
            error("Error. Unknown option '{}'".format(args[i]))
            return 
    
    if( not funcName ):
        error("Missing function to call")
    else:
        # Set offset 
        if( not set_offset(offset) ):
            error("Error. Your offset is too big :'(")
            return 
        try:
            res = build_call(funcName, funcArgs, constraint, assertion, clmax=clmax, optimizeLen=seenShortest)
            if( isinstance(res, str) ):
                error(res)
            else:
                print_chains([res], "Built matching ROPChain", constraint.getBadBytes())
        except Exception, e:
            reset_offset()
            raise sys.exc_info()[1], None, sys.exc_info()[2]
        # Reset offset 
        reset_offset()