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)
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
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
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
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
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)
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 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)
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)
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
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
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
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
def script_start(): return not idc.warning(SCRIPT_NAME + "\n\n" + SCRIPT_DESCRIPTION + "\n\n- " + SCRIPT_AUTHOR)
def script_information(text): return not idc.warning(SCRIPT_NAME + "\n\n" + text + "\n\n- " + SCRIPT_AUTHOR)