Merge remote-tracking branch 'origin/Ghidra_10.2'

This commit is contained in:
Ryan Kurtz 2022-10-26 12:36:14 -04:00
commit 89f9fed2f3
13 changed files with 132 additions and 67 deletions

View File

@ -221,10 +221,10 @@
</H3>
<BLOCKQUOTE>
<P>Enter <B>file:</B> followed by a file offset of the program's source file bytes (at
time of import) into the text area of the dialog. The file offset entered will be assumed
to be in decimal, unless it is preceeded by <B>0x</B>. That is, "file:0x1000" and
"file:1000" are different values.</P>
<P>Enter <B>file(n)</B>, where <B>n</b> is a file offset of the program's source file bytes
(at time of import), into the text area of the dialog. The file offset entered will be
assumed to be in decimal unless it is preceeded by <B>0x</B>. That is, "file(0x1000)" and
"file(1000)" are different values.</P>
<P><I><IMG src="../../shared/note.png" border="0">Ghidra does not support storing source
file bytes for all file formats. Searching for a file offset in these programs will always

View File

@ -17,11 +17,11 @@ package ghidra.app.util.navigation;
import java.awt.Component;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.SwingUtilities;
import org.apache.commons.lang3.StringUtils;
import docking.widgets.table.threaded.ThreadedTableModelListener;
import ghidra.GhidraOptions;
import ghidra.app.nav.Navigatable;
@ -50,7 +50,13 @@ import ghidra.util.table.GhidraProgramTableModel;
import ghidra.util.task.TaskMonitor;
public class GoToQuery {
private final String FILE_OFFSET_PREFIX = "file:";
/**
* Regex used for going to a file offset. We expect something of the form <code>file(n)</code>,
* where <code>n</code> can be hex or decimal. Spaces should be ignored.
*/
private Pattern FILE_OFFSET_REGEX = Pattern
.compile("file\\s*\\(\\s*((0x[0-9a-fA-F]+|[0-9]+))\\s*\\)", Pattern.CASE_INSENSITIVE);
private QueryData queryData;
private Address fromAddress;
@ -363,9 +369,10 @@ public class GoToQuery {
private boolean processFileOffset() {
String input = queryData.getQueryString();
if (StringUtils.startsWithIgnoreCase(input, FILE_OFFSET_PREFIX)) {
Matcher matcher = FILE_OFFSET_REGEX.matcher(input);
if (matcher.matches()) {
try {
long offset = Long.decode(input.substring(FILE_OFFSET_PREFIX.length()));
long offset = Long.decode(matcher.group(1));
// NOTE: Addresses are parsed via AbstractAddressSpace.parseString(String addr)
Program currentProgram = navigatable.getProgram();
Memory mem = currentProgram.getMemory();

View File

@ -250,31 +250,37 @@ public class GoToAddressLabelPluginTest extends AbstractGhidraHeadedIntegrationT
});
// Test decimal
setText("file:0");
setText("file(0)");
showDialog();
performOkCallback();
assertEquals(addr1, cbPlugin.getCurrentAddress());
// Test hex
setText("file:0x1");
setText("file(0x1)");
showDialog();
performOkCallback();
assertEquals(addr1.add(1), cbPlugin.getCurrentAddress());
// Test "case"
setText("FILE:2");
setText("FILe(0X2)");
showDialog();
performOkCallback();
assertEquals(addr1.add(2), cbPlugin.getCurrentAddress());
// Test spaces
setText("file ( 0 )");
showDialog();
performOkCallback();
assertEquals(addr1, cbPlugin.getCurrentAddress());
// Test not found
setText("file:0x100");
setText("file(0x100)");
showDialog();
performOkCallback();
assertNotEquals(addr1.add(0x100), cbPlugin.getCurrentAddress());
// Test multiple results
setText("file:3");
setText("file(3)");
showDialog();
performOkCallback();
GhidraProgramTableModel<?> model = waitForModel();

View File

@ -1,2 +1,2 @@
DATA SEARCH IGNORE DIR: yajsw-stable-12.12
DATA SEARCH IGNORE DIR: yajsw-stable-13.05
EXCLUDE FROM GHIDRA JAR: true

View File

@ -21,7 +21,7 @@ apply plugin: 'eclipse'
eclipse.project.name = 'Features GhidraServer'
def yajswRelease = "yajsw-stable-13.04"
def yajswRelease = "yajsw-stable-13.05"
configurations {
runGhidraServer

View File

@ -3,9 +3,9 @@ MODULE FILE LICENSE: lib/jdom-legacy-1.1.3.jar JDOM License
MODULE FILE LICENSE: lib/log4j-api-2.17.1.jar Apache License 2.0
MODULE FILE LICENSE: lib/log4j-core-2.17.1.jar Apache License 2.0
MODULE FILE LICENSE: lib/commons-collections4-4.1.jar Apache License 2.0
MODULE FILE LICENSE: lib/commons-lang3-3.9.jar Apache License 2.0
MODULE FILE LICENSE: lib/commons-lang3-3.12.0.jar Apache License 2.0
MODULE FILE LICENSE: lib/commons-io-2.11.0.jar Apache License 2.0
MODULE FILE LICENSE: lib/commons-text-1.6.jar Apache License 2.0
MODULE FILE LICENSE: lib/commons-text-1.10.0.jar Apache License 2.0
MODULE FILE LICENSE: lib/gson-2.9.0.jar Apache License 2.0
MODULE FILE LICENSE: lib/bcpkix-jdk15on-1.69.jar Bouncy Castle License
MODULE FILE LICENSE: lib/bcprov-jdk15on-1.69.jar Bouncy Castle License

View File

@ -31,8 +31,8 @@ dependencies {
api "org.apache.logging.log4j:log4j-api:2.17.1"
api "org.apache.logging.log4j:log4j-core:2.17.1"
api "org.apache.commons:commons-collections4:4.1"
api "org.apache.commons:commons-lang3:3.9"
api "org.apache.commons:commons-text:1.6"
api "org.apache.commons:commons-lang3:3.12.0"
api "org.apache.commons:commons-text:1.10.0"
api "commons-io:commons-io:2.11.0"
api "com.google.code.gson:gson:2.9.0"
api 'org.bouncycastle:bcpkix-jdk15on:1.69' // requires bcutil and bcprov

View File

@ -411,21 +411,33 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
}
case MIPS_ElfRelocationConstants.R_MIPS_32:
value = (int) symbolValue;
int intAddend = (int) (mipsRelocationContext.extractAddend() ? oldValue : addend);
value += intAddend;
int intAddend;
if (mipsRelocationContext.extractAddend()) {
intAddend = elf.is64Bit() ? (int) memory.getLong(relocationAddress)
: memory.getInt(relocationAddress);
}
else {
intAddend = (int) addend;
}
newValue = value;
writeNewValue = true;
newValue = value + intAddend;
long newValueBig = Integer.toUnsignedLong(newValue);
if (symbolIndex != 0 && intAddend != 0 && !saveValue) {
// If not continuing with compound relocation perform fixup so
// we can create offset-pointer now.
// NOTE: this may not handle all combound relocation cases
memory.setInt(relocationAddress, newValue);
writeNewValue = false;
warnExternalOffsetRelocation(program, relocationAddress,
symbolAddr, symbolName, intAddend, mipsRelocationContext.getLog());
if (elf.is32Bit()) {
if (saveValue) {
mipsRelocationContext.savedAddend = newValueBig;
}
else {
if (elf.is64Bit()) {
memory.setLong(relocationAddress, newValueBig);
}
else {
memory.setInt(relocationAddress, newValue);
}
if (symbolIndex != 0 && intAddend != 0 && !saveValue) {
// If not continuing with compound relocation (64-bit only)
// perform fixup so we can create offset-pointer now.
warnExternalOffsetRelocation(program, relocationAddress,
symbolAddr, symbolName, intAddend, mipsRelocationContext.getLog());
applyComponentOffsetPointer(program, relocationAddress, intAddend);
}
}
@ -451,7 +463,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
case MIPS_ElfRelocationConstants.R_MIPS_PC16:
newValue =
mipsRelocationContext.extractAddend() ? (oldValue & 0xffff) << 2 : (int) addend;
long newValueBig = signExtend(newValue, 18);
newValueBig = signExtend(newValue, 18);
newValueBig += symbolValue - offset;
value = (int) newValueBig;

View File

@ -22,6 +22,7 @@ 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
@ -30,6 +31,10 @@ 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
@ -52,13 +57,13 @@ def accept_file(li, filename):
# read 16K bytes to allow for the DTD
data = li.read(0x4000)
# look for start of <PROGRAM> element
start = data.find("<PROGRAM")
start = data.find(b"<PROGRAM")
if start >= 0:
s = data.find("<PROCESSOR ")
s = data.find(b"<PROCESSOR ")
p = data[s+11:]
e = p.find("/>")
e = p.find(b"/>")
proc = p[:e]
ida_kernwin.info("Processor specified in the XML file is:\n" + proc +
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 }
@ -83,19 +88,19 @@ def load_file(li, neflags, format):
status = xml.import_xml()
except idaxml.Cancelled:
msg = "XML PROGRAM import cancelled!"
print "\n" + msg
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
print("\n" + msg)
idc.warning(msg)
except:
print "\nHouston, we have a problem!"
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
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)

View File

@ -22,6 +22,7 @@ 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
@ -29,6 +30,10 @@ 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):
"""
@ -72,12 +77,12 @@ class XmlExporterPlugin(ida_idaapi.plugin_t):
except idaxml.Cancelled:
ida_kernwin.hide_wait_box()
msg = "XML Export cancelled!"
print "\n" + msg
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
print("\n" + msg + "\n", sys.exc_type, sys.exc_value)
idc.warning(msg)
finally:
xml.cleanup()

View File

@ -22,12 +22,18 @@ 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
@ -68,17 +74,17 @@ class XmlImporterPlugin(ida_idaapi.plugin_t):
xml.import_xml()
except idaxml.Cancelled:
msg = "XML Import cancelled!"
print "\n" + msg
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
print("\n" + msg)
idc.warning(msg)
except:
msg = "***** Exception occurred: XML Importer failed! *****"
print "\n" + msg + "\n", sys.exc_type, sys.exc_value
print("\n" + msg + "\n", sys.exc_type, sys.exc_value)
idc.warning(msg)
finally:
xml.cleanup()

View File

@ -19,6 +19,7 @@
"""
"""
from __future__ import print_function
import ida_auto
import ida_bytes
import ida_diskio
@ -52,10 +53,16 @@ import sys
import time
from xml.etree import cElementTree
if sys.version_info.major >= 3:
import copy
time.clock = time.perf_counter
_exc_info = copy.copy(sys.exc_info)
sys.exc_value = lambda: _exc_info()[1]
sys.exc_type = lambda: _exc_info()[0]
DEBUG = False # print debug statements
IDAXML_VERSION = "5.0.1"
IDAXML_VERSION = "5.0.2"
BASELINE_IDA_VERSION = 700
BASELINE_STR = '7.00'
IDA_SDK_VERSION = ida_pro.IDA_SDK_VERSION
@ -166,7 +173,19 @@ class IdaXml:
Args:
what: String indicating Exporter, Importer, or Loader
"""
f = ida_diskio.idadir('python') + '/idaxml.py'
if os.path.isfile(os.path.join(ida_diskio.idadir('python'), 'idaxml.py')):
f = os.path.join(ida_diskio.idadir('python'), 'idaxml.py')
elif os.path.isfile(os.path.join(ida_diskio.idadir('python'), '3', 'idaxml.py')):
f = os.path.join(ida_diskio.idadir('python'), '3', 'idaxml.py')
elif os.path.isfile(os.path.join(ida_diskio.idadir('python'), '2', 'idaxml.py')):
f = os.path.join(ida_diskio.idadir('python'), '2', 'idaxml.py')
elif os.path.isfile(os.path.join(ida_diskio.get_user_idadir(), 'python', 'idaxml.py')):
f = os.path.join(ida_diskio.get_user_idadir(), 'python', 'idaxml.py')
else:
msg = "Error opening file " + os.path.join(ida_diskio.idadir('python'), 'idaxml.py') + " !\n"
idc.msg(msg)
raise FileError
ftime = time.localtime(os.path.getmtime(f))
ts = time.strftime('%b %d %Y %H:%M:%S', ftime)
version = "\nXML " + what + " v" + IDAXML_VERSION
@ -254,7 +273,7 @@ class XmlExporter(IdaXml):
self.inf = ida_idaapi.get_inf_structure()
self.min_ea = self.inf.min_ea
self.max_ea = self.inf.max_ea
self.cbsize = (ida_idp.ph_get_cnbits()+7)/8
self.cbsize = (ida_idp.ph_get_cnbits()+7)//8
self.processor = str.upper(ida_idp.get_idp_name())
self.batch = ida_kernwin.cvar.batch
@ -373,6 +392,8 @@ class XmlExporter(IdaXml):
String containing either the character or the entity
substition string.
"""
if isinstance(ch, int):
ch = chr(ch)
if ((ord(ch) < 0x20) and (ord(ch) != 0x09 and
ord(ch) != 0x0A and ord(ch) != 0x0D)): return ''
elif ch == '&' : return '&amp;'
@ -647,7 +668,10 @@ class XmlExporter(IdaXml):
# tag_remove seems to be losing last character
# work around is to add a space
cmt_text = ida_lines.tag_remove(cmt + ' ')
self.write_text(cmt_text.decode('utf-8'))
if sys.version_info.major >= 3:
self.write_text(cmt_text)
else:
self.write_text(cmt_text.decode('utf-8'))
self.end_element(COMMENT, False)
@ -714,7 +738,7 @@ class XmlExporter(IdaXml):
if msize == 0:
msize = 1
if idc.is_strlit(f) == False and size != msize:
dtype = "%s[%d]" % (dtype, size/msize)
dtype = "%s[%d]" % (dtype, size//msize)
self.start_element(DEFINED_DATA)
self.write_address_attribute(ADDRESS, addr)
self.write_attribute(DATATYPE, dtype)
@ -1108,7 +1132,7 @@ class XmlExporter(IdaXml):
if size < msize: size = msize
if (size != msize):
arraytype = self.get_member_type(m)
dtype = "%s[%d]" % (arraytype, size/msize)
dtype = "%s[%d]" % (arraytype, size//msize)
self.write_attribute(DATATYPE, dtype)
self.write_numeric_attribute(SIZE, size*self.cbsize)
regcmt = ida_struct.get_member_cmt(m.id, False)
@ -1544,7 +1568,7 @@ class XmlExporter(IdaXml):
if size < msize: size = msize
if (idc.is_strlit(f) == False and ida_bytes.is_align(f) == False
and size != msize):
mtype = "%s[%d]" % (mtype, size/msize)
mtype = "%s[%d]" % (mtype, size//msize)
self.write_attribute(DATATYPE, mtype)
self.write_numeric_attribute(SIZE, size*self.cbsize)
regcmt = ida_struct.get_member_cmt(member.id, False)
@ -1781,7 +1805,7 @@ class XmlExporter(IdaXml):
return idc.get_struc_name(opnd.tid)
if idc.is_strlit(f) == True:
str_type = idc.get_str_type(addr)
#print ida_bytes.print_strlit_type(str_type)
#print(ida_bytes.print_strlit_type(str_type))
if str_type == ida_nalt.STRTYPE_TERMCHR: return "string"
if str_type == ida_nalt.STRTYPE_PASCAL: return "string1"
if str_type == ida_nalt.STRTYPE_LEN2: return "string2"
@ -2451,7 +2475,7 @@ class XmlImporter(IdaXml):
Integer representing the number of 8-bit bytes in an
addressable codebyte.
"""
return (ida_idp.ph_get_cnbits()+7)/8
return (ida_idp.ph_get_cnbits()+7)//8
def get_datatype_flags(self, datatype, size):
@ -2637,7 +2661,7 @@ class XmlImporter(IdaXml):
if idc.is_mapped(addr) == False:
msg = ("import_bookmark: address %X not enabled in database"
% addr)
print msg
print(msg)
return
self.update_counter(BOOKMARK)
for slot in range(ida_moves.MAX_MARK_SLOT):
@ -2647,7 +2671,7 @@ class XmlImporter(IdaXml):
break
except:
msg = "** Exception occurred in import_bookmark **"
print "\n" + msg + "\n", sys.exc_type, sys.exc_value
print("\n" + msg + "\n", sys.exc_type, sys.exc_value)
def import_cmts(self, element, sid, typ):
@ -2777,7 +2801,7 @@ class XmlImporter(IdaXml):
"""
self.update_counter(DESCRIPTION)
# TODO: import_description: decide what to do with DESCRIPTION
# print description.text
# print(description.text)
def import_enum(self, enum):
@ -2946,7 +2970,7 @@ class XmlImporter(IdaXml):
if idc.is_mapped(entry_point) == False:
msg = ("import_function: address %X not enabled in database"
% entry_point)
print msg
print(msg)
return
idc.add_func(entry_point, BADADDR)
self.update_counter(FUNCTION)
@ -2981,7 +3005,7 @@ class XmlImporter(IdaXml):
self.import_register_var(register_var, func)
except:
msg = "** Exception occurred in import_function **"
print "\n" + msg + "\n", sys.exc_type, sys.exc_value
print("\n" + msg + "\n", sys.exc_type, sys.exc_value)
def import_function_def(self, function_def):
@ -3205,7 +3229,7 @@ class XmlImporter(IdaXml):
# TODO: import_memory_reference: store refs? maybe only user-defined?
'''
if user == 'y':
#print "%08X %08X" % (addr, to_addr), op, primary
#print("%08X %08X" % (addr, to_addr), op, primary)
pass
'''
@ -3232,7 +3256,7 @@ class XmlImporter(IdaXml):
seg_str = ''
if '::' in addrstr:
# overlay - skip for now
print ' ** Overlayed memory block %s skipped ** ' % name
print(' ** Overlayed memory block %s skipped ** ' % name)
msg = 'Overlayed memory block %s skipped!' % name
msg += "\n\nXML Import does not currently support"
msg += "\noverlayed memory blocks."

View File

@ -74,9 +74,9 @@ ext.deps = [
destination: FLAT_REPO_DIR
],
[
name: "yajsw-stable-13.04.zip",
url: "https://sourceforge.net/projects/yajsw/files/yajsw/yajsw-stable-13.04/yajsw-stable-13.04.zip",
sha256: "9dd2f713e808be84acccc28ca83129d0ee8d5859d3f33c522baf5185a0fd1253",
name: "yajsw-stable-13.05.zip",
url: "https://sourceforge.net/projects/yajsw/files/yajsw/yajsw-stable-13.05/yajsw-stable-13.05.zip",
sha256: "ff7a4c8262f7d24079b16607122bad8f6fb024f051c27b91883d9498568429a9",
destination: file("${DEPS_DIR}/GhidraServer")
],
[