Ejemplo n.º 1
0
 def run(self, arg):
     """
     run function for XML Exporter plugin.
     
     Args:
         arg: Integer, non-zero value enables auto-run feature for
             IDA batch (no gui) processing mode. Default is 0.
     """
     st = idc.set_ida_state(idc.IDA_STATUS_WORK)
     xml = idaxml.XmlExporter(arg)
     try:
         try:
             xml.export_xml()
         except idaxml.Cancelled:
             ida_kernwin.hide_wait_box()
             msg = "XML Export cancelled!"
             print "\n" + msg
             idc.warning(msg)
         except:
             ida_kernwin.hide_wait_box()
             msg = "***** Exception occurred: XML Exporter failed! *****"
             print "\n" + msg + "\n", sys.exc_type, sys.exc_value
             idc.warning(msg)
     finally:
         xml.cleanup()
         ida_auto.set_ida_state(st)
Ejemplo n.º 2
0
 def run(self, arg):
     """
     run function for XML Exporter plugin.
     
     Args:
         arg: Integer, non-zero value enables auto-run feature for
             IDA batch (no gui) processing mode. Default is 0.
     """
     st = idc.set_ida_state(idc.IDA_STATUS_WORK)
     xml = idaxml.XmlExporter(arg)
     try:
         try:
             xml.export_xml()
         except idaxml.Cancelled:
             ida_kernwin.hide_wait_box()
             msg = "XML Export cancelled!"
             print "\n" + msg
             idc.warning(msg)
         except:
             ida_kernwin.hide_wait_box()
             msg = "***** Exception occurred: XML Exporter failed! *****"
             print "\n" + msg + "\n", sys.exc_type, sys.exc_value
             idc.warning(msg)
     finally:
         xml.cleanup()
         ida_auto.set_ida_state(st)
Ejemplo n.º 3
0
def test_import(n, p=None):
    msg_t = "couldn't import %s - you should install %s"
    r = False
    try:
        __import__(n)
        r = True
    except ImportError:
        msg = msg_t % (n, p or n)
        print '[-]', msg
        idc.warning(msg)
    return r
Ejemplo n.º 4
0
Archivo: lib.py Proyecto: trib0r3/GhIDA
def export_ida_project_to_xml():
    """
    Export the current project into XML format
    """
    global EXPORT_XML_FILE

    xml_file_path, bin_file_path = get_ida_exported_files()
    print("GhIDA:: [DEBUG] EXPORT_XML_FILE: %s" % EXPORT_XML_FILE)

    # Check if files are alredy available
    if os.path.isfile(xml_file_path) and \
            os.path.isfile(bin_file_path) and \
            not EXPORT_XML_FILE:
        return xml_file_path, bin_file_path

    EXPORT_XML_FILE = False

    # Otherwise call the XML exporter IDA plugin
    print("GhIDA:: [DEBUG] Exporting IDA project into XML format")
    st = idc.set_ida_state(idc.IDA_STATUS_WORK)
    xml = XmlExporter(1)

    try:
        xml.export_xml(xml_file_path)
        print("GhIDA:: [INFO] XML exporting completed")
    except Cancelled:
        ida_kernwin.hide_wait_box()
        msg = "GhIDA:: [!] XML Export cancelled!"
        print("\n" + msg)
        idc.warning(msg)
    except Exception:
        ida_kernwin.hide_wait_box()
        msg = "GhIDA:: [!] Exception occurred: XML Exporter failed!"

        excinfo = sys.exc_info()
        tb = excinfo[2]
        print("\n" + msg + "\n", excinfo[:2], tb)
        traceback.print_tb(tb)

        idc.warning(msg)
    finally:
        xml.cleanup()
        ida_auto.set_ida_state(st)

    # check if both xml and binary format exist
    if not os.path.isfile(xml_file_path) or \
            not os.path.isfile(bin_file_path):
        raise Exception("GhIDA:: [!] XML or bytes file non existing.")
    return xml_file_path, bin_file_path
Ejemplo n.º 5
0
    def login(self):
        data = json.dumps({'api_key': self.api_key})
        headers = {
            "Accept-encoding": "gzip, deflate",
            "Content-type": "application/json",
            "Accept": "*/*;q=0.8",
            "Accept-Language": "en-US,en;q=0.5"
        }

        self.h_conn.request("POST", "/api/1.0/auth_token/", data, headers)
        res = self.h_conn.getresponse()
        if res.status != 200:
            idc.warning("Error, cannot login to Polichombr!")
            raise IOError
        token = json.loads(res.read())["token"]
        self.auth_token = token
Ejemplo n.º 6
0
    def login(self):
        data = json.dumps({'api_key': self.api_key})
        headers = {"Accept-encoding": "gzip, deflate",
                   "Content-type": "application/json",
                   "Accept": "*/*;q=0.8",
                   "Accept-Language": "en-US,en;q=0.5"}

        self.h_conn.request("POST",
                            "/api/1.0/auth_token/",
                            data,
                            headers)
        res = self.h_conn.getresponse()
        if res.status != 200:
            idc.warning("Error, cannot login to Polichombr!")
            raise IOError
        token = json.loads(res.read())["token"]
        self.auth_token = token
Ejemplo n.º 7
0
def xex_read_uncompressed(li):
    global directory_entry_headers
    global directory_entries
    global xex_header
    global session_key

    data_descriptor = directory_entries[XEX_FILE_DATA_DESCRIPTOR_HEADER]

    li.seek(directory_entry_headers[XEX_FILE_DATA_DESCRIPTOR_HEADER] +
            8)  # skip first 8 bytes of data descriptor
    num_blocks = (data_descriptor.Size - 8) / 8

    # Read block descriptor structs
    xex_blocks = []
    for i in range(0, num_blocks):
        block = read_struct(li, XEXRawBaseFileBlock)
        xex_blocks.append(block)

    # Read in basefile
    pe_data = io.BytesIO()
    aes = AES.new(session_key, AES.MODE_CBC, '\0' * 16)

    li.seek(xex_header.SizeOfHeaders)
    for block in xex_blocks:
        data_size = block.Size
        zero_size = block.ZeroSize

        if data_descriptor.Flags == 0:
            # decrypted
            pe_data.write(li.read(data_size))
        elif data_descriptor.Flags == 1:
            # encrypted
            data = li.read(data_size)
            pe_data.write(aes.decrypt(data))
        else:
            idc.warning(
                "xex_read_uncompressed failed: unknown encryption flags %d" %
                data_descriptor.Flags)
            return 0

        pe_data.write('\0' * zero_size)

    return pe_load(pe_data)
Ejemplo n.º 8
0
 def run(self, arg):
     """
     run function for XML Importer plugin.
     
     Args:
         arg: Integer, a non-zero value enables auto-run feature for
              IDA batch (no gui) processing mode. Default is 0.
     """
     st = idc.set_ida_state(idc.IDA_STATUS_WORK)
     xml = idaxml.XmlImporter(idaxml.PLUGIN, arg)
     try:
         try:
             xml.import_xml()
         except idaxml.Cancelled:
             msg = "XML Import cancelled!"
             print "\n" + msg
             idc.warning(msg)
         except idaxml.MultipleAddressSpacesNotSupported:
             msg  = "XML Import cancelled!"
             msg += "\n\nXML Import does not currently support"
             msg += "\nimporting multiple address spaces."
             print "\n" + msg
             idc.warning(msg)
         except:
             msg = "***** Exception occurred: XML Importer failed! *****"
             print "\n" + msg + "\n", sys.exc_type, sys.exc_value
             idc.warning(msg)
     finally:
         xml.cleanup()
         idc.set_ida_state(st)
Ejemplo n.º 9
0
def main():
    if not idaapi.is_debugger_on():
        idc.warning("Please run the process first!")
        return
    if idaapi.get_process_state() != -1:
        idc.warning("Please suspend the debugger first!")
        return

    # only avail from IdaPython r232
    if hasattr(idaapi, "NearestName"):
        # get all debug names
        dn = idaapi.get_debug_names(idaapi.cvar.inf.min_ea,
                                    idaapi.cvar.inf.max_ea)
        # initiate a nearest name search (using debug names)
        nn = idaapi.NearestName(dn)
    else:
        nn = None

    ret, callstack = CallStackWalk(nn)
    if ret:
        title = "Call stack walker (thread %X)" % (get_current_thread())
        idaapi.close_chooser(title)
        c = CallStackWalkChoose(title, callstack)
        c.Show()
    else:
        idc.warning("Failed to walk the stack:" + callstack)
Ejemplo n.º 10
0
 def run(self, arg):
     """
     run function for XML Importer plugin.
     
     Args:
         arg: Integer, a non-zero value enables auto-run feature for
              IDA batch (no gui) processing mode. Default is 0.
     """
     st = idc.set_ida_state(idc.IDA_STATUS_WORK)
     xml = idaxml.XmlImporter(idaxml.PLUGIN, arg)
     try:
         try:
             xml.import_xml()
         except idaxml.Cancelled:
             msg = "XML Import cancelled!"
             print "\n" + msg
             idc.warning(msg)
         except idaxml.MultipleAddressSpacesNotSupported:
             msg = "XML Import cancelled!"
             msg += "\n\nXML Import does not currently support"
             msg += "\nimporting multiple address spaces."
             print "\n" + msg
             idc.warning(msg)
         except:
             msg = "***** Exception occurred: XML Importer failed! *****"
             print "\n" + msg + "\n", sys.exc_type, sys.exc_value
             idc.warning(msg)
     finally:
         xml.cleanup()
         idc.set_ida_state(st)
def script_settings():
    settings = "Search:\n" + \
               "- Entry Mnemonic: " + ENTRY_MNEM + "\n" + \
               "- Entry Mnemonic Bytecode: " + ENTRY_ID_BYTECODE + "\n" + \
               "- Landing Strip Signature: " + LANDING_STRIP + "\n" + \
               "Manipulation:\n" + \
               "- NOP Buffer: " + str(BUFFER_NOP) + "\n" + \
               "- Hide Buffer: " + str(BUFFER_HIDE) + "\n" + \
               "- - Oreans Buffer Name: " + str(BUFFER_NAME) + "\n" + \
               "- - Oreans Start Buffer Name: " + str(BUFFER_START_NAME) + "\n" + \
               "- - Oreans End Buffer Name: " + str(BUFFER_END_NAME) + "\n" + \
               "Output:\n" + \
               "- JSON File: " + current_idb_path() + OUTPUT_JSON + "\n"
    return not idc.warning(SCRIPT_NAME + " - Settings\n\n" + settings + "\n\n- " + SCRIPT_AUTHOR)
Ejemplo n.º 12
0
def xex_read_image(li, xex_key_index):
    global directory_entries
    global image_key
    global session_key

    comp_format = 0
    enc_flag = 0
    if XEX_FILE_DATA_DESCRIPTOR_HEADER in directory_entries:
        data_descriptor = directory_entries[XEX_FILE_DATA_DESCRIPTOR_HEADER]
        comp_format = data_descriptor.Format
        enc_flag = data_descriptor.Flags

    if comp_format > 1:
        idc.warning("Sorry, XEX loader can't load compressed XEX atm :(")
        return 0

    # Setup session key for decrypting basefile
    aes = AES.new(xex_keys[xex_key_index], AES.MODE_ECB)
    session_key = aes.decrypt(image_key)

    result = 0
    if comp_format == 0:
        result = xex_read_raw(li)
    elif comp_format == 1:
        result = xex_read_uncompressed(li)
    elif comp_format == 2:
        result = xex_read_compressed(li)
    else:
        idc.warning("xex_read_image failed: unknown compression format %d!" %
                    comp_format)
        result = 0

    # Let user know which key was used if file is encrypted & we've loaded successfully
    if result and enc_flag == 1:
        print("[+] (decrypted using %s key)" % xex_key_names[xex_key_index])

    return result
Ejemplo n.º 13
0
def load_file(li, neflags, format):
    """
    Load the file into database

    @param li: a file-like object which can be used to access the input data
    @param neflags: options selected by the user, see loader.hpp
    @return: 0-failure, 1-ok
    """
    global event, element
    if ida_idp.get_idp_name() == None:
        ida_idp.set_processor_type("metapc", ida_idp.SETPROC_LOADER)
    status = 0
    st = idc.set_ida_state(idc.IDA_STATUS_WORK)
    xml = idaxml.XmlImporter(idaxml.LOADER, 0)
    try:
        status = xml.import_xml()
    except idaxml.Cancelled:
        msg = "XML PROGRAM import cancelled!"
        print "\n" + msg
        idc.warning(msg)
    except idaxml.MultipleAddressSpacesNotSupported:
        msg = "XML Import cancelled!"
        msg += "\n\nXML Import does not currently support"
        msg += "\nimporting multiple address spaces."
        print "\n" + msg
        idc.warning(msg)
    except:
        print "\nHouston, we have a problem!"
        msg = "***** Exception occurred: XML loader failed! *****"
        print "\n" + msg + "\n", sys.exc_type, sys.exc_value
        print event, element.tag, element.attrib
        idc.warning(msg)
    finally:
        idc.set_ida_state(st)
        xml.cleanup()
        return status
Ejemplo n.º 14
0
    def OnFormChange(self, fid):
        if fid == self.rOptMD5.id or fid == self.rOptFile.id:
            input = (self.cfg.md5sum, self.cfg.infile)
            if fid == self.rOptMD5.id:
                c1 = self.rOptMD5
                c2 = self.rOptFile
                idx = 0
            else:
                c1 = self.rOptFile
                c2 = self.rOptMD5
                idx = 1

            v = not self.GetControlValue(c1)
            if v: idx = not idx

            # Uncheck the opposite input type
            self.SetControlValue(c2, v)

            # Set input field depending on input type
            self.SetControlValue(self.txtInput, input[idx])
        #
        # Report button
        #
        elif fid == self.btnReport.id:
            input = self.GetControlValue(self.txtInput)
            as_file = self.GetControlValue(self.rOptFile)
            apikey = self.GetControlValue(self.txtApiKey)

            ok, r = VtReport(self.cfg.apikey,
                             filename=input if as_file else None,
                             md5sum=None if as_file else input)

            # Error?
            if not ok:
                idc.warning(r)
                return 1

            # Pass the result
            self.EChooser.SetItems(r)

            # We have results and it was a file? Print its MD5
            if r and as_file:
                print("%s: %s" % (vt.LAST_FILE_HASH, input))

            # Refresh the embedded chooser control
            # (Could also clear previous results if not were retrieved during this run)
            self.RefreshField(self.cEChooser)

            # Store the input for the caller
            self.cfg.input = input

            # No results and file as input was supplied?
            if r is None:
                if as_file:
                    # Propose to upload
                    if idc.ask_yn(
                            0,
                            "HIDECANCEL\nNo previous results. Do you want to submit the file:\n\n'%s'\n\nto VirusTotal?"
                            % input) == 0:
                        return 1

                    try:
                        r = vt.scan_file(input)
                    except Exception as e:
                        idc.warning("Exceptio during upload: %s" % str(e))
                    else:
                        if r is None:
                            idc.warning("Failed to upload the file!")
                        else:
                            idc.warning(
                                "File uploaded. Check again later to get the analysis report. Scan id: %s"
                                % r)
                else:
                    idc.warning("No results found for hash: %s" % input)

        return 1
Ejemplo n.º 15
0
def load_file(li, neflags, format):
    global xex_magic
    global xex_header
    global directory_entry_headers
    global directory_entries
    global export_table_va
    global base_address
    global entry_point
    global image_key

    if format != _FORMAT_XEX32 and format != _FORMAT_XEX31 and format != _FORMAT_XEX25 and format != _FORMAT_XEX2D and format != _FORMAT_XEX3F:
        Warning("Unknown format name: '%s'" % format)
        return 0

    idaapi.set_processor_type("ppc", idc.SETPROC_LOADER)
    ida_typeinf.set_compiler_id(idc.COMP_MS)

    print("[+] IDAPython XEX Loader 0.6 for IDA 7.0+ by emoose")

    # Read XEX header & directory entry headers
    li.seek(0)
    xex_magic = li.read(4)
    li.seek(0)
    if xex_magic == _MAGIC_XEX3F:
        xex_header = read_struct(li, ImageXEXHeader_3F)
    else:
        xex_header = read_struct(li, ImageXEXHeader)

    print(xex_header)

    directory_entry_headers = {}
    for i in range(0, xex_header.HeaderDirectoryEntryCount):
        dir_header = read_struct(li, ImageXEXDirectoryEntry)
        directory_entry_headers[dir_header.Key] = dir_header.Value

    # Read XEX SecurityInfo header
    if xex_magic != _MAGIC_XEX3F:
        li.seek(xex_header.SecurityInfo)

        if xex_magic == _MAGIC_XEX32:
            xex_security_info = read_struct(li, XEX2SecurityInfo)
        elif xex_magic == _MAGIC_XEX31:
            xex_security_info = read_struct(li, XEX1SecurityInfo)
        elif xex_magic == _MAGIC_XEX25:
            xex_security_info = read_struct(li, XEX25SecurityInfo)
        elif xex_magic == _MAGIC_XEX2D:
            xex_security_info = read_struct(li, XEX2DSecurityInfo)

        export_table_va = xex_security_info.ImageInfo.ExportTableAddress
        if xex_magic != _MAGIC_XEX2D:
            image_key = xex_security_info.ImageInfo.ImageKey

    # Try reading in XEX directory entry structures
    print("[+] Reading %d XEX directory entries / optional headers..." %
          xex_header.HeaderDirectoryEntryCount)

    directory_entries = {}
    for key in directory_entry_headers:
        header_value = directory_entry_headers[key]
        entry_size = key & 0xFF
        if entry_size <= 1:
            # value is stored in the header itself
            directory_entries[key] = header_value
            print("0x%X = 0x%X" % (key, header_value))
            continue

        li.seek(header_value)
        # value is pointer to a structure...
        if key == XEX_HEADER_SECTION_TABLE:
            print("0x%X = HeaderSectionTable (@ 0x%X)" % (key, header_value))
            directory_entries[key] = 0  # todo: read_struct(li, XEX2Resources)

        elif key == XEX_FILE_DATA_DESCRIPTOR_HEADER:
            print("0x%X = FileDataDescriptor (@ 0x%X)" % (key, header_value))
            directory_entries[key] = read_struct(li, XEXFileDataDescriptor)
            print(directory_entries[key])

        elif key == XEX_HEADER_DELTA_PATCH_DESCRIPTOR:
            print("0x%X = DeltaPatchDescriptor (@ 0x%X)" % (key, header_value))
            directory_entries[
                key] = 0  # todo: read_struct(li, XEX2DeltaPatchDescriptor)

        elif key == XEX_HEADER_BOUND_PATH:
            print("0x%X = BoundingPath (@ 0x%X)" % (key, header_value))
            directory_entries[key] = read_xexstring(li)
            print(directory_entries[key])

        elif key == XEX_HEADER_IMPORTS:
            print("0x%X = Imports (@ 0x%X)" % (key, header_value))
            directory_entries[
                key] = 0  # todo: read_struct(li, XEX2ImportDescriptor)

        elif key == XEX_HEADER_IMPORTS_PREXEX2:
            print("0x%X = Imports_OldKey (@ 0x%X)" % (key, header_value))
            directory_entries[
                key] = 0  # todo: read_struct(li, XEX2ImportDescriptor)

        elif key == XEX_HEADER_VITAL_STATS:
            print("0x%X = VitalStats (@ 0x%X)" % (key, header_value))
            directory_entries[key] = read_struct(li, XEX2VitalStats)
            print(directory_entries[key])

        elif key == XEX_HEADER_CALLCAP_IMPORTS:
            print("0x%X = CallcapImports (@ 0x%X)" % (key, header_value))
            directory_entries[key] = read_struct(li, XEX2CallcapImports)
            print(directory_entries[key])

        elif key == XEX_HEADER_PE_MODULE_NAME:
            print("0x%X = PEModuleName (@ 0x%X)" % (key, header_value))
            directory_entries[key] = read_xexstring(li)
            print(directory_entries[key])

        elif key == XEX_HEADER_BUILD_VERSIONS:
            print("0x%X = BuildVersions (@ 0x%X)" % (key, header_value))
            directory_entries[
                key] = 0  # todo: read_struct(li, XEXImageLibraryVersions)

        elif key == XEX_HEADER_TLS_DATA:
            print("0x%X = TLSData (@ 0x%X)" % (key, header_value))
            directory_entries[key] = read_struct(li, XEX2TLSData)
            print(directory_entries[key])

        elif key == XEX_HEADER_EXECUTION_ID:
            print("0x%X = ExecutionID (@ 0x%X)" % (key, header_value))
            directory_entries[key] = read_struct(li, XEX2ExecutionID)
            print(directory_entries[key])

        elif key == XEX_HEADER_SERVICE_ID_LIST:
            print("0x%X = ServiceIDList (@ 0x%X)" % (key, header_value))
            directory_entries[key] = read_struct(li, XEX2ServiceIDList)
            print(directory_entries[key])

        elif key == XEX_HEADER_GAME_RATINGS:
            print("0x%X = GameRatings (@ 0x%X)" % (key, header_value))
            directory_entries[key] = read_struct(li, XEX2GameRatings)
            print(directory_entries[key])

        elif key == XEX_HEADER_LAN_KEY:
            print("0x%X = LANKey (@ 0x%X)" % (key, header_value))
            directory_entries[key] = li.read(0x10)
            print(directory_entries[key].encode('hex'))

        elif key == XEX_HEADER_MSLOGO:
            print("0x%X = MicrosoftLogo (@ 0x%X)" % (key, header_value))
            directory_entries[key] = read_struct(li, XEX2MSLogo)
            print(directory_entries[key])

        elif key == XEX_HEADER_PE_EXPORTS:
            print("0x%X = PEExports (@ 0x%X)" % (key, header_value))
            directory_entries[key] = read_struct(li, ImageDataDirectory)
            print(directory_entries[key])

        elif key == XEX_HEADER_PE_EXPORTS_PREXEX2:
            print("0x%X = PEExports_OldKey (@ 0x%X)" % (key, header_value))
            directory_entries[key] = read_struct(li, ImageDataDirectory)
            print(directory_entries[key])

        else:
            if entry_size == 0xFF:
                print("0x%X = variable-size data (@ 0x%X)" %
                      (key, header_value))
                directory_entries[
                    key] = 0  # todo: read_struct(li, OptionalHeaderData)
            else:
                print("0x%X = unknown key (data @ 0x%X)" % (key, header_value))

    # Print some info about the XEX
    if XEX_HEADER_EXECUTION_ID in directory_entries:
        exec_id = directory_entries[XEX_HEADER_EXECUTION_ID]
        print
        print("[+] XEX info:")
        print(" TitleId: %08X" % exec_id.TitleId)
        print(" Version: %d.%d.%d.%d (base: %d.%d.%d.%d)" %
              (exec_id.Version.Major, exec_id.Version.Minor,
               exec_id.Version.Build, exec_id.Version.QFE,
               exec_id.BaseVersion.Major, exec_id.BaseVersion.Minor,
               exec_id.BaseVersion.Build, exec_id.BaseVersion.QFE))
        print(" MediaId: %08X" % exec_id.MediaId)
        print(" SaveGameId: %08X" % exec_id.SaveGameId)
        print

    # Exit out if this is a patch file
    if xex_header.ModuleFlags & (XEX_MODULE_FLAG_PATCH
                                 | XEX_MODULE_FLAG_PATCH_FULL
                                 | XEX_MODULE_FLAG_PATCH_DELTA):
        idc.warning("Sorry, XEX loader doesn't support loading XEX patches")
        return 0

    # Try getting EP from directory entries
    # If not found here load_pe will fall back to the EP inside PE headers (not what we want!)
    entry_point = 0
    if XEX_HEADER_ENTRY_POINT in directory_entries:
        entry_point = directory_entries[XEX_HEADER_ENTRY_POINT]

    # Try getting base address from directory entries
    # If not found we'll use the one from SecurityInfo
    # (not sure which is preferred... guess the optional header should override the always-present SecurityInfo one?)
    base_address = xex_security_info.ImageInfo.LoadAddress if xex_magic != _MAGIC_XEX3F else xex_header.LoadAddress
    if XEX_HEADER_PE_BASE in directory_entries:
        base_address = directory_entries[XEX_HEADER_PE_BASE]

    # Try reading in the basefile
    if xex_read_image(li, 0) == 0 and xex_read_image(
            li, 1) == 0 and xex_read_image(li, 2) == 0:
        print("[+] Failed to load PE image from XEX :(")
        return 0

    # basefile loaded!

    # Setup imports if we have them
    if XEX_HEADER_IMPORTS in directory_entry_headers:
        xex_load_imports(li)

    # Setup exports if we have them
    if export_table_va != 0:
        xex_load_exports(li)

    # Done :)
    print("[+] XEX loaded, voila!")
    return 1
Ejemplo n.º 16
0
def script_start():
    return not idc.warning(SCRIPT_NAME + "\n\n" + SCRIPT_DESCRIPTION +
                           "\n\n- " + SCRIPT_AUTHOR)
Ejemplo n.º 17
0
def script_information(text):
    return not idc.warning(SCRIPT_NAME + "\n\n" + text + "\n\n- " +
                           SCRIPT_AUTHOR)