예제 #1
0
class JsDomFuzzer(Fuzzer):
    NAME = "js_dom_fuzzer"
    CONFIG_PARAMS = [
        "starting_elements", "total_operations", "browser", "seed",
        "canvas_size", "file_type"
    ]
    CALLING_COMMENT = "//FUNCTION_CALLING"
    TIMEOUT = 20

    def __init__(self,
                 starting_elements,
                 total_operations,
                 browser,
                 seed,
                 canvas_size,
                 file_type='html'):
        self._starting_elements = int(starting_elements)
        self._total_operations = int(total_operations)
        self._browser = browser
        seed = int(seed)
        #  self._html_fuzzer = HtmlFuzzer(self._starting_elements, 3, seed)
        self._html_fuzzer = Html5Fuzzer(int(seed), self._starting_elements, 10,
                                        5, file_type)
        self._css_fuzzer = CssFuzzer(seed)
        self._canvas_fuzzer = CanvasFuzzer(int(canvas_size))
        if seed == 0:
            random.seed()
        else:
            random.seed(seed)
        self._file_type = file_type
        self._function_count = 0
        self._operations_count = 0
        self._js_elements = {}
        """:type dict(JsElement)"""
        self._occurring_events = {}
        for event in DomObjectTypes.DOM_EVENTS:
            self._occurring_events[event] = 0
        self._html_page = None
        self._calls_in_startup = []
        # arrays dictionary layout: {'array_id': [JsObject, .... JsObject], ...}
        self._arrays = {}

    @classmethod
    def from_list(cls, params):
        return cls(params[0], params[1], params[2], params[3], params[4],
                   params[5])

    @property
    def prng_state(self):
        return random.getstate()

    @property
    def file_type(self):
        return self._file_type

    def set_seed(self, seed=0):
        random.seed(seed)

    def __re_init(self):
        self._function_count = 0
        self._operations_count = 0
        self._function_count = 0
        self._operations_count = 0
        self._js_elements = {}
        self._calls_in_startup = []
        self._arrays = []
        self._occurring_events = {}
        for event in DomObjectTypes.DOM_EVENTS:
            self._occurring_events[event] = 0

    def create_testcases(self, count, directory):
        for i in range(count):
            test_name = "/test" + str(i) if i > 9 else "/test0" + str(i)
            with open(directory + test_name + "." + self._file_type,
                      "wb+") as html_fd, open(directory + test_name + ".css",
                                              "wb+") as css_fd:
                html, css = self.fuzz()
                html = html.replace("TESTCASE", test_name)
                html_fd.write(html)
                css_fd.write(css)

    def fuzz(self):
        self._html_page = self._html_fuzzer.fuzz()
        html = self._html_page.get_raw_html()
        self._css_fuzzer.set_tags(
            self._html_page.get_elements_by_html_tag().keys())
        css = self._css_fuzzer.fuzz()
        js_code = ""
        js_code += self.__create_canvas_functions()
        js_code += self.__create_startup()
        while self._total_operations > self._operations_count:
            js_code += self.__add_function()
        js_code += self.__add_event_dispatcher()
        js_code += self.__create_event_handlers()
        js_code = js_code.replace(self.CALLING_COMMENT,
                                  self.__concate_startup_list())
        doc = html.replace("SCRIPT_BODY", js_code)
        self.__re_init()
        return doc, css

    def set_state(self, state):
        random.setstate(state)

    def __create_startup(self):
        code = "function startup() {\n"
        i = 0
        for elem_id in self._html_page.get_element_ids():
            code += "\t" + "elem" + str(i) + " = " + JsDocument.getElementById(
                elem_id) + "\n"
            self._js_elements["elem" + str(i)] = JsDomElement(
                "elem" + str(i), self._html_page.get_element_by_id(elem_id))
            i += 1
        code += "\t" + self.CALLING_COMMENT + \
                "\n\tevent_firing();\n}\n"
        return code

    def __create_canvas_functions(self):
        code = ""
        for canvas_id in (
                self._html_page.get_elements_by_html_tag())['canvas']:
            self._calls_in_startup.append("\tfunc_" + canvas_id + "();")
            self._canvas_fuzzer.set_canvas_id(canvas_id)
            code += self._canvas_fuzzer.fuzz()
        return code

    def __add_function(self, func_name=None, event=False):
        if not func_name:
            func_name = "func_" + str(self._function_count) + "()"
        code = "function " + func_name + " {\n"
        func_count = random.randint(10, 50)
        for i in range(func_count):
            code += "\t" + JsGlobal.try_catch_block(
                self.__add_element_method())
        if not event:
            self._function_count += 1
            if random.randint(0, 10) <= 3:
                code += "\t" + JsWindow.setTimeout(
                    "func_" + str(self._function_count) + "()",
                    self.TIMEOUT) + "\n"
            else:
                self._calls_in_startup.append("\tfunc_" +
                                              str(self._function_count) +
                                              "();")
        code += "}\n"
        return code

    def __create_event_handlers(self):
        code = ""
        for event in self._occurring_events:
            code += self.__add_function(event + "_handler" + "(event)", True)
        return code

    def __add_event_dispatcher(self):
        code = "function event_firing() {\n"
        for key in self._js_elements:
            for event in self._js_elements[key].registered_events.keys():
                if 'DOM' in event:
                    continue
                elif event == 'click':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].click() + "\n", "ex")
                elif event == 'error':
                    pass
                elif event == 'load':
                    pass
                elif event == 'scroll':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].scrollLeft() + " = 10;" + "\n",
                        "ex")
                elif event == 'resize' or event == 'change':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].innerHtml() + " = \"" +
                        "A" * 100 + "\";\n", "ex")
                elif event == 'focus' or event == 'focusin':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].focus() + "\n", "ex")
                elif event == 'blur':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].blur() + "\n", "ex")
                elif event == 'select':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].select() + "\n", "ex")
        code += "}\n"
        return code

    def __add__new_element(self):
        elem_name = "elem_cr" + str(len(self._js_elements))
        html_type = random.choice(HTML_OBJECTS)
        code = elem_name + " = " + JsDocument.createElement(html_type) + "\n"
        self._js_elements[elem_name] = JsDomElement(elem_name, html_type)
        return elem_name, code, html_type

    def __add_element_method(self, key=None):
        code = ""
        if not key:
            key = random.choice(self._js_elements.keys())
        method = random.choice(DomObjectTypes.DOM_ELEMENT_FUZZ_STUFF)
        if method == 'addEventListener':
            event = random.choice(DomObjectTypes.DOM_EVENTS)
            self._occurring_events[event] += 1
            code += self._js_elements[key].addEventListener(
                event, event + "_handler")
        elif method == 'appendChild':
            if random.randint(1, 100) < 80:
                child = random.choice(self._js_elements.keys())
                if child == key:
                    elem_name, add_code, html_type = self.__add__new_element()
                    code += add_code
                    self._js_elements[elem_name] = JsDomElement(
                        elem_name, self._js_elements[key].html_type)
                    child = elem_name
                code += self._js_elements[key].appendChild(child)
            else:
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                self._js_elements[elem_name] = JsDomElement(
                    elem_name, html_type)
                code += self._js_elements[key].appendChild(elem_name)
        elif method == 'cloneNode':
            length = len(self._js_elements)
            elem_name = "elem_cr" + str(length)
            code += elem_name + " = " + self._js_elements[key].cloneNode(True)
            self._js_elements[elem_name] = JsDomElement(
                elem_name, self._js_elements[key].html_type)
            self._js_elements[elem_name].set_children(
                self._js_elements[key].get_children())
        elif method == 'hasAttribute':
            code += self._js_elements[key].hasAttribute(
                random.choice(HTML_ATTR_GENERIC))
        elif method == 'hasChildNode':
            code += self._js_elements[key].hasChildNodes()
        elif method == 'insertBefore':
            if not self._js_elements[key].get_children():
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += "\t" + self._js_elements[key].appendChild(
                    elem_name) + "\n"
            elem_name, add_code, html_type = self.__add__new_element()
            code += add_code
            code += self._js_elements[key].insertBefore(
                elem_name,
                random.choice(self._js_elements[key].get_children()))
        elif method == 'normalize':
            code += self._js_elements[key].normalize()
        elif method == 'removeAttribute':
            if not self._js_elements[key].attributes:
                code += self._js_elements[key].setAttribute(
                    random.choice(HTML_ATTR_GENERIC),
                    random.choice(FuzzValues.INTERESTING_VALUES))
            else:
                code += self._js_elements[key].removeAttribute(
                    random.choice(self._js_elements[key].attributes.keys()))
        elif method == 'removeChild':
            if not self._js_elements[key].get_children():
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].appendChild(elem_name)
            else:
                code += self._js_elements[key].removeChild(
                    random.choice(self._js_elements[key].get_children()))
        elif method == 'replaceChild':
            if not self._js_elements[key].get_children():
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].appendChild(elem_name)
            else:
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].replaceChild(
                    elem_name,
                    random.choice(self._js_elements[key].get_children()))
        elif method == 'removeEventListener':
            if not self._js_elements[key].registered_events:
                event = random.choice(DomObjectTypes.DOM_EVENTS)
                self._occurring_events[event] += 1
                code += self._js_elements[key].addEventListener(
                    event, event + "_handler")
            else:
                event = random.choice(
                    self._js_elements[key].registered_events.keys())
                self._occurring_events[event] -= 1
                event = random.choice(
                    self._js_elements[key].registered_events.keys())
                code += self._js_elements[key].removeEventListener(
                    event, self._js_elements[key].registered_events[event])
        elif method == 'setAttribute':
            attr = random.choice(HTML_ATTR_GENERIC)
            if attr == 'style':
                val = ""
                for i in range(1, 50):
                    css = random.choice(CSS_STYLES)
                    val += css[0] + ": " + random.choice(css[1:]) + "; "
            else:
                val = random.choice(FuzzValues.INTERESTING_VALUES)
            code += self._js_elements[key].setAttribute(attr, val)
        elif method == 'REPLACE_EXIST_ELEMENT':
            elem_name, add_code, html_type = self.__add__new_element()
            code += add_code
            code += "\t" + key + " = " + elem_name + ";"
            self._js_elements[key] = self._js_elements[elem_name]
        elif method == 'MIX_REFERENCES':
            code += self._js_elements[key]
        elif method == 'className':
            code += self._js_elements[key].className(
            ) + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'contentEditable':
            code += self._js_elements[key].contentEditable(
            ) + " = " + random.choice(FuzzValues.BOOL) + ";"
        elif method == 'dir':
            code += self._js_elements[key].dir() + " = \"" + random.choice(
                FuzzValues.TEXT_DIRECTION) + "\";"
        elif method == 'id':
            code += self._js_elements[key].id() + " = \"" + random.choice(
                FuzzValues.STRINGS) + "\";"
        elif method == 'innerHTML':
            code += self._js_elements[key].innerHtml(
            ) + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'lang':
            code += self._js_elements[key].lang() + " = \"" + random.choice(
                FuzzValues.LANG_CODES) + "\";"
        elif method == 'scrollLeft':
            code += self._js_elements[key].scrollLeft(
            ) + " = \"" + random.choice(FuzzValues.INTS) + "\";"
        elif method == 'scrollTop':
            code += self._js_elements[key].scrollTop(
            ) + " = \"" + random.choice(FuzzValues.INTS) + "\";"
        elif method == 'style':
            value = random.choice(CSS_STYLES)
            if "-" in value[0]:
                pos = value[0].find("-")
                value[0] = value[0].replace("-", "")
                value[0] = value[0][0:pos -
                                    1] + value[0][pos].upper() + value[0][pos +
                                                                          1:]
            code += self._js_elements[key].style(
            ) + "." + value[0] + " = \"" + random.choice(value[1:]) + "\";"
        elif method == 'tabIndex':
            code += self._js_elements[key].tabIndex() + " = " + str(
                random.randint(-20, 20)) + ";"
        elif method == 'textContent':
            code += self._js_elements[key].textContent(
            ) + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'title':
            code += self._js_elements[key].title() + " = \"" + random.choice(
                FuzzValues.STRINGS) + "\";"
        self._operations_count += 1
        if random.randint(1, 10000) < 50:
            code += "CollectGarbage();"
        return code

    def __build_array(self, length=0):
        array_id = "array_" + str(len(self._arrays.keys()))
        self._arrays[array_id] = []
        code = array_id + " = ["
        array_length = length if length != 0 else random.randint(
            1,
            len(self._js_elements.keys()) / 2)
        for i in range(array_length):
            element_to_add = random.choice(self._js_elements.keys())
            self._arrays[array_id].append(self._js_elements[element_to_add])
            code += element_to_add + ","
        code = code[:-1] + "];\n"
        return code

    def __create_for_loop(self):
        pass

    def __create_if_clause(self):
        pass

    def __concate_startup_list(self):
        code = ""
        for item in self._calls_in_startup[:-1]:
            if random.randint(0, 10) < 5:
                code += item + "\n"
            else:
                code += "\t" + JsWindow.setTimeout(item, self.TIMEOUT)
        return code
예제 #2
0
파일: javascript.py 프로젝트: h0wl/PyFuzz2
class JsDomFuzzer(Fuzzer):
    NAME = "js_dom_fuzzer"
    CONFIG_PARAMS = ["starting_elements", "total_operations", "browser", "seed", "canvas_size", "file_type"]
    CALLING_COMMENT = "//FUNCTION_CALLING"
    TIMEOUT = 20

    def __init__(self, starting_elements, total_operations, browser, seed, canvas_size, file_type='html'):
        self._starting_elements = int(starting_elements)
        self._total_operations = int(total_operations)
        self._browser = browser
        seed = int(seed)
        #  self._html_fuzzer = HtmlFuzzer(self._starting_elements, 3, seed)
        self._html_fuzzer = Html5Fuzzer(int(seed), self._starting_elements, 10, 5, file_type)
        self._css_fuzzer = CssFuzzer(seed)
        self._canvas_fuzzer = CanvasFuzzer(int(canvas_size))
        if seed == 0:
            random.seed()
        else:
            random.seed(seed)
        self._file_type = file_type
        self._function_count = 0
        self._operations_count = 0
        self._js_elements = {}
        """:type dict(JsElement)"""
        self._occurring_events = {}
        for event in DomObjectTypes.DOM_EVENTS:
            self._occurring_events[event] = 0
        self._html_page = None
        self._calls_in_startup = []
        # arrays dictionary layout: {'array_id': [JsObject, .... JsObject], ...}
        self._arrays = {}

    @classmethod
    def from_list(cls, params):
        return cls(params[0], params[1], params[2], params[3], params[4], params[5])

    @property
    def prng_state(self):
        return random.getstate()

    @property
    def file_type(self):
        return self._file_type

    def set_seed(self, seed=0):
        random.seed(seed)

    def __re_init(self):
        self._function_count = 0
        self._operations_count = 0
        self._function_count = 0
        self._operations_count = 0
        self._js_elements = {}
        self._calls_in_startup = []
        self._arrays = []
        self._occurring_events = {}
        for event in DomObjectTypes.DOM_EVENTS:
            self._occurring_events[event] = 0

    def create_testcases(self, count, directory):
        for i in range(count):
            test_name = "/test" + str(i) if i > 9 else "/test0" + str(i)
            with open(directory + test_name + "." + self._file_type, "wb+") as html_fd, open(directory + test_name + ".css", "wb+") as css_fd:
                html, css = self.fuzz()
                html = html.replace("TESTCASE", test_name)
                html_fd.write(html)
                css_fd.write(css)

    def fuzz(self):
        self._html_page = self._html_fuzzer.fuzz()
        html = self._html_page.get_raw_html()
        self._css_fuzzer.set_tags(self._html_page.get_elements_by_html_tag().keys())
        css = self._css_fuzzer.fuzz()
        js_code = ""
        js_code += self.__create_canvas_functions()
        js_code += self.__create_startup()
        while self._total_operations > self._operations_count:
            js_code += self.__add_function()
        js_code += self.__add_event_dispatcher()
        js_code += self.__create_event_handlers()
        js_code = js_code.replace(self.CALLING_COMMENT, self.__concate_startup_list())
        doc = html.replace("SCRIPT_BODY", js_code)
        self.__re_init()
        return doc, css

    def set_state(self, state):
        random.setstate(state)

    def __create_startup(self):
        code = "function startup() {\n"
        i = 0
        for elem_id in self._html_page.get_element_ids():
            code += "\t" + "elem" + str(i) + " = " + JsDocument.getElementById(elem_id) + "\n"
            self._js_elements["elem"+str(i)] = JsDomElement("elem" + str(i), self._html_page.get_element_by_id(elem_id))
            i += 1
        code += "\t" + self.CALLING_COMMENT + \
                "\n\tevent_firing();\n}\n"
        return code

    def __create_canvas_functions(self):
        code = ""
        for canvas_id in (self._html_page.get_elements_by_html_tag())['canvas']:
            self._calls_in_startup.append("\tfunc_" + canvas_id + "();")
            self._canvas_fuzzer.set_canvas_id(canvas_id)
            code += self._canvas_fuzzer.fuzz()
        return code

    def __add_function(self, func_name=None, event=False):
        if not func_name:
            func_name = "func_" + str(self._function_count) + "()"
        code = "function " + func_name + " {\n"
        func_count = random.randint(10, 50)
        for i in range(func_count):
            code += "\t" + JsGlobal.try_catch_block(self.__add_element_method())
        if not event:
            self._function_count += 1
            if random.randint(0, 10) <= 3:
                code += "\t" + JsWindow.setTimeout("func_" + str(self._function_count) + "()", self.TIMEOUT) + "\n"
            else:
                self._calls_in_startup.append("\tfunc_" + str(self._function_count) + "();")
        code += "}\n"
        return code

    def __create_event_handlers(self):
        code = ""
        for event in self._occurring_events:
            code += self.__add_function(event + "_handler" + "(event)", True)
        return code

    def __add_event_dispatcher(self):
        code = "function event_firing() {\n"
        for key in self._js_elements:
            for event in self._js_elements[key].registered_events.keys():
                if 'DOM' in event:
                    continue
                elif event == 'click':
                    code += JsGlobal.try_catch_block(self._js_elements[key].click() + "\n", "ex")
                elif event == 'error':
                    pass
                elif event == 'load':
                    pass
                elif event == 'scroll':
                    code += JsGlobal.try_catch_block(self._js_elements[key].scrollLeft() + " = 10;" + "\n", "ex")
                elif event == 'resize' or event == 'change':
                    code += JsGlobal.try_catch_block(self._js_elements[key].innerHtml() + " = \"" + "A" * 100 + "\";\n", "ex")
                elif event == 'focus' or event == 'focusin':
                    code += JsGlobal.try_catch_block(self._js_elements[key].focus() + "\n", "ex")
                elif event == 'blur':
                    code += JsGlobal.try_catch_block(self._js_elements[key].blur() + "\n", "ex")
                elif event == 'select':
                    code += JsGlobal.try_catch_block(self._js_elements[key].select() + "\n", "ex")
        code += "}\n"
        return code

    def __add__new_element(self):
        elem_name = "elem_cr" + str(len(self._js_elements))
        html_type = random.choice(HTML_OBJECTS)
        code = elem_name + " = " + JsDocument.createElement(html_type) + "\n"
        self._js_elements[elem_name] = JsDomElement(elem_name, html_type)
        return elem_name, code, html_type

    def __add_element_method(self, key=None):
        code = ""
        if not key:
            key = random.choice(self._js_elements.keys())
        method = random.choice(DomObjectTypes.DOM_ELEMENT_FUZZ_STUFF)
        if method == 'addEventListener':
            event = random.choice(DomObjectTypes.DOM_EVENTS)
            self._occurring_events[event] += 1
            code += self._js_elements[key].addEventListener(event, event + "_handler")
        elif method == 'appendChild':
            if random.randint(1, 100) < 80:
                child = random.choice(self._js_elements.keys())
                if child == key:
                    elem_name, add_code, html_type = self.__add__new_element()
                    code += add_code
                    self._js_elements[elem_name] = JsDomElement(elem_name, self._js_elements[key].html_type)
                    child = elem_name
                code += self._js_elements[key].appendChild(child)
            else:
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                self._js_elements[elem_name] = JsDomElement(elem_name, html_type)
                code += self._js_elements[key].appendChild(elem_name)
        elif method == 'cloneNode':
            length = len(self._js_elements)
            elem_name = "elem_cr" + str(length)
            code += elem_name + " = " + self._js_elements[key].cloneNode(True)
            self._js_elements[elem_name] = JsDomElement(elem_name, self._js_elements[key].html_type)
            self._js_elements[elem_name].set_children(self._js_elements[key].get_children())
        elif method == 'hasAttribute':
            code += self._js_elements[key].hasAttribute(random.choice(HTML_ATTR_GENERIC))
        elif method == 'hasChildNode':
            code += self._js_elements[key].hasChildNodes()
        elif method == 'insertBefore':
            if not self._js_elements[key].get_children():
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += "\t" + self._js_elements[key].appendChild(elem_name) + "\n"
            elem_name, add_code, html_type = self.__add__new_element()
            code += add_code
            code += self._js_elements[key].insertBefore(elem_name, random.choice(self._js_elements[key].get_children()))
        elif method == 'normalize':
            code += self._js_elements[key].normalize()
        elif method == 'removeAttribute':
            if not self._js_elements[key].attributes:
                code += self._js_elements[key].setAttribute(random.choice(HTML_ATTR_GENERIC),
                                                            random.choice(FuzzValues.INTERESTING_VALUES))
            else:
                code += self._js_elements[key].removeAttribute(random.choice(self._js_elements[key].attributes.keys()))
        elif method == 'removeChild':
            if not self._js_elements[key].get_children():
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].appendChild(elem_name)
            else:
                code += self._js_elements[key].removeChild(random.choice(self._js_elements[key].get_children()))
        elif method == 'replaceChild':
            if not self._js_elements[key].get_children():
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].appendChild(elem_name)
            else:
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].replaceChild(elem_name,
                                                            random.choice(self._js_elements[key].get_children()))
        elif method == 'removeEventListener':
            if not self._js_elements[key].registered_events:
                event = random.choice(DomObjectTypes.DOM_EVENTS)
                self._occurring_events[event] += 1
                code += self._js_elements[key].addEventListener(event, event + "_handler")
            else:
                event = random.choice(self._js_elements[key].registered_events.keys())
                self._occurring_events[event] -= 1
                event = random.choice(self._js_elements[key].registered_events.keys())
                code += self._js_elements[key].removeEventListener(event,
                                                                   self._js_elements[key].registered_events[event])
        elif method == 'setAttribute':
            attr = random.choice(HTML_ATTR_GENERIC)
            if attr == 'style':
                val = ""
                for i in range(1, 50):
                    css = random.choice(CSS_STYLES)
                    val += css[0] + ": " + random.choice(css[1:]) + "; "
            else:
                val = random.choice(FuzzValues.INTERESTING_VALUES)
            code += self._js_elements[key].setAttribute(attr, val)
        elif method == 'REPLACE_EXIST_ELEMENT':
            elem_name, add_code, html_type = self.__add__new_element()
            code += add_code
            code += "\t" + key + " = " + elem_name + ";"
            self._js_elements[key] = self._js_elements[elem_name]
        elif method == 'MIX_REFERENCES':
            code += self._js_elements[key]
        elif method == 'className':
            code += self._js_elements[key].className() + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'contentEditable':
            code += self._js_elements[key].contentEditable() + " = " + random.choice(FuzzValues.BOOL) + ";"
        elif method == 'dir':
            code += self._js_elements[key].dir() + " = \"" + random.choice(FuzzValues.TEXT_DIRECTION) + "\";"
        elif method == 'id':
            code += self._js_elements[key].id() + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'innerHTML':
            code += self._js_elements[key].innerHtml() + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'lang':
            code += self._js_elements[key].lang() + " = \"" + random.choice(FuzzValues.LANG_CODES) + "\";"
        elif method == 'scrollLeft':
            code += self._js_elements[key].scrollLeft() + " = \"" + random.choice(FuzzValues.INTS) + "\";"
        elif method == 'scrollTop':
            code += self._js_elements[key].scrollTop() + " = \"" + random.choice(FuzzValues.INTS) + "\";"
        elif method == 'style':
            value = random.choice(CSS_STYLES)
            if "-" in value[0]:
                pos = value[0].find("-")
                value[0] = value[0].replace("-", "")
                value[0] = value[0][0:pos-1] + value[0][pos].upper() + value[0][pos+1:]
            code += self._js_elements[key].style() + "." + value[0] + " = \"" + random.choice(value[1:]) + "\";"
        elif method == 'tabIndex':
            code += self._js_elements[key].tabIndex() + " = " + str(random.randint(-20, 20)) + ";"
        elif method == 'textContent':
            code += self._js_elements[key].textContent() + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'title':
            code += self._js_elements[key].title() + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        self._operations_count += 1
        if random.randint(1, 10000) < 50:
            code += "CollectGarbage();"
        return code

    def __build_array(self, length=0):
        array_id = "array_" + str(len(self._arrays.keys()))
        self._arrays[array_id] = []
        code = array_id + " = ["
        array_length = length if length != 0 else random.randint(1, len(self._js_elements.keys()) / 2)
        for i in range(array_length):
            element_to_add = random.choice(self._js_elements.keys())
            self._arrays[array_id].append(self._js_elements[element_to_add])
            code += element_to_add + ","
        code = code[:-1] + "];\n"
        return code

    def __create_for_loop(self):
        pass

    def __create_if_clause(self):
        pass

    def __concate_startup_list(self):
        code = ""
        for item in self._calls_in_startup[:-1]:
            if random.randint(0,10) < 5:
                code += item + "\n"
            else:
                code += "\t" + JsWindow.setTimeout(item, self.TIMEOUT)
        return code
예제 #3
0
class JsFuzzer(Fuzzer):
    NAME = "js_fuzzer"
    CONFIG_PARAMS = ['seed', 'starting_elements', 'html_depth', 'html_max_attr', 'canvas_size', 'js_block_size',
                     'function_count', 'file_type', 'media_folder']
    CALLING_COMMENT = "//CALLING COMMENT"
    FIRST_ARRAY_LENGTH = 5
    FUNCTION_TYPES = ['default', 'event', 'array']
    SPECIAL_PARAMETERS = ['JS_ARRAY', 'JS_DOM_CHILD_ELEMENT']

    def __init__(self, seed, starting_elements, html_depth, html_max_attr, canvas_size, js_block_size, function_count, file_type, media_folder="NONE"):
        self._logger = logging.getLogger(__name__)
        self._html_fuzzer = Html5Fuzzer(int(seed), int(starting_elements), int(html_depth), int(html_max_attr), file_type)
        self._canvas_fuzzer = CanvasFuzzer(int(canvas_size))
        self._css_fuzzer = CssFuzzer(int(seed))
        random.seed(int(seed)) if int(seed) != 0 else random.seed()
        self._size = int(js_block_size)
        self._function_count = int(function_count)
        self._file_type = file_type
        self._js_objects = {}
        self._media_folder = media_folder
        self.__init_js_object_dict()
        self._js_default_functions = []
        self._js_event_listener = []
        self._js_array_functions = []
        max_funcs = min((self._size / 10), 20)
        for i in range(max_funcs):
            self._js_array_functions.append("array_func_" + str(i))
            self._js_event_listener.append("event_handler_" + str(i))
        self._html_page = HtmlPage()

    def __init_js_object_dict(self):
        for js_obj_type in JS_OBJECTS:
            self._js_objects[js_obj_type] = []

    @property
    def file_type(self):
        return self._file_type

    @classmethod
    def from_list(cls, params):
        return cls(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7], params[8])

    @property
    def prng_state(self):
        return random.getstate

    def set_state(self, state):
        random.setstate(state)

    def create_testcases(self, count, directory):
        self.clear_folder(directory)
        media_file_names = []
        byte_mutation_fuzzers = []
        if self._media_folder is not "NONE":
            media_folder_listing = os.listdir(self._media_folder)
            for i in range(8):
                file_name = random.choice(media_folder_listing)
                media_file_names.append(file_name)
                byte_mutation_fuzzers.append(ByteMutation(self._media_folder + "/" + file_name, 5, 50, 0, file_name.split(".")[1]))
        for i in range(count):
            test_name = "/test" + str(i) if i > 9 else "/test0" + str(i)
            fuzzer_number = 0
            for byte_mutation_fuzzer in byte_mutation_fuzzers:
                fuzz_data_file_name = test_name + "_" + str(fuzzer_number) + "." + byte_mutation_fuzzer.file_type
                fuzz_data = byte_mutation_fuzzer.fuzz()
                with open(directory + fuzz_data_file_name, 'wb+') as data_fd:
                    data_fd.write(fuzz_data)
                self._html_fuzzer.add_embed_source(fuzz_data_file_name.replace("/", ""))
                fuzzer_number += 1
            with open(directory + test_name + "." + self._file_type, "wb+") as html_fd, open(directory + test_name + ".css", "wb+") as css_fd:
                html, css = self.fuzz()
                html = html.replace("TESTCASE", test_name)
                html_fd.write(html)
                css_fd.write(css)
            self._html_fuzzer.embed_sources_list = []

    def set_seed(self, seed):
        pass

    def __reinit(self):
        self._js_objects = {}
        self.__init_js_object_dict()
        self._js_default_functions = []

    def fuzz(self):
        self._html_page = self._html_fuzzer.fuzz()
        tags = self._html_page.get_elements_by_html_tag().keys()
        css_class_names = self._html_page.get_css_class_names()
        self._css_fuzzer.set_options(tags, css_class_names)
        css = self._css_fuzzer.fuzz()
        code = ""
        code += self.__init_js_objects(self._html_page)
        i = 0
        func_size = self._size / self._function_count
        while i < self._size:
            code += self.__build_function("default", func_size)
            i += func_size
        for func_name in self._js_event_listener:
            code += self.__build_function("event", func_size, func_name)
        for func_name in self._js_array_functions:
            code += self.__build_function("array", func_size, func_name)
        code += self.__add_event_dispatcher()
        for canvas_id in self._html_page.get_elements_by_html_tag()['canvas']:
            self._canvas_fuzzer.set_canvas_id(canvas_id)
            self._js_default_functions.append("func_" + canvas_id)
            code += self._canvas_fuzzer.fuzz()
        call_block = ""
        for func_name in self._js_default_functions:
            choice = random.randint(1, 20)
            if choice < 15:
                call_block += "\t" + func_name + "();\n"
            else:
                call_block += "\t" + JsWindow.setTimeout(func_name + "();", 100) + "\n"
        call_block += "\t" + "event_firing();\n"
        call_block += "\t" + "location.reload();\n"
        code = code.replace(self.CALLING_COMMENT, call_block)
        html = self._html_page.get_raw_html()
        html = html.replace("SCRIPT_BODY", code)
        self.__reinit()
        return html, css

    def test(self):
        self._html_page = self._html_fuzzer.fuzz()
        tags = self._html_page.get_elements_by_html_tag().keys()
        css_class_names = self._html_page.get_css_class_names()
        self._css_fuzzer.set_options(tags, css_class_names)
        css = self._css_fuzzer.fuzz()
        code = ""
        code += self.__init_js_objects(self._html_page)
        for i in range(30):
            code += self.__build_assignment2() + "\n"
        return code

    def __init_js_objects(self, html_page):
        available_dom_elements = html_page.get_elements_by_id()
        code = "function startup() {\n"
        for element_id in available_dom_elements.keys():
            code += "\telem_" + element_id + " = " + JsDocument.getElementById(element_id) + ";\n"
            self._js_objects['JS_DOM_ELEMENT'].append(JsDomElement("elem_" + element_id,
                                                                   available_dom_elements[element_id]))
        #  Init a Object of each type
        for i in range(0, 5):
            code += "\t" + self.__build_js_array(self.FIRST_ARRAY_LENGTH)
            code += "\t" + self.__add_js_string()
            code += "\t" + self.__add_js_number()
            code += "\t" + self.__add_js_object()
        code += self.CALLING_COMMENT + "\n"
        code += "}\n"
        return code

    # region Little Helper
    def __build_js_array(self, length):
        array_obj_list = []
        for i in range(length):
            js_obj = self.__get_an_js_object()
            array_obj_list.append(js_obj)
        js_array = JsArray(self.__get_js_array_name(), array_obj_list)
        self._js_objects['JS_ARRAY'].append(js_array)
        return js_array.newArray() + ";\n"

    def __add_js_string(self):
        js_str = JsString(self.__get_js_string_name())
        self._js_objects['JS_STRING'].append(js_str)
        return js_str.newString(random.choice(FuzzValues.STRINGS)) + ";\n"

    def __add_js_number(self):
        js_number = JsNumber(self.__get_js_number_name())
        self._js_objects['JS_NUMBER'].append(js_number)
        return js_number.newNumber(random.choice(FuzzValues.INTS)) + ";\n"

    def __add_js_dom_element(self):
        var_name = "elem_" + str(len(self._js_objects['JS_DOM_ELEMENT']))
        html_type = random.choice(HTML5_OBJECTS.keys())
        js_dom_element = JsDomElement(var_name, html_type)
        self._js_objects['JS_DOM_ELEMENT'].append(js_dom_element)
        return var_name + " = " + JsDocument.createElement(html_type) + ";\n"

    def __add_js_object(self):
        var_name = self.__get_js_object_name()
        self._js_objects['JS_OBJECT'].append(JsObject(var_name))
        available_types = self._js_objects.keys()
        available_types.remove('JS_OBJECT')
        js_obj_type = random.choice(available_types)
        return var_name + " = " + (random.choice(self._js_objects[js_obj_type])).name + ";\n"

    def __get_js_dom_element_name(self):
        return "elem_" + str(len(self._js_objects['JS_DOM_ELEMENT']))

    def __get_js_string_name(self):
        return "str_" + str(len((self._js_objects['JS_STRING'])))

    def __get_js_number_name(self):
        return "number_" + str(len(self._js_objects['JS_NUMBER']))

    def __get_js_array_name(self):
        return "array_" + str(len(self._js_objects['JS_ARRAY']))

    def __get_js_object_name(self):
        return "object_" + str(len(self._js_objects['JS_OBJECT']))

    def __get_an_js_object(self):
        usable_object = self._js_objects.keys()
        usable_object.remove('JS_OBJECT')
        js_obj_type = 'JS_STRING' # random.choice(usable_object)
        while not self._js_objects[js_obj_type]:
            js_obj_type = random.choice(self._js_objects.keys())
        js_obj = random.choice(self._js_objects[js_obj_type])
        return js_obj

    @staticmethod
    def __check_params_for_optional(parameter_list):
        for param in parameter_list:
            if "*" in param:
                return True
        return False
    # endregion

    def __build_function(self, func_type, length, func_name=None):
        code = ""
        func_end = ""
        block_length = length / 10
        if func_type == 'default':
            func_name = "func_" + str(len(self._js_default_functions))
            self._js_default_functions.append(func_name)
            code += "function " + func_name + "() { \n"
            func_end = "}\n"
        elif func_type == "array" or "event":
            code += "function " + func_name + "(x) { \n"
            func_end = "\treturn x;\n}\n" if func_type == "array" else "}\n"
        for i in range(length):
            choice = random.randint(1, 20)
            if choice <= 10:
                code += "\t" + self.__build_assignment()
            elif 10 < choice < 15:
                code += self.__build_if_statement_block(block_length)
                i += block_length
            elif choice > 15:
                code += self.__build_for_loop_block(block_length)
                i += block_length
        code += func_end
        return code

    def __build_if_statement_block(self, length):
        code = "\tif " + self.__create_bool_expression() + "{ \n"
        for i in range(length):
            code += "\t\t" + self.__build_assignment(False)
        code += "\t}\n"
        return "\t" + JsGlobal.try_catch_block("\n" + code)

    #  TODO: iterate over the array
    def __build_for_loop_block(self, length):
        code = "\tfor (var i = 0; i < " + (random.choice(self._js_objects['JS_ARRAY'])).length() + ";i++) {\n"
        for i in range(length):
            code += "\t\t" + self.__build_assignment(False)
        code += "\t}\n"
        return "\t" + JsGlobal.try_catch_block("\n" + code)

    #  TODO: build assignments but keep the JsArray Objects functional (array elements)
    #  TODO: also keep the JsDomElement functional (children and so on)
    def __build_assignment2(self, try_catch=True):
        code = ""
        choice = random.randint(1, 20)
        js_obj = self.__get_an_js_object()
        js_method_name = random.choice(js_obj.methods_and_properties.keys())
        js_obj_method = js_obj.methods_and_properties[js_method_name]['method']
        js_method_ret_val = js_obj.methods_and_properties[js_method_name]['ret_val']
        js_method_parameters = js_obj.methods_and_properties[js_method_name]['parameters']
        special_param = (False, None)
        star_param = False
        if js_method_parameters is not None:
            for param in js_method_parameters:
                if param in self.SPECIAL_PARAMETERS:
                    special_param = (True, param)
                elif '*' in param:
                    star_param = True
        # region Default assignment
        if ((star_param and choice <= 10) or (not star_param)) and not special_param[0]:
            #  TODO: going deeper,
            #  TODO: e.g for strings call a method on a method call on method call and add it inside or outside
            if js_method_parameters is None or star_param:
                code += js_obj_method()
            else:
                parameters = self.__get_params(js_obj, js_method_parameters)
                code += js_obj_method(*parameters)
            js_method_ret_val = 'JS_NUMBER' if js_method_ret_val == "INT" or js_method_ret_val == "FLOAT" else js_method_ret_val
            if js_method_ret_val == "JS_DOM_ELEMENT":
                new_js_obj = JsDomElement(self.__get_js_dom_element_name()) if choice < 10 else random.choice(self._js_objects['JS_DOM_ELEMENT'])
            # region JS_STRING
            elif js_method_ret_val == "JS_STRING":
                new_js_obj = JsString(self.__get_js_string_name()) if choice < 10 else random.choice(self._js_objects['JS_STRING'])
                if choice > 15:
                    add_js_str_obj = random.choice(self._js_objects['JS_STRING'])
                    second_obj_code = add_js_str_obj.name
                    for i in range(choice % 10):
                        js_str_func = random.choice(js_obj.methods_and_properties_by_return_type['JS_STRING'])
                        add_js_str_func = random.choice(add_js_str_obj.methods_and_properties_by_return_type['JS_STRING'])
                        if js_str_func['parameters'] is not None and \
                                not self.__check_params_for_optional(js_str_func['parameters']):
                            js_str_func_parameters = self.__get_params(js_obj, js_str_func['parameters'])
                            code = "(" + code + ")" + (js_str_func['method'](*js_str_func_parameters)).replace(js_obj.name, "")
                        else:
                            code = "(" + code + ")" + (js_str_func['method']()).replace(js_obj.name, "")
                        if add_js_str_func['parameters'] is not None and \
                                not self.__check_params_for_optional(add_js_str_func['parameters']):
                            add_js_str_func_parameters = self.__get_params(js_obj, add_js_str_func['parameters'])
                            second_obj_code = "(" + second_obj_code + ")" + (add_js_str_func['method'](*add_js_str_func_parameters)).replace(add_js_str_obj.name, "")
                        else:
                            second_obj_code = "(" + second_obj_code + ")" + (add_js_str_func['method']()).replace(add_js_str_obj.name, "")
                    code = code + " + " + second_obj_code
            # endregion
            elif js_method_ret_val == "JS_NUMBER":
                new_js_obj = JsNumber(self.__get_js_number_name()) if choice < 10 else random.choice(self._js_objects['JS_NUMBER'])
                pass
            elif js_method_ret_val == "JS_ARRAY":
                new_js_obj = JsArray(self.__get_js_array_name()) if choice < 10 else random.choice(self._js_objects['JS_ARRAY'])
                pass
            else:  # it's a js_object
                new_js_obj = JsObject(self.__get_js_object_name()) if choice < 10 else random.choice(self._js_objects['JS_OBJECT'])
                pass
            code = new_js_obj.name + " = " + code
        #  endregion
        # region properties setting
        elif star_param and choice > 10:
            print("Star param")
            parameters = self.__get_params(js_obj, js_method_parameters)
            code = js_obj_method(*parameters)
        # endregion
        # region JS_ARRAY or JS_DOM_CHILD_ELEMENT
        elif special_param[0]:
            print("Special param")
            pass
        # endregion
        return code

    def __build_assignment(self, try_catch=True):
        choice = random.randint(1, 20)
        js_obj = self.__get_an_js_object()
        js_function_name = random.choice(js_obj.methods_and_properties.keys())
        if js_function_name == "removeChild" or js_function_name == "replaceChild":
            children = js_obj.get_children()
            if not children:
                js_function_name = "appendChild"
        js_obj_function = js_obj.methods_and_properties[js_function_name]
        parameters = js_obj_function['parameters']
        ret_val = js_obj_function['ret_val']
        optional = False
        if parameters is not None:
            for params in parameters:
                if "*" in params:
                    if choice > 8:
                        parameters = None
                    else:
                        optional = True
        if parameters is not None:
            params = self.__get_params(js_obj, js_obj_function['parameters'])
            code = js_obj_function['method'](*params)
        else:
            code = js_obj_function['method']()
        #  TODO: how to involve operators in numbers and strings ...
        if not optional:
            ret_val = "JS_STRING" if ret_val == "STRING" else ret_val
            ret_val = "JS_NUMBER" if ret_val == "INT" or ret_val == "EXP_FLOAT" or ret_val == "FLOAT" else ret_val
            if ret_val == "JS_DOM_ELEMENT":
                new_js_obj = JsDomElement(self.__get_js_dom_element_name()) if choice < 10 else random.choice(self._js_objects['JS_DOM_ELEMENT'])
                self._js_objects['JS_DOM_ELEMENT'].append(new_js_obj)
            elif ret_val == "JS_STRING":
                new_js_obj = JsString(self.__get_js_string_name()) if choice < 10 else random.choice(self._js_objects['JS_STRING'])
                self._js_objects['JS_STRING'].append(new_js_obj)
                if choice >= 15:
                    js_str = random.choice(self._js_objects['JS_STRING'])
                    js_str_func = random.choice(js_str.methods_and_properties_by_return_type['JS_STRING'])
                    js_str_func_params = self.__get_params(js_str, js_str_func['parameters']) if js_str_func['parameters'] is not None else None
                    code += " + " + js_str_func['method'](*js_str_func_params) if js_str_func['parameters'] is not None else " + " + js_str_func['method']()
            elif ret_val == "JS_NUMBER":
                new_js_obj = JsNumber(self.__get_js_number_name()) if choice < 10 else random.choice(self._js_objects['JS_NUMBER'])
                self._js_objects['JS_NUMBER'].append(new_js_obj)
                if choice >= 15:
                    number_operator = random.choice(JsNumber.OPERATORS)
                    js_number = random.choice(self._js_objects['JS_NUMBER'])
                    code += " " + number_operator + " " + js_number.name
            elif ret_val == "JS_ARRAY":
                new_js_obj = JsArray(self.__get_js_array_name()) if choice < 10 else random.choice(self._js_objects['JS_ARRAY'])
                self._js_objects['JS_ARRAY'].append(new_js_obj)
            else:
                new_js_obj = JsObject(self.__get_js_object_name()) if choice < 10 else random.choice(self._js_objects['JS_OBJECT'])
                self._js_objects['JS_OBJECT'].append(new_js_obj)
            code = new_js_obj.name + " = " + code
        return JsGlobal.try_catch_block(code + "; ") if try_catch else code + ";\n"

    def __get_params(self, calling_obj, param_list):
        ret_params = []
        for param in param_list:
            if param == 'BOOL':
                switch = random.choice([0, 1])
                if switch == 0:
                    ret_params.append(self.__create_bool_expression())
                elif switch == 1:
                    ret_params.append(random.choice(FuzzValues.BOOL))
            elif param == 'CLASS_NAME':
                ret_params.append(random.choice(self._html_page.get_css_class_names()))
            elif param == 'CSS_SELECTOR':  # Build a tag, tag, tag style selector
                # TODO: Work through the CSS Selector reference
                count = random.randint(1, 10)
                css_selector = ""
                for i in range(count):
                    css_selector += random.choice(self._html_page.get_elements_by_html_tag().keys()) + ","
                css_selector = css_selector[:-1]  # remove the comma
                ret_params.append(random.choice(css_selector))
            elif param == 'CSS_STYLE':
                style = random.choice(CSS_STYLES)
                ret_params.append(style[0])
                ret_params.append(random.choice(style[1:]))
            elif param == 'EVENT':
                ret_params.append(random.choice(DomObjectTypes.DOM_EVENTS))
            elif param == 'HTML_ATTR':
                html_attr = random.choice(HTML5_GLOBAL_ATTR.keys())
                ret_params.append(html_attr)
                if 'HTML_ATTR_VAL' in param_list:
                    if HTML5_GLOBAL_ATTR[html_attr] == "CSS_CLASS":
                        ret_params.append(random.choice(self._html_page.get_css_class_names()))
                    elif html_attr == "style":
                        style = random.choice(CSS_STYLES)
                        ret_params.append(style[0] + " " + random.choice(style[1:]))
                    else:
                        ret_params.append(random.choice(Html5Fuzzer.TYPES_DICT[HTML5_GLOBAL_ATTR[html_attr]]))
            elif param == 'HTML_ATTR_VAL':
                continue
            elif param == 'HTML_CODE':
                count = random.randint(1, 10)
                ret_params.append(self._html_fuzzer.get_some_html_code(count))
            elif param == 'HTML_TAG':
                ret_params.append(random.choice(HTML5_OBJECTS.keys()))
            elif param == 'INT':
                switch = random.choice([0, 1])
                if switch == 1:  # Get a JS_Number ID
                    ret_params.append((random.choice(self._js_objects['JS_NUMBER'])).name)
                else:  # Get one from FuzzValues
                    ret_params.append(random.choice(FuzzValues.PURE_INTS))
            elif param == 'JS_ARRAY':
                ret_params.append(random.choice(self._js_objects['JS_ARRAY']))
            elif param == 'JS_DOM_ELEMENT':
                ret_params.append((random.choice(self._js_objects['JS_DOM_ELEMENT'])).name)
            elif param == 'JS_DOM_CHILD_ELEMENT':
                if not calling_obj.get_children():
                    ret_params.append((random.choice(self._js_objects['JS_DOM_ELEMENT'])).name)
                else:
                    ret_params.append(random.choice(calling_obj.get_children()))
            elif param == 'JS_EVENT_LISTENER':
                ret_params.append(random.choice(self._js_event_listener))
            elif param == 'JS_ARRAY_FUNCTION':
                ret_params.append(random.choice(self._js_array_functions))
            elif param == 'JS_OBJECT':
                obj_type = random.choice(self._js_objects.keys())
                ret_params.append((random.choice(self._js_objects[obj_type])).name)
            elif param == 'LANG':
                ret_params.append(random.choice(FuzzValues.LANG_CODES))
            elif param == 'NAMESPACE_URI':
                # TODO: think about namespace URIs
                ret_params.append("localhost")
            elif param == 'NUMBER':
                ret_params.append(random.choice(FuzzValues.INTS))
            elif param == 'REGEX':
                # TODO: Build a regex builder method
                ret_params.append("g/[*]+/")
            elif param == 'JS_STRING':
                switch = random.choice([0, 1])
                if switch == 0:
                    ret_params.append((random.choice(self._js_objects['JS_STRING'])).name)
                else:
                    ret_params.append(random.choice(FuzzValues.STRINGS))
            elif param == 'TEXT_DIRECTION':
                ret_params.append(random.choice(FuzzValues.TEXT_DIRECTION))
            elif param == 'UNICODE_VALUE_LIST':
                value = random.randint(0x0000, 0xFFFF)
                ret_params.append(format(value, '04x'))
        return ret_params

    def __create_bool_expression(self):
        code = "("
        operator = random.choice(JsGlobal.BOOL_OPERATORS)
        operand_type = random.choice(self._js_objects.keys())
        operand1 = random.choice(self._js_objects[operand_type])
        operand2 = random.choice(self._js_objects[operand_type])
        same_ret_val = [x for x in operand1.methods_and_properties_by_return_type.keys() if x in operand2.methods_and_properties_by_return_type.keys()]
        ret_val = random.choice(same_ret_val)
        operand1_func = random.choice(operand1.methods_and_properties_by_return_type[ret_val])
        operand2_func = random.choice(operand2.methods_and_properties_by_return_type[ret_val])
        operand1_param = self.__get_params(operand1, operand1_func['parameters']) if operand1_func['parameters'] is not None and '*' not in ("" + x for x in operand1_func['parameters']) else None
        operand2_param = self.__get_params(operand2, operand2_func['parameters']) if operand2_func['parameters'] is not None and '*' not in ("" + x for x in operand2_func['parameters'])else None
        code += operand1_func['method'](*operand1_param) if operand1_param is not None else operand1_func['method']()
        code += operator
        code += operand2_func['method'](*operand2_param) if operand2_param is not None else operand2_func['method']()
        code += ")"
        return code

    def __add_event_dispatcher(self):
        code = "function event_firing() {\n"
        for elem in self._js_objects['JS_DOM_ELEMENT']:
            for event in elem.registered_events.keys():
                if 'DOM' in event:
                    continue
                elif event == 'click':
                    code += JsGlobal.try_catch_block(elem.click() + "\n", "ex")
                elif event == 'error':
                    pass
                elif event == 'load':
                    pass
                elif event == 'scroll':
                    code += JsGlobal.try_catch_block(elem.scrollLeft() + " = 10;" + "\n", "ex")
                elif event == 'resize' or event == 'change':
                    code += JsGlobal.try_catch_block(elem.innerHtml() + " = \"" + "A" * 100 + "\";\n", "ex")
                elif event == 'focus' or event == 'focusin':
                    code += JsGlobal.try_catch_block(elem.focus() + "\n", "ex")
                elif event == 'blur':
                    code += JsGlobal.try_catch_block(elem.blur() + "\n", "ex")
                elif event == 'select':
                    code += JsGlobal.try_catch_block(elem.select() + "\n", "ex")
        code += "}\n"
        return code