GP-5873: New idaxml.py for IDA 9.x

This commit is contained in:
Ryan Kurtz 2025-08-07 09:01:30 -04:00
parent 6c44623c41
commit 82f50a9305
7 changed files with 4124 additions and 1 deletions

View file

@ -0,0 +1,40 @@
<html>
<head>
<title>XML Exporter for IDA version 9</title>
<style>
filename {
font-family: monospace;
}
</style>
</head>
<body>
<h1>XML Exporter for IDA version 9</h1>
<p>
The 7XX versions of the XML Exporter, Importer, and Loader can only be used
with IDA version 9.0 and greater.
</p>
<p>
<filename>xml_exporter.py</filename> is a plugin to export an IDA database as an XML file.
It must be placed in the IDA plugins folder.
</p>
<p>
<filename>xml_loader.py</filename> is an IDA loader to build a new database using an XML file.
It loads the .bytes file and builds the IDA database using the contents of
the XML file. NOTE: Currently, the loader does not support importing memory
overlays or Harvard architectures (e.g., 8051).
It must be placed in the IDA loaders folder.
</p>
<p>
<filename>xml_importer.py</filename> is a plugin to add data from an XML file to an existing
database. It will NOT load any binary data from the bytes file. It will add
symbols, comments, code, data, functions, etc. for addresses that currently
exist in the database.
It must be placed in the IDA plugins folder.
</p>
<p>
The <filename>idaxml.py</filename> module is a require import for the xml_exporter, xml_importer,
and xml_loader.
It must be placed in the IDA python folder.
</p>
</body>
</html>

View file

@ -0,0 +1,108 @@
## ###
# IP: GHIDRA
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
#---------------------------------------------------------------------
# xmlldr.py - IDA XML loader
#---------------------------------------------------------------------
"""
Loader for IDA to import a XML PROGRAM file and create a new database (.idb).
This file must be placed in the IDA loaders directory.
The file idaxml.py must be placed in the IDA python directory.
"""
from __future__ import print_function
import ida_idaapi
import ida_idp
import ida_kernwin
import ida_pro
import idaxml
import idc
import sys
if sys.version_info.major >= 3:
from idaxml import _exc_info
sys.exc_value = lambda: _exc_info()[1]
sys.exc_type = lambda: _exc_info()[0]
"""
Loader functions
"""
def accept_file(li, filename):
"""
Check if the file is of supported format
@param li: a file-like object which can be used to access the input data
@param n : format number. The function will be called with incrementing
number until it returns zero
@return: 0 - no more supported formats
string "name" - format name to display in the chooser dialog
dictionary { 'format': "name", 'options': integer }
options: should be 1, possibly ORed with ACCEPT_FIRST (0x8000)
to indicate preferred format
"""
if not idaxml.is_ida_version_supported():
return 0
# read 16K bytes to allow for the DTD
data = li.read(0x4000)
# look for start of <PROGRAM> element
start = data.find(b"<PROGRAM")
if start >= 0:
s = data.find(b"<PROCESSOR ")
p = data[s+11:]
e = p.find(b"/>")
proc = p[:e]
ida_kernwin.info("Processor specified in the XML file is:\n" + proc.decode() +
"\n\nYou must select and set the compatible " +
"IDA processor type.")
return { 'format': "XML PROGRAM file", 'options': 0x8001 }
return 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

View file

@ -0,0 +1,97 @@
## ###
# IP: GHIDRA
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
#---------------------------------------------------------------------
# xmlexp.py - IDA XML Exporter plugin
#---------------------------------------------------------------------
"""
Plugin for IDA which exports a XML PROGRAM document file from a database.
This file must be placed in the IDA plugins directory.
The file idaxml.py must be placed in the IDA python directory.
"""
from __future__ import print_function
import ida_auto
import ida_idaapi
import ida_kernwin
import idaxml
import idc
import sys
if sys.version_info.major >= 3:
from idaxml import _exc_info
sys.exc_value = lambda: _exc_info()[1]
sys.exc_type = lambda: _exc_info()[0]
class XmlExporterPlugin(ida_idaapi.plugin_t):
"""
XML Exporter plugin class
"""
flags = 0
comment = "Export database as XML file"
help = "Export database as XML <PROGRAM> document"
wanted_name = "XML Exporter"
wanted_hotkey = "Ctrl-Shift-x"
def init(self):
"""
init function for XML Exporter plugin.
Returns:
Constant PLUGIN_OK if this IDA version supports the plugin,
else returns PLUGIN_SKIP if this IDA is older than the supported
baseline version.
"""
if idaxml.is_ida_version_supported():
return ida_idaapi.PLUGIN_OK
else:
return ida_idaapi.PLUGIN_SKIP
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 term(self):
pass
def PLUGIN_ENTRY():
return XmlExporterPlugin()

View file

@ -0,0 +1,99 @@
## ###
# IP: GHIDRA
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
#---------------------------------------------------------------------
# xmlimp.py - IDA XML Importer plugin
#---------------------------------------------------------------------
"""
Plugin for IDA to import a XML PROGRAM file into an existing open database.
This file must be placed in the IDA plugins directory.
The file idaxml.py must be placed in the IDA python directory.
"""
from __future__ import print_function
import ida_idaapi
import ida_pro
import idaxml
import idc
import sys
if sys.version_info.major >= 3:
from idaxml import _exc_info
sys.exc_value = lambda: _exc_info()[1]
sys.exc_type = lambda: _exc_info()[0]
class XmlImporterPlugin(ida_idaapi.plugin_t):
"""
XML Importer plugin class
"""
flags = 0
comment = "Import XML PROGRAM file"
help = "Import XML <PROGRAM> document to database"
wanted_name = "XML Importer"
wanted_hotkey = "Ctrl-Alt-l"
def init(self):
"""
init function for XML Importer plugin.
Returns:
Constant PLUGIN_OK if this IDA version supports the plugin,
else returns PLUGIN_SKIP if this IDA is older than the supported
baseline version.
"""
if idaxml.is_ida_version_supported():
return ida_idaapi.PLUGIN_OK
else:
return ida_idaapi.PLUGIN_SKIP
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 term(self):
pass
def PLUGIN_ENTRY():
return XmlImporterPlugin()

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@
The plugins also facilitate transfer from Ghidra to IDA.
</p>
<p>
The plugin is provided in Python for IDA versions 6 and 7.
The plugin is provided in Python for IDA versions 6, 7, and 9.
See the README file within each for further instruction.
</p>
</body>

View file

@ -1,4 +1,5 @@
##VERSION: 2.0
Python/6xx/README.html||GHIDRA||||END|
Python/7xx/README.html||GHIDRA||||END|
Python/9xx/README.html||GHIDRA||||END|
README.html||GHIDRA||||END|