mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Merge remote-tracking branch 'origin/Ghidra_11.1'
This commit is contained in:
commit
1a07f05e1d
4 changed files with 58 additions and 36 deletions
|
@ -60,7 +60,10 @@
|
||||||
<P>NOTE: Each build distribution will include native components (e.g., decompiler) for at least one platform (e.g., Windows x86-64).
|
<P>NOTE: Each build distribution will include native components (e.g., decompiler) for at least one platform (e.g., Windows x86-64).
|
||||||
If you have another platform that is not included in the build distribution, you can build
|
If you have another platform that is not included in the build distribution, you can build
|
||||||
native components for your platform directly from the distribution.
|
native components for your platform directly from the distribution.
|
||||||
See the <a href="InstallationGuide.html">Ghidra Installation Guide</a> for additional information.</P>
|
See the <a href="InstallationGuide.html">Ghidra Installation Guide</a> for additional information.
|
||||||
|
Users running with older shared libraries and operating systems (e.g., CentOS 7.x) may also run into
|
||||||
|
compatibility errors when launching native executables such as the Decompiler and GNU Demangler which
|
||||||
|
may necessitate a rebuild of native components.</P>
|
||||||
|
|
||||||
<P>IMPORTANT: To use the Debugger, you will need Python3 (3.7 to 3.12 supported) installed on your system.</P>
|
<P>IMPORTANT: To use the Debugger, you will need Python3 (3.7 to 3.12 supported) installed on your system.</P>
|
||||||
|
|
||||||
|
@ -170,8 +173,8 @@
|
||||||
<LI>Standard keyboard navigation should now work in most component windows and dialogs. In general, <span class="gtitle">Tab</span> and <span class="gtitle"><CTRL> Tab</span> will
|
<LI>Standard keyboard navigation should now work in most component windows and dialogs. In general, <span class="gtitle">Tab</span> and <span class="gtitle"><CTRL> Tab</span> will
|
||||||
move focus to the next focusable component and <span class="gtitle"><SHIFT> Tab</span> and <span class="gtitle"><CTRL><SHIFT> Tab</span> will move to the
|
move focus to the next focusable component and <span class="gtitle"><SHIFT> Tab</span> and <span class="gtitle"><CTRL><SHIFT> Tab</span> will move to the
|
||||||
previous focusable component. <span class="gtitle">Tab</span> and <span class="gtitle"><SHIFT> Tab</span> do not always work as some components use those keys internally, but
|
previous focusable component. <span class="gtitle">Tab</span> and <span class="gtitle"><SHIFT> Tab</span> do not always work as some components use those keys internally, but
|
||||||
<span class="gtitle"><CTRL> Tab,</span> and <span class="gtitle"><SHIFT><CTRL> Tab</span> should work universally.
|
<span class="gtitle"><CTRL> Tab,</span> and <span class="gtitle"><SHIFT><CTRL> Tab</span> should work universally.</LI>
|
||||||
<LI>Ghidra now provides some convenient keyboard shortcut actions for transferring focus:
|
<LI>Ghidra now provides some convenient keyboard shortcut actions for transferring focus:</LI>
|
||||||
<UL style="padding-left:50px">
|
<UL style="padding-left:50px">
|
||||||
<LI><span class="gtitle"><CTRL> F3</span> - Transfers focus to the next window or dialog.</LI>
|
<LI><span class="gtitle"><CTRL> F3</span> - Transfers focus to the next window or dialog.</LI>
|
||||||
<LI><span class="gtitle"><CTRL><SHIFT> F3</span> - Transfers focus to the previous window or dialog.</LI>
|
<LI><span class="gtitle"><CTRL><SHIFT> F3</span> - Transfers focus to the previous window or dialog.</LI>
|
||||||
|
|
|
@ -39,6 +39,7 @@ else:
|
||||||
def main():
|
def main():
|
||||||
# Delay these imports until sys.path is patched
|
# Delay these imports until sys.path is patched
|
||||||
from ghidradbg import commands as cmd
|
from ghidradbg import commands as cmd
|
||||||
|
from ghidradbg.hooks import on_stop
|
||||||
from ghidradbg.util import dbg
|
from ghidradbg.util import dbg
|
||||||
|
|
||||||
# So that the user can re-enter by typing repl()
|
# So that the user can re-enter by typing repl()
|
||||||
|
@ -51,15 +52,17 @@ def main():
|
||||||
args = ' ' + args
|
args = ' ' + args
|
||||||
cmd.ghidra_trace_create(
|
cmd.ghidra_trace_create(
|
||||||
os.getenv('OPT_TARGET_IMG') + args, start_trace=False)
|
os.getenv('OPT_TARGET_IMG') + args, start_trace=False)
|
||||||
cmd.ghidra_trace_start(os.getenv('OPT_TARGET_IMG'))
|
|
||||||
cmd.ghidra_trace_sync_enable()
|
|
||||||
|
|
||||||
# TODO: HACK
|
# TODO: HACK
|
||||||
try:
|
try:
|
||||||
dbg.wait()
|
dbg.wait()
|
||||||
except KeyboardInterrupt as ki:
|
except KeyboardInterrupt as ki:
|
||||||
dbg.interrupt()
|
dbg.interrupt()
|
||||||
|
|
||||||
|
cmd.ghidra_trace_start(os.getenv('OPT_TARGET_IMG'))
|
||||||
|
cmd.ghidra_trace_sync_enable()
|
||||||
|
|
||||||
|
on_stop()
|
||||||
cmd.repl()
|
cmd.repl()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@ from . import util
|
||||||
|
|
||||||
|
|
||||||
language_map = {
|
language_map = {
|
||||||
'ARM': ['AARCH64:BE:64:v8A', 'AARCH64:LE:64:AppleSilicon', 'AARCH64:LE:64:v8A', 'ARM:BE:64:v8', 'ARM:LE:64:v8'],
|
'AARCH64': ['AARCH64:LE:64:AppleSilicon'],
|
||||||
|
'ARM': ['ARM:LE:32:v8'],
|
||||||
'Itanium': [],
|
'Itanium': [],
|
||||||
'x86': ['x86:LE:32:default'],
|
'x86': ['x86:LE:32:default'],
|
||||||
'x86_64': ['x86:LE:64:default'],
|
'x86_64': ['x86:LE:64:default'],
|
||||||
|
@ -37,7 +38,7 @@ x86_compiler_map = {
|
||||||
}
|
}
|
||||||
|
|
||||||
arm_compiler_map = {
|
arm_compiler_map = {
|
||||||
'windows': 'windows',
|
'windows': 'default',
|
||||||
}
|
}
|
||||||
|
|
||||||
compiler_map = {
|
compiler_map = {
|
||||||
|
@ -57,12 +58,14 @@ def get_arch():
|
||||||
try:
|
try:
|
||||||
type = util.dbg.get_actual_processor_type()
|
type = util.dbg.get_actual_processor_type()
|
||||||
except Exception:
|
except Exception:
|
||||||
#print("Error getting actual processor type.")
|
print("Error getting actual processor type.")
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
if type is None:
|
if type is None:
|
||||||
return "x86_64"
|
return "x86_64"
|
||||||
if type == 0x8664:
|
if type == 0x8664:
|
||||||
return "x86_64"
|
return "x86_64"
|
||||||
|
if type == 0xAA64:
|
||||||
|
return "AARCH64"
|
||||||
if type == 0x014c:
|
if type == 0x014c:
|
||||||
return "x86"
|
return "x86"
|
||||||
if type == 0x01c0:
|
if type == 0x01c0:
|
||||||
|
|
|
@ -54,18 +54,18 @@ public class X86_32_ElfExtension extends ElfExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
super.processGotPlt(elfLoadHelper, monitor);
|
super.processGotPlt(elfLoadHelper, monitor);
|
||||||
|
|
||||||
processX86Plt(elfLoadHelper, monitor);
|
processX86PltSections(elfLoadHelper, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the case where GOT entry offset are computed based upon EBX.
|
* Handle the case where GOT entry offset are computed based upon EBX.
|
||||||
* This implementation replaces the old "magic map" which had previously been used.
|
* This implementation replaces the old "magic map" which had previously been used.
|
||||||
* @param elfLoadHelper
|
* @param elfLoadHelper ELF load helper
|
||||||
* @param monitor
|
* @param monitor task monitor
|
||||||
* @throws CancelledException
|
* @throws CancelledException thrown if load cancelled
|
||||||
*/
|
*/
|
||||||
private void processX86Plt(ElfLoadHelper elfLoadHelper, TaskMonitor monitor) throws CancelledException {
|
private void processX86PltSections(ElfLoadHelper elfLoadHelper, TaskMonitor monitor) throws CancelledException {
|
||||||
|
|
||||||
// TODO: Does 64-bit have a similar mechanism?
|
// TODO: Does 64-bit have a similar mechanism?
|
||||||
|
|
||||||
|
@ -73,37 +73,50 @@ public class X86_32_ElfExtension extends ElfExtension {
|
||||||
// the unresolved issue is to determine the length of the PLT area without a section
|
// the unresolved issue is to determine the length of the PLT area without a section
|
||||||
|
|
||||||
ElfHeader elfHeader = elfLoadHelper.getElfHeader();
|
ElfHeader elfHeader = elfLoadHelper.getElfHeader();
|
||||||
ElfSectionHeader pltSection = elfHeader.getSection(ElfSectionHeaderConstants.dot_plt);
|
|
||||||
if (pltSection == null || !pltSection.isExecutable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ElfDynamicTable dynamicTable = elfHeader.getDynamicTable();
|
ElfDynamicTable dynamicTable = elfHeader.getDynamicTable();
|
||||||
if (dynamicTable == null || !dynamicTable.containsDynamicValue(ElfDynamicType.DT_PLTGOT)) {
|
if (dynamicTable == null || !dynamicTable.containsDynamicValue(ElfDynamicType.DT_PLTGOT)) {
|
||||||
return; // avoid NotFoundException which causes issues for importer
|
return; // avoid NotFoundException which causes issues for importer
|
||||||
}
|
}
|
||||||
|
|
||||||
Program program = elfLoadHelper.getProgram();
|
long pltgotOffset;
|
||||||
Memory memory = program.getMemory();
|
|
||||||
|
|
||||||
// MemoryBlock pltBlock = getBlockPLT(pltSection);
|
|
||||||
MemoryBlock pltBlock = memory.getBlock(pltSection.getNameAsString());
|
|
||||||
if (pltBlock == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Paint pltgot base over .plt section to allow thunks to be resolved during analysis
|
|
||||||
Register ebxReg = program.getRegister("EBX");
|
|
||||||
try {
|
try {
|
||||||
long pltgotOffset = elfHeader.adjustAddressForPrelink(dynamicTable.getDynamicValue(
|
pltgotOffset = elfHeader.adjustAddressForPrelink(dynamicTable.getDynamicValue(
|
||||||
ElfDynamicType.DT_PLTGOT));
|
ElfDynamicType.DT_PLTGOT));
|
||||||
pltgotOffset = elfLoadHelper.getDefaultAddress(pltgotOffset).getOffset(); // adjusted for image base
|
pltgotOffset = elfLoadHelper.getDefaultAddress(pltgotOffset).getOffset(); // adjusted for image base
|
||||||
RegisterValue pltgotValue = new RegisterValue(ebxReg, BigInteger.valueOf(pltgotOffset));
|
}
|
||||||
program.getProgramContext().setRegisterValue(pltBlock.getStart(), pltBlock.getEnd(), pltgotValue);
|
catch (NotFoundException e) {
|
||||||
} catch (NotFoundException | ContextChangeException e) {
|
|
||||||
throw new AssertException("unexpected", e);
|
throw new AssertException("unexpected", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Program program = elfLoadHelper.getProgram();
|
||||||
|
Register ebxReg = program.getRegister("EBX");
|
||||||
|
Memory memory = program.getMemory();
|
||||||
|
|
||||||
|
String pltPrefix = ElfSectionHeaderConstants.dot_plt + ".";
|
||||||
|
|
||||||
|
for (ElfSectionHeader section : elfHeader.getSections()) {
|
||||||
|
monitor.checkCancelled();
|
||||||
|
String sectionName = section.getNameAsString();
|
||||||
|
if (!section.isExecutable()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (sectionName.equals(ElfSectionHeaderConstants.dot_plt) || sectionName.startsWith(pltPrefix)) {
|
||||||
|
|
||||||
|
MemoryBlock pltBlock = memory.getBlock(sectionName);
|
||||||
|
if (pltBlock == null) {
|
||||||
|
elfLoadHelper.log("Skipped processing of " + sectionName + ": memory block not found");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paint pltgot base over .plt section as EBX value to allow thunks to be resolved during analysis
|
||||||
|
try {
|
||||||
|
RegisterValue pltgotValue = new RegisterValue(ebxReg, BigInteger.valueOf(pltgotOffset));
|
||||||
|
program.getProgramContext().setRegisterValue(pltBlock.getStart(), pltBlock.getEnd(), pltgotValue);
|
||||||
|
} catch (ContextChangeException e) {
|
||||||
|
throw new AssertException("unexpected", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue