Beispiel #1
0
	def expand(self, match):
		# first we try to find the given arguments from the matched line, if needed
		# after that we find StringPositions from the payload
		# then we substitute each parameter match in the payload (not inside strings)
		start = match.start('name')
		end = match.end('name')
		identifier = match.group('name')

		#print("MATCH1: " + match.group(1))

		subs = Substitution(match.group('name'), start, end) 
		subs.string = ""
		subs.start = start
						
		if self.parameters:
			c = readchar(match.string, end)

			if not c or c != '(' and self.flag == False:
				errors.add(None, "No parameters for " + self.name)
				return False

			args = parseArgumentList(end, match.string)
			subs.end = end + args.length 

			#print("namematch: " + str(args.arr))

			replacement = self.payload
			strings = scanForStrings(replacement)

			if len(args.arr) != len(self.parameters):
				errors.add(None, "Invalid parameters")
				return None

			for i, p in enumerate(self.parameters):
				reg = re.compile(r"(\W|^)+(?P<name>" + p + r")(\W|$)+")

				while True:
					hits = 0
					namematch = reg.finditer(replacement)

					for n in namematch:
						if checkIfInsideString(n.start('name'), strings):
							continue

						replacement = n.string[:n.start('name')] + args.arr[i] + n.string[n.end('name'):]
						hits += 1
						break
					
					if hits == 0:
						break

			subs.string = replacement

		else:
			subs.string = self.payload

		return subs
Beispiel #2
0
def handlePragma(identifier, args):
    if identifier == "dumb_debug":
        args.dumb_debug = True
    elif identifier == "anticrap":
        args.anticrap = True
    elif identifier == "nomacros":
        args.nomacros = True
    else:
        errors.add("Invalid #pragma identifier")
    return args
Beispiel #3
0
def handlePragma(identifier, args):
	if identifier == "dumb_debug":
		args.dumb_debug = True
	elif identifier == "anticrap":
		args.anticrap = True
	elif identifier == "nomacros":
		args.nomacros = True
	else:
		errors.add("Invalid #pragma identifier")	
	return args
Beispiel #4
0
def expandAll(string, macros, visited, state):
    macrokeys = getMacroKeys(macros, state)
    expanded = string
    line = string
    strings = []

    for name in macrokeys:
        m = macros[name]

        if m.flag:
            continue

        if visited.contains(name):
            warnings.add(state.row, "Skipping recursive macro call " + name)
            continue

        try_match = True
        while (try_match):
            try_match = False
            strings = scanForStrings(expanded)
            namematch = m.nameregex.finditer(expanded)

            for n in namematch:
                if checkIfInsideString(n.start('name'), strings):
                    continue

                if checkIfInsideComment(line, n.start('name')):
                    continue

                if state.args.verbose: infos.add(state.row, "\tfound " + name)

                visited.push(name)
                length = getInvocationLength(n, m)

                subs = m.expand(n)
                visited.pop()

                if not subs:
                    errors.add(state.row, "Invalid macro call " + name)
                    return expanded

                final = expandAll(subs.string, macros, visited, state)
                expanded = strInsert(expanded, subs.start, subs.end, final)

                if state.args.verbose == True:
                    infos.add(state.row, "Expand " + name + ": " + final)
                try_match = True
                break

    return expanded
Beispiel #5
0
def expandAll(string, macros, visited, state):
	macrokeys = getMacroKeys(macros, state)
	expanded = string
	line = string
	strings = []
	
	for name in macrokeys:
		m = macros[name]

		if m.flag:
			continue
			
		if visited.contains(name):
			warnings.add(state.row, "Skipping recursive macro call " + name)
			continue

		try_match = True
		while (try_match):
			try_match = False
			strings = scanForStrings(expanded)
			namematch = m.nameregex.finditer(expanded)

			for n in namematch:
				if checkIfInsideString(n.start('name'), strings):
					continue

				if checkIfInsideComment(line, n.start('name')):
					continue

				if state.args.verbose: infos.add(state.row, "\tfound " + name)

				visited.push(name)
				length = getInvocationLength(n, m)
				
				subs = m.expand(n)
				visited.pop()
				
				if not subs:
					errors.add(state.row, "Invalid macro call " + name)
					return expanded

				final = expandAll(subs.string, macros, visited, state)
				expanded = strInsert(expanded, subs.start, subs.end, final)
				
				if state.args.verbose == True: infos.add(state.row, "Expand " + name + ": " + final)
				try_match = True
				break
				
	return expanded
Beispiel #6
0
def getInvocationLength(match, macro):
    start = match.start('name')
    end = match.end('name')
    identifier = match.group('name')

    c = readchar(match.string, end)

    if macro.flag == True:
        return len(match.group('name'))

    if not c or c != '(' and macro.parameters:
        errors.add(None, "No parameters for " + macro.name)
        return False

    args = parseArgumentList(match.end('name'), match.string)

    if not args:
        return False

    return args.length + len(identifier)
Beispiel #7
0
def getInvocationLength(match, macro):
	start = match.start('name')
	end = match.end('name')
	identifier = match.group('name')
	
	c = readchar(match.string, end)
	
	if macro.flag == True:
		return len(match.group('name'))

	if not c or c != '(' and macro.parameters:
		errors.add(None, "No parameters for " + macro.name)
		return False
		
	args = parseArgumentList(match.end('name'), match.string)
	
	if not args:
		return False
		
	return args.length + len(identifier)
Beispiel #8
0
	def process(self):
		args = self.args
		self.state.args = args
		state = self.state

		path = args.input

		inputfile = open(path)
		nextline = inputfile.readline()
		line = ""

		state.filename = ntpath.basename(path)
		state.row = 0
		out = [] # the actual contents of the output file

		operations = []
		operations.append(IfdefOperation())
		operations.append(DebugOperation())
		operations.append(CommentOperation())
		operations.append(MacroOperation())
		""" TODO: #include handling might clash with DECORATE definitions """
		operations.append(MultilineMacroOperation())
		
		operations.append(DotOperation())
		operations.append(MinifyOperation())
		operations.append(CullOperation())

		while True:
			state.depth = 0 	# paren depth
			state.instring = False
			discard = False

			line = nextline
			nextline = inputfile.readline()

			if not nextline:
				state.lastline = True

			if not line:
				break

			current_line = line
			state.row += 1

			for o in operations:
				result = o.apply(current_line, state)

				if result.error != None:
					errors.add(state.row, result.error)

				if result.discard:
					discard = True
					break
				current_line = result.line
				
			if not discard:
				out.append(current_line)
		inputfile.close()

		outputfile = open(args.output, 'w')
		for r in out:
			print(r, file=outputfile, end='')

		outputfile.close()
			
		if args.show_report:
			print ("Found the following macros: ")
			for m in state.macros:
				print(str(state.macros[m]))

			print("")
		if args.wait_on_error:
			error_count = len(errors.getLog())
			print(str(error_count) + " errors: ")

			for m in errors:
				print("  " + m.toString())

			if error_count > 0:
				waitForEnter()
Beispiel #9
0
    def expand(self, match):
        # first we try to find the given arguments from the matched line, if needed
        # after that we find StringPositions from the payload
        # then we substitute each parameter match in the payload (not inside strings)
        start = match.start('name')
        end = match.end('name')
        identifier = match.group('name')

        #print("MATCH1: " + match.group(1))

        subs = Substitution(match.group('name'), start, end)
        subs.string = ""
        subs.start = start

        if self.parameters:
            c = readchar(match.string, end)

            if not c or c != '(' and self.flag == False:
                errors.add(None, "No parameters for " + self.name)
                return False

            args = parseArgumentList(end, match.string)
            subs.end = end + args.length

            #print("namematch: " + str(args.arr))

            replacement = self.payload
            strings = scanForStrings(replacement)

            if len(args.arr) != len(self.parameters):
                errors.add(None, "Invalid parameters")
                return None

            for i, p in enumerate(self.parameters):
                reg = re.compile(r"(?P<name>(?P<hash>#)?" + p + r")(\W|$)+")

                while True:
                    hits = 0
                    namematch = reg.finditer(replacement)

                    for n in namematch:
                        if checkIfInsideString(n.start('name'), strings):
                            continue

                        val = args.arr[i]

                        if n.group('hash'):
                            val = '"' + val + '"'
                        replacement = n.string[:n.start(
                            'name')] + val + n.string[n.end('name'):]
                        hits += 1
                        break

                    if hits == 0:
                        break

            subs.string = replacement

        else:
            subs.string = self.payload

        return subs