Esempio n. 1
0
  def initUI(self):
    p = Panel(self)

    self._target_notebook = nb(p)
    self.build_target_notebook(self._target_notebook)

    self.main_notebook = nb(p)
    page1 = self.build_page1(self.main_notebook)
    page2 = self.build_page2(self.main_notebook)
    page3 = self.build_page3(self.main_notebook)
    page4 = self.build_page4(self.main_notebook)
    page5 = self.build_page5(self.main_notebook)
    page6 = self.build_page6(self.main_notebook)

    self.main_notebook.AddPage(page1, '选项区(1)')
    self.main_notebook.AddPage(page2, '输出区(2)')
    self.main_notebook.AddPage(page3, '日志区(3)')
    self.main_notebook.AddPage(page4, 'API区(4)')
    self.main_notebook.AddPage(page5, '帮助(H)')
    self.main_notebook.AddPage(page6, '关于')

    vbox = BoxSizer(VERTICAL)
    vbox.Add(self._target_notebook, flag = EXPAND)
    vbox.Add(self.main_notebook, proportion = 1, flag = EXPAND)
    p.SetSizer(vbox)

    _frame_sz = BoxSizer()
    _frame_sz.Add(p, proportion = 1, flag = EXPAND)
    # 使用SetSizerAndFit方法使frame拥有最小size
    self.SetSizerAndFit(_frame_sz)
Esempio n. 2
0
  def build_page6(self, parent):
    p = Panel(parent)

    _version = '0.3.3.1'
    _timestamp = '2021-01-31 05:12:52'

    _url_self = 'https://github.com/needle-wang/sqlmap-wx'
    _url_tutorial1 = 'https://wiki.wxpython.org/'
    _url_tutorial2 = 'http://zetcode.com/wxpython/'
    _url_api = 'https://wxpython.org/Phoenix/docs/html/index.html'
    _url_idea = 'https://github.com/kxcode'
    _about_str = f'''
    1. Website: {_url_self}
       VERSION: {_version}
       {_timestamp}
       required: python3.6+, wxPython4.0+,
                 requests, sqlmap\n
    2. use wxPython4 to recode sqlmap-gtk(driven by PyGObject)
    3. thanks to the idea from sqm(by python2 + tkinter),
                 author: KINGX, {_url_idea}\n
    4. wxPython tutorial: {_url_tutorial1}
                          {_url_tutorial2}
    5. wxPython API: {_url_api}
    '''
    hbox = BoxSizer()
    _page6_about = st(p, label = _about_str)
    # 完全居中!
    hbox.Add(_page6_about, flag = ALIGN_CENTER)

    vbox = BoxSizer(VERTICAL)
    vbox.Add(hbox, proportion = 1, flag = ALIGN_CENTER)
    p.SetSizerAndFit(vbox)
    return p
Esempio n. 3
0
  def build_page3(self, parent):
    p = Panel(parent)
    m = self.m

    # 多行文本框的默认size太小了
    # 默认高度太低, 不指定个高度, 会报 滚动条相关的size 警告
    m._page3_log_view.Create(p,
                             size = (-1, 300),
                             style = wx.TE_MULTILINE | wx.TE_READONLY)
    self._handlers.clear_log_view_buffer(None)

    grid = GridSizer(1, 3, 0, 0)
    m._page3_read_target_btn.Create(p, label = '查看target文件')
    m._page3_clear_btn.Create(p, label = '清空(&C)')
    m._page3_read_log_btn.Create(p, label = '查看log文件')

    m._page3_read_target_btn.Bind(EVT_BUTTON, self._handlers.read_target_file)
    m._page3_clear_btn.Bind(EVT_BUTTON, self._handlers.clear_log_view_buffer)
    m._page3_read_log_btn.Bind(EVT_BUTTON, self._handlers.read_log_file)

    grid.Add(m._page3_read_target_btn, flag = ALIGN_CENTER)
    grid.Add(m._page3_clear_btn, flag = ALIGN_CENTER)
    grid.Add(m._page3_read_log_btn, flag = ALIGN_CENTER)

    vbox = BoxSizer(VERTICAL)
    vbox.Add(m._page3_log_view, proportion = 1, flag = EXPAND | ALL, border = 10)
    vbox.Add(grid, flag = EXPAND)
    p.SetSizerAndFit(vbox)
    return p
Esempio n. 4
0
    def _file_write(self):
        sbSizer = StaticBoxSizer(self.m._file_write_area, VERTICAL)

        border = SizerFlags().Expand().Border(LEFT | RIGHT, 5)
        proportion_border = SizerFlags(1).Border(LEFT | RIGHT, 5)

        row1 = BoxSizer()
        row2 = BoxSizer()
        row3 = BoxSizer()
        row1.Add(self.m._file_write_area_udf_ckbtn, border)
        row1.Add(self.m._file_write_area_shared_lib_ckbtn, border)
        row1.Add(self.m._file_write_area_shared_lib_entry,
                 proportion=1,
                 flag=EXPAND)
        row1.Add(self.m._file_write_area_shared_lib_chooser, border)
        row2.Add(self.m._file_write_area_file_write_ckbtn, border)
        row2.Add(self.m._file_write_area_file_write_entry,
                 proportion=1,
                 flag=EXPAND)
        row2.Add(self.m._file_write_area_file_write_chooser, border)
        row3.Add(self.m._file_write_area_file_dest_ckbtn, border)
        row3.Add(self.m._file_write_area_file_dest_entry, proportion_border)

        spacing = SizerFlags().Expand().Border(TOP | BOTTOM, 3)
        sbSizer.Add(row1, spacing)
        sbSizer.Add(row2, spacing)
        sbSizer.Add(row3, spacing)
        return sbSizer
Esempio n. 5
0
    def other_sizer(self):
        vbox = BoxSizer(VERTICAL)

        page1_other_general_area = self._other_general()
        page1_other_misc_area = self._other_misc()

        expand_border = SizerFlags().Expand().Border(LEFT | RIGHT, 5)

        vbox.Add(page1_other_general_area, expand_border)
        vbox.Add(page1_other_misc_area, expand_border)
        return vbox
Esempio n. 6
0
    def _enumeration_dump(self):
        sbSizer = StaticBoxSizer(self.m._dump_area, VERTICAL)

        spacing = SizerFlags().Expand().Border(LEFT | RIGHT, 10)
        sbSizer.Add(self.m._dump_area_dump_ckbtn, spacing)
        sbSizer.Add(self.m._dump_area_repair_ckbtn, spacing)
        sbSizer.Add(self.m._dump_area_statements_ckbtn, spacing)
        _ = BoxSizer()
        _.Add(self.m._dump_area_search_ckbtn)
        _.Add(self.m._dump_area_no_sys_db_ckbtn, spacing)
        sbSizer.Add(_, spacing)
        sbSizer.Add(self.m._dump_area_dump_all_ckbtn, spacing)
        return sbSizer
Esempio n. 7
0
    def _file_read(self):
        sbSizer = StaticBoxSizer(self.m._file_read_area, VERTICAL)

        border = SizerFlags().Expand().Border(LEFT | RIGHT, 5)

        row1 = BoxSizer()
        row1.Add(self.m._file_read_area_file_read_ckbtn, border)
        row1.Add(self.m._file_read_area_file_read_entry, proportion=1)
        row1.Add(self.m._file_read_area_file_read_btn, border)

        spacing = SizerFlags().Expand().Border(TOP | BOTTOM, 3)
        sbSizer.Add(row1, spacing)

        return sbSizer
Esempio n. 8
0
    def _setting_offen(self):
        sbSizer = StaticBoxSizer(self.m._offen_area, VERTICAL)

        row1 = BoxSizer()
        row1.Add(self.m._general_area_verbose_ckbtn, flag=EXPAND)
        row1.Add(self.m._general_area_verbose_scale, proportion=1)

        spacing = SizerFlags().Expand().Border(ALL, 3)

        sbSizer.Add(row1, spacing)
        sbSizer.Add(self.m._general_area_finger_ckbtn, spacing)
        sbSizer.Add(self.m._general_area_hex_ckbtn, spacing)
        sbSizer.Add(self.m._general_area_batch_ckbtn, spacing)
        sbSizer.Add(self.m._misc_area_wizard_ckbtn, spacing)
        return sbSizer
Esempio n. 9
0
    def file_sizer(self):
        vbox = BoxSizer(VERTICAL)

        file_read_area = self._file_read()
        file_write_area = self._file_write()
        file_os_access_area = self._file_os_access()
        file_registry_area = self._file_registry()

        spacing = SizerFlags().Expand().Border(TOP | LEFT | RIGHT, 5)
        vbox.Add(self.nb._page1_file_note_label, spacing)
        vbox.Add(file_read_area, spacing)
        vbox.Add(file_write_area, spacing)
        vbox.Add(file_os_access_area, spacing)
        vbox.Add(file_registry_area, spacing)

        return vbox
Esempio n. 10
0
    def _enumeration_brute_force(self):
        sbSizer = StaticBoxSizer(self.m._brute_force_area, VERTICAL)

        border = SizerFlags().Expand().Border(LEFT | RIGHT, 6)

        row1 = BoxSizer()
        row1.Add(self.nb._brute_force_area_label,
                 flag=ALIGN_CENTER | LEFT,
                 border=6)
        row1.Add(self.m._brute_force_area_common_tables_ckbtn, border)
        row1.Add(self.m._brute_force_area_common_columns_ckbtn, border)
        row1.Add(self.m._brute_force_area_common_files_ckbtn, border)

        sbSizer.Add(row1, flag=EXPAND | ALL, border=6)

        return sbSizer
Esempio n. 11
0
    def _setting_optimize(self):
        sbSizer = StaticBoxSizer(self.m._optimize_area, VERTICAL)

        row2 = BoxSizer()
        row2.Add(self.m._optimize_area_thread_num_ckbtn, flag=EXPAND)
        row2.Add(self.m._optimize_area_thread_num_spinbtn,
                 proportion=1,
                 flag=RIGHT,
                 border=10)

        spacing = SizerFlags().Expand().Border(ALL, 3)
        sbSizer.Add(self.m._optimize_area_turn_all_ckbtn, spacing)
        sbSizer.Add(row2, spacing)
        sbSizer.Add(self.m._optimize_area_predict_ckbtn, spacing)
        sbSizer.Add(self.m._optimize_area_keep_alive_ckbtn, spacing)
        sbSizer.Add(self.m._optimize_area_null_connect_ckbtn, spacing)
        return sbSizer
Esempio n. 12
0
    def request_sizer(self):
        vbox = BoxSizer(VERTICAL)

        proportion_border = SizerFlags(1).Expand().Border(RIGHT, 20)
        # 本来没必要加行的, 为了让win下的滚动条不致于掩盖末端内容~~
        row1 = BoxSizer()
        request_header_area = self._request_header()
        row1.Add(request_header_area, proportion_border)

        row2 = BoxSizer()
        request_data_area = self._request_data()
        row2.Add(request_data_area, proportion_border)

        row3 = BoxSizer()
        request_custom_area = self._request_custom()
        row3.Add(request_custom_area, proportion_border)

        row4 = BoxSizer()
        request_proxy_area = self._request_proxy()
        row4.Add(request_proxy_area, proportion_border)

        spacing = SizerFlags().Expand().Border(LEFT | RIGHT | TOP, 5)
        vbox.Add(row1, spacing)
        vbox.Add(row2, spacing)
        vbox.Add(row3, spacing)
        vbox.Add(row4, spacing)
        return vbox
Esempio n. 13
0
  def build_page1(self, parent):
    p = Panel(parent)
    m = self.m

    # sqlmap命令语句
    cmd_area = StaticBoxSizer(VERTICAL, p, 'A.收集选项 的结果显示在这:')
    _cmd_area = cmd_area.GetStaticBox()

    m._cmd_entry.Create(_cmd_area)

    cmd_area.Add(m._cmd_entry, flag = EXPAND)

    # 主构造区
    self._notebook = Notebook(p, m, self._handlers)

    # 构造与执行
    self.btn_grid = GridSizer(1, 4, 0, 0)

    _build_button = btn(p, label = 'A.收集选项(A)')
    _unselect_all_btn = btn(p, label = '反选所有复选框(S)')
    _clear_all_entry = btn(p, label = '清空所有输入框(D)')

    _build_button.Bind(EVT_BUTTON, self._handlers.build_all)
    _unselect_all_btn.Bind(EVT_BUTTON, self.unselect_all_ckbtn)
    _clear_all_entry.Bind(EVT_BUTTON, self.clear_all_entry)

    _run_button = btn(p, label = 'B.开始(F)')
    _run_button.Bind(EVT_BUTTON, self._handlers.run_cmdline)

    self.btn_grid.Add(_build_button, flag = ALIGN_CENTER)
    self.btn_grid.Add(_unselect_all_btn, flag = ALIGN_CENTER)
    self.btn_grid.Add(_clear_all_entry, flag = ALIGN_CENTER)
    self.btn_grid.Add(_run_button, flag = ALIGN_CENTER)

    vbox = BoxSizer(VERTICAL)
    vbox.Add(cmd_area, flag = EXPAND)
    vbox.Add(self._notebook, proportion = 1, flag = EXPAND)
    vbox.Add(self.btn_grid, flag = EXPAND)
    p.SetSizerAndFit(vbox)
    return p
Esempio n. 14
0
  def build_page5(self, parent):
    p = Panel(parent)
    m = self.m

    self._get_sqlmap_path_btn = btn(p, label = 'sqlmap -hh')
    self._get_sqlmap_path_btn.Disable()
    # 多行文本框的默认size太小了
    # 默认高度太低, 不指定个高度, gtk会报 滚动条相关的size 警告
    m._page5_manual_view.Create(p,
                                size = (-1, 300),
                                style = wx.TE_MULTILINE | wx.TE_READONLY)

    self._get_sqlmap_path_btn.Bind(
      EVT_BUTTON, lambda evt, view = m._page5_manual_view:
        self._make_help_thread(evt, view))

    self._make_help_thread(None, m._page5_manual_view)

    vbox = BoxSizer(VERTICAL)
    vbox.Add(self._get_sqlmap_path_btn, flag = TOP | LEFT | BOTTOM, border = 10)
    vbox.Add(m._page5_manual_view, proportion = 1, flag = EXPAND | LEFT | RIGHT, border = 10)
    p.SetSizerAndFit(vbox)
    return p
Esempio n. 15
0
    def _enumeration_runsql(self):
        sbSizer = StaticBoxSizer(self.m._runsql_area, VERTICAL)

        border = SizerFlags().Expand().Border(LEFT | RIGHT, 10)

        row1 = BoxSizer()
        row2 = BoxSizer()
        row1.Add(self.m._runsql_area_sql_query_ckbtn, border)
        row1.Add(self.m._runsql_area_sql_query_entry,
                 proportion=1,
                 flag=RIGHT,
                 border=10)
        row2.Add(self.m._runsql_area_sql_shell_ckbtn, border)
        row2.Add(self.m._runsql_area_sql_file_ckbtn, border)
        row2.Add(self.m._runsql_area_sql_file_entry, proportion=1, flag=EXPAND)
        row2.Add(self.m._runsql_area_sql_file_chooser, border)

        spacing = SizerFlags().Expand().Border(TOP | BOTTOM, 6)
        sbSizer.Add(row1, spacing)
        sbSizer.Add(row2, spacing)
        return sbSizer
Esempio n. 16
0
    def enumeration_sizer(self):
        hbox1 = BoxSizer()
        enum_area = self._enumeration_enum()
        dump_area = self._enumeration_dump()
        limit_area = self._enumeration_limit()
        blind_area = self._enumeration_blind()

        spacing = SizerFlags().Expand().Border(LEFT | RIGHT, 5)
        hbox1.Add(enum_area, spacing)
        hbox1.Add(dump_area, spacing)
        hbox1.Add(limit_area, spacing)
        hbox1.Add(blind_area, spacing)

        meta_area = self._enumeration_meta()
        runsql_area = self._enumeration_runsql()
        brute_force_area = self._enumeration_brute_force()

        vbox = BoxSizer(VERTICAL)
        vbox.Add(hbox1, flag=TOP, border=5)
        vbox.Add(meta_area, flag=EXPAND | LEFT | RIGHT | TOP, border=5)
        vbox.Add(runsql_area, flag=EXPAND | LEFT | RIGHT | TOP, border=5)
        vbox.Add(brute_force_area, flag=LEFT | TOP, border=5)
        return vbox
Esempio n. 17
0
  def build_target_notebook(self, parent):
    m = self.m

    m._url_combobox.Create(parent, choices = ['http://www.site.com/vuln.php?id=1'])   # style = wx.CB_DROPDOWN

    p2 = Panel(parent)
    hbox2 = BoxSizer()
    m._burp_logfile.Create(p2)
    m._burp_logfile_chooser.Create(p2, label = '打开')
    m._burp_logfile_chooser.Bind(
      EVT_BUTTON,
      lambda evt, data = [m._burp_logfile]:
        self._handlers.set_file_entry_text(evt, data))

    hbox2.Add(m._burp_logfile, proportion = 1, flag = EXPAND)
    hbox2.Add(m._burp_logfile_chooser, flag = EXPAND)
    p2.SetSizer(hbox2)

    p3 = Panel(parent)
    hbox3 = BoxSizer()
    m._request_file.Create(p3)
    m._request_file_chooser.Create(p3, label = '打开')
    m._request_file_chooser.Bind(
      EVT_BUTTON,
      lambda evt, data = [m._request_file]:
        self._handlers.set_file_entry_text(evt, data))

    hbox3.Add(m._request_file, proportion = 1, flag = EXPAND)
    hbox3.Add(m._request_file_chooser, flag = EXPAND)
    p3.SetSizer(hbox3)

    p4 = Panel(parent)
    hbox4 = BoxSizer()
    m._bulkfile.Create(p4)
    m._bulkfile_chooser.Create(p4, label = '打开')
    m._bulkfile_chooser.Bind(
      EVT_BUTTON,
      lambda evt, data = [m._bulkfile]:
        self._handlers.set_file_entry_text(evt, data))

    hbox4.Add(m._bulkfile, proportion = 1, flag = EXPAND)
    hbox4.Add(m._bulkfile_chooser, flag = EXPAND)
    p4.SetSizer(hbox4)

    p5 = Panel(parent)
    hbox5 = BoxSizer()
    m._configfile.Create(p5)
    m._configfile_chooser.Create(p5, label = '打开')
    m._configfile_chooser.Bind(
      EVT_BUTTON,
      lambda evt, data = [m._configfile]:
        self._handlers.set_file_entry_text(evt, data))

    hbox5.Add(m._configfile, proportion = 1, flag = EXPAND)
    hbox5.Add(m._configfile_chooser, flag = EXPAND)
    p5.SetSizer(hbox5)

    m._google_dork.Create(parent)
    m._direct_connect.Create(parent,
                             value = 'mysql://*****:*****@DBMS_IP:DBMS_PORT/DATABASE_NAME or '
                                     'access://DATABASE_FILEPATH')

    parent.AddPage(m._url_combobox, '目标url')
    parent.AddPage(p2, 'burp日志')
    parent.AddPage(p3, 'HTTP请求')
    parent.AddPage(p4, 'BULKFILE')
    parent.AddPage(p5, 'ini文件')
    parent.AddPage(m._google_dork, 'GOOGLEDORK')
    parent.AddPage(m._direct_connect, '-d DIRECT')
Esempio n. 18
0
  def build_page4(self, parent):
    p = Panel(parent)
    m = self.m

    border = SizerFlags().Border(LEFT | RIGHT, 5).Align(ALIGN_CENTER)
    proportion_border = SizerFlags(1).Border(LEFT | RIGHT, 5).Align(ALIGN_CENTER)

    row1, row2 = (BoxSizer() for _ in range(2))
    m._page4_api_server_label.Create(p, label = 'REST-JSON API server:')
    m._page4_api_server_entry.Create(p, value = '127.0.0.1:8775')
    m._page4_admin_token_label.Create(p, label = 'Admin (secret) token:')
    m._page4_admin_token_entry.Create(p)
    m._page4_admin_token_entry.SetMaxLength(32)
    row1.Add(m._page4_api_server_label, border)
    row1.Add(m._page4_api_server_entry, proportion_border)
    row1.Add(m._page4_admin_token_label, border)
    row1.Add(m._page4_admin_token_entry, proportion_border)

    m._page4_task_new_btn.Create(p, label = '创建任务')
    m._page4_admin_list_btn.Create(p, label = '显示任务')
    m._page4_admin_flush_btn.Create(p, label = '删除所有任务')
    m._page4_clear_task_view_btn.Create(p, label = '清空反馈的结果')
    m._page4_username_label.Create(p, label = '用户名:')
    m._page4_username_entry.Create(p)
    m._page4_password_label.Create(p, label = '密码:')
    m._page4_password_entry.Create(p)

    _arrow_down = wx.ArtProvider.GetBitmap(wx.ART_GO_DOWN, wx.ART_BUTTON)
    m._page4_admin_list_btn.SetBitmap(_arrow_down, dir = RIGHT)

    m._page4_task_new_btn.Bind(EVT_BUTTON, self._handlers.api.task_new)
    m._page4_admin_list_btn.Bind(EVT_BUTTON, self._handlers.api.admin_list)
    m._page4_admin_flush_btn.Bind(EVT_BUTTON, self._handlers.api.admin_flush)
    m._page4_clear_task_view_btn.Bind(EVT_BUTTON, self._handlers.clear_task_view_buffer)

    row2.Add(m._page4_task_new_btn, border)
    row2.Add(m._page4_admin_list_btn, border)
    row2.Add(m._page4_admin_flush_btn, border)
    row2.Add(m._page4_clear_task_view_btn, border)
    row2.Add(m._page4_username_label, flag = ALIGN_CENTER | LEFT, border = 200)
    row2.Add(m._page4_username_entry, proportion_border)
    row2.Add(m._page4_password_label, border)
    row2.Add(m._page4_password_entry, proportion_border)

    row3 = SplitterWindow(p, style = wx.SP_LIVE_UPDATE | wx.BORDER_SUNKEN)
    # 不能放在SplitVertically后面, 不然gravity会无效
    # row3.SetSashGravity(0.5)
    row3.SetMinimumPaneSize(400)

    lpane = Scroll(row3)
    self._api_admin_list_rows = lpane

    lpane.SetSizer(BoxSizer(VERTICAL))

    rpane = Panel(row3)
    _rbox = BoxSizer(VERTICAL)

    m._page4_option_get_entry.Create(rpane, value = 'url risk level')
    _page4_option_set_view_tip = st(rpane, label = 'check optiondict.py of sqlmap about options.')
    _options_example = ("{\n"
                        "  'url': 'http://www.site.com/vuln.php?id=1',\n"
                        "  'level': 1, 'risk': 1,\n\n"
                        "}\n")
    m._page4_option_set_view.Create(rpane,
                                    value = _options_example,
                                    style = wx.TE_MULTILINE)
    _rbox.Add(m._page4_option_get_entry, flag = EXPAND | ALL, border = 2)
    _rbox.Add(_page4_option_set_view_tip, flag = ALL, border = 2)
    _rbox.Add(m._page4_option_set_view, proportion = 1, flag = EXPAND | ALL, border = 2)
    rpane.SetSizer(_rbox)

    row3.SplitVertically(lpane, rpane)
    # win下, lpane是灰色的, 将row3设下颜色, 又是兼容代码...
    row3.SetBackgroundColour(m._page4_option_set_view.GetBackgroundColour())
    row3.SetSashPosition(lpane.GetMinWidth())

    m._page4_task_view.Create(p, value = 'response result:\n', style = wx.TE_MULTILINE | wx.TE_READONLY)

    vbox = BoxSizer(VERTICAL)
    vbox.Add(row1, flag = EXPAND | ALL, border = 5)
    vbox.Add(row2, flag = EXPAND | ALL, border = 5)
    vbox.Add(row3, proportion = 1, flag = EXPAND | LEFT | RIGHT, border = 10)
    vbox.Add(m._page4_task_view, proportion = 1, flag = EXPAND | ALL, border = 10)
    p.SetSizerAndFit(vbox)
    return p
Esempio n. 19
0
    def setting_sizer(self):
        spacing = SizerFlags().Expand().Border(ALL, 5)

        hbox0 = BoxSizer()
        hbox0.Add(self.m._sqlmap_path_label, flag=ALIGN_CENTER)
        hbox0.Add(self.m.sqlmap_path_entry, proportion=1, flag=EXPAND)
        hbox0.Add(self.m._sqlmap_path_chooser, flag=EXPAND | RIGHT, border=25)

        hbox1 = BoxSizer()
        # win下 探测选项staticbox不能用proportion = 1, 最大化时会让右侧的staticbox消失
        # hbox1_grid为了win写的兼容sizer, 怎么感觉在写html?
        hbox1_grid = FlexGridSizer(1, 2, 0, 0)

        inject_area = self._setting_inject()

        detection_area = self._setting_detection()
        tech_area = self._setting_tech()
        hbox1_grid.Add(detection_area, flag=EXPAND | RIGHT, border=10)
        hbox1_grid.Add(tech_area, flag=EXPAND)
        hbox1_grid.AddGrowableRow(0, 1)
        hbox1_grid.AddGrowableCol(0, 1)

        hbox1.Add(inject_area, spacing)
        hbox1.Add(hbox1_grid, proportion=1, flag=EXPAND | ALL, border=5)

        hbox2 = BoxSizer()
        tamper_area = self._setting_tamper()
        optimize_area = self._setting_optimize()
        offen_area = self._setting_offen()
        hidden_area = self._setting_hidden()

        hbox2.Add(tamper_area, spacing)
        hbox2.Add(optimize_area, spacing)
        hbox2.Add(offen_area, spacing)
        hbox2.Add(hidden_area, spacing)

        vbox = BoxSizer(VERTICAL)
        vbox.Add(hbox0, flag=EXPAND | LEFT, border=5)
        # border = 20: 让win下的滚动条不致于掩盖末端内容~~
        vbox.Add(hbox1, flag=EXPAND | RIGHT, border=20)
        vbox.Add(hbox2)
        return vbox