Merge remote-tracking branch 'origin/GP-6434_dev747368_rust_elf_binary_id'

This commit is contained in:
Ryan Kurtz
2026-03-17 05:04:07 -04:00
18 changed files with 79 additions and 59 deletions
@@ -107,7 +107,7 @@ public class Lisa_ResolveX86orX64LinuxSyscallsScript extends GhidraScript {
@Override
protected void run() throws Exception {
if (!(currentProgram.getExecutableFormat().equals(ElfLoader.ELF_NAME) &&
if (!(ElfLoader.isElf(currentProgram) &&
currentProgram.getLanguage().getProcessor().toString().equals(X86))) {
popup("This script is intended for x86 or x64 Linux files");
return;
@@ -71,7 +71,7 @@ public class EmuX86DeobfuscateExampleScript extends GhidraScript {
if (currentProgram == null || !currentProgram.getName().startsWith(PROGRAM_NAME) ||
!"x86:LE:64:default".equals(currentProgram.getLanguageID().toString()) ||
!ElfLoader.ELF_NAME.equals(format)) {
!ElfLoader.isElf(format)) {
printerr("""
This emulation example script is specifically intended to be executed against
@@ -75,7 +75,7 @@ public class EmuX86GccDeobfuscateHookExampleScript extends GhidraScript {
if (currentProgram == null || !currentProgram.getName().startsWith(PROGRAM_NAME) ||
!"x86:LE:64:default".equals(currentProgram.getLanguageID().toString()) ||
!ElfLoader.ELF_NAME.equals(format)) {
!ElfLoader.isElf(format)) {
printerr("""
This emulation example script is specifically intended to be executed against
@@ -93,7 +93,7 @@ public class ResolveX86orX64LinuxSyscallsScript extends GhidraScript {
@Override
protected void run() throws Exception {
if (!(currentProgram.getExecutableFormat().equals(ElfLoader.ELF_NAME) &&
if (!(ElfLoader.isElf(currentProgram) &&
currentProgram.getLanguage().getProcessor().toString().equals(X86))) {
popup("This script is intended for x86 or x64 Linux files");
return;
@@ -1,13 +1,12 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* 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.
@@ -37,14 +36,14 @@ public class ElfScalarOperandAnalyzer extends ScalarOperandAnalyzer {
@Override
public boolean canAnalyze(Program program) {
boolean elf = isELF(program);
boolean elf = ElfLoader.isElf(program);
return elf;
}
@Override
public boolean getDefaultEnablement(Program program) {
if (!isELF(program)) {
if (!ElfLoader.isElf(program)) {
return false;
}
return getDefaultEnablement2(program);
@@ -61,7 +60,7 @@ public class ElfScalarOperandAnalyzer extends ScalarOperandAnalyzer {
@Override
protected boolean addReference(Program program, Instruction instr, int opIndex,
AddressSpace space, Scalar scalar) {
if (program.getExecutableFormat().equals(ElfLoader.ELF_NAME)) {
if (ElfLoader.isElf(program)) {
if (instr.getMnemonicString().equalsIgnoreCase("add")) {
try {
Address gotAddr = instr.getMinAddress().add(scalar.getUnsignedValue());
@@ -57,7 +57,7 @@ public class ExternalSymbolResolverAnalyzer extends AbstractAnalyzer {
}
String format = program.getExecutableFormat();
return ElfLoader.ELF_NAME.equals(format) || MachoLoader.MACH_O_NAME.equals(format);
return ElfLoader.isElf(format) || MachoLoader.MACH_O_NAME.equals(format);
}
@Override
@@ -4,9 +4,9 @@
* 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.
@@ -67,13 +67,9 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
setPriority(AnalysisPriority.REFERENCE_ANALYSIS.before().before());
}
protected boolean isELF(Program program) {
return ElfLoader.ELF_NAME.equals(program.getExecutableFormat());
}
@Override
public boolean canAnalyze(Program program) {
return !isELF(program);
return !ElfLoader.isElf(program);
}
@Override
@@ -363,7 +359,7 @@ public class ScalarOperandAnalyzer extends AbstractAnalyzer {
@Override
public boolean getDefaultEnablement(Program program) {
if (isELF(program)) {
if (ElfLoader.isElf(program)) {
return false;
}
return getDefaultEnablement2(program);
@@ -23,6 +23,8 @@ import org.xml.sax.SAXException;
import generic.jar.ResourceFile;
import ghidra.app.plugin.processors.sleigh.SleighException;
import ghidra.app.util.bin.format.elf.info.ElfComment;
import ghidra.app.util.opinion.ElfLoader;
import ghidra.framework.Application;
import ghidra.framework.store.LockException;
import ghidra.program.database.SpecExtension;
@@ -43,8 +45,12 @@ import ghidra.xml.XmlParseException;
*/
public class RustUtilities {
private static final java.util.regex.Pattern ELF_COMMENT_REGEX =
java.util.regex.Pattern.compile("^rustc version .*$");
/**
* Checks if a given {@link MemoryBlock} contains a Rust signature
* Checks if the specified program contains Rust stuff, either by metadata or by searching
* the specified {@link MemoryBlock} for byte pattern signatures.
* <p>
* This may be used by loaders to determine if a program was compiled with rust.
* If the program is determined to be rust, then the compiler property is set to
@@ -60,6 +66,20 @@ public class RustUtilities {
*/
public static boolean isRust(Program program, MemoryBlock block, TaskMonitor monitor)
throws IOException, CancelledException {
if ( ElfLoader.isElf(program)) {
// ELF binaries can contain a ".comment" section that records the toolchains that
// produced the binary. Search this first as its quick and easy.
ElfComment elfComments = ElfComment.fromProgram(program);
if ( elfComments != null ) {
for(String s : elfComments.getCommentStrings() ) {
if (ELF_COMMENT_REGEX.matcher(s).matches()) {
return true;
}
}
}
}
if (block == null) {
return false;
}
@@ -283,7 +283,7 @@ public class GoBuildInfo implements ElfInfoItem {
public static String getProgramGOOS(Program program) {
// TODO: this mapping needs more logic
String loaderName = program.getExecutableFormat();
if (ElfLoader.ELF_NAME.equals(loaderName)) {
if (ElfLoader.isElf(loaderName)) {
// TODO: this will require additional work to map all Go OSs to Ghidra loader info
return "linux";
}
@@ -61,6 +61,22 @@ public class ElfLoader extends AbstractLibrarySupportLoader {
return (oibStr != null) ? NumericUtilities.parseHexLong(oibStr) : null;
}
/**
* {@return true if the specified program was loaded via the ELF loader}
* @param program {@link Program}
*/
public static boolean isElf(Program program) {
return isElf(program.getExecutableFormat());
}
/**
* {@return true if the specified executable format string matches the ELF loader}
* @param executableFormatString executable format string retrieved from a program's properties
*/
public static boolean isElf(String executableFormatString) {
return executableFormatString != null && ELF_NAME.equals(executableFormatString);
}
public ElfLoader() {
}
@@ -4,9 +4,9 @@
* 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.
@@ -19,9 +19,7 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.ByteProvider;
import ghidra.app.util.bin.MemoryByteProvider;
import ghidra.app.util.bin.*;
import ghidra.app.util.bin.format.elf.ElfSectionHeaderConstants;
import ghidra.app.util.importer.MessageLog;
import ghidra.app.util.opinion.ElfLoader;
@@ -63,8 +61,7 @@ public final class OatUtilities {
*/
public static boolean isOAT(Program program) {
if (program != null) {
String executableFormat = program.getExecutableFormat();
if (ElfLoader.ELF_NAME.equals(executableFormat)) {
if (ElfLoader.isElf(program)) {
MemoryBlock roDataBlock =
program.getMemory().getBlock(ElfSectionHeaderConstants.dot_rodata);
if (roDataBlock != null) {
@@ -77,12 +74,8 @@ public final class OatUtilities {
return false;
}
public static boolean isELF(Program program) {
return ElfLoader.ELF_NAME.equals(program.getExecutableFormat());
}
public static Symbol getOatDataSymbol(Program program) {
if (isELF(program)) {
if (ElfLoader.isElf(program)) {
MemoryBlock block = program.getMemory().getBlock(ElfSectionHeaderConstants.dot_rodata);
if (block != null) {
SymbolTable symbolTable = program.getSymbolTable();
@@ -97,7 +90,7 @@ public final class OatUtilities {
}
public static Symbol getOatExecSymbol(Program program) {
if (isELF(program)) {
if (ElfLoader.isElf(program)) {
MemoryBlock block = program.getMemory().getBlock(ElfSectionHeaderConstants.dot_text);
if (block != null) {
SymbolTable symbolTable = program.getSymbolTable();
@@ -112,7 +105,7 @@ public final class OatUtilities {
}
public static Symbol getOatLastWordSymbol(Program program) {
if (isELF(program)) {
if (ElfLoader.isElf(program)) {
MemoryBlock block = program.getMemory().getBlock(ElfSectionHeaderConstants.dot_text);
if (block != null) {
SymbolTable symbolTable = program.getSymbolTable();
@@ -47,7 +47,7 @@ public class GnuDemangler implements Demangler {
public boolean canDemangle(Program program) {
String executableFormat = program.getExecutableFormat();
if (isELF(executableFormat) || isMacho(executableFormat)) {
if (ElfLoader.isElf(executableFormat) || isMacho(executableFormat)) {
return true;
}
@@ -282,10 +282,6 @@ public class GnuDemangler implements Demangler {
//@formatter:on
}
private boolean isELF(String executableFormat) {
return executableFormat != null && executableFormat.indexOf(ElfLoader.ELF_NAME) != -1;
}
private boolean isMacho(String executableFormat) {
return executableFormat != null && executableFormat.indexOf(MachoLoader.MACH_O_NAME) != -1;
}
@@ -4,9 +4,9 @@
* 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.
@@ -188,7 +188,7 @@ public class ElfArmRelocationFixupHandler extends ElfRelocationFixupHandler {
@Override
public boolean handlesProgram(Program program) {
if (!ElfLoader.ELF_NAME.equals(program.getExecutableFormat())) {
if (!ElfLoader.isElf(program)) {
return false;
}
Language language = program.getLanguage();
@@ -4,9 +4,9 @@
* 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.
@@ -52,7 +52,7 @@ public class Pic24DInitAnalyzer extends AbstractAnalyzer {
if (!isSupportedProcessor) {
return false;
}
if (!ElfLoader.ELF_NAME.equals(program.getExecutableFormat())) {
if (!ElfLoader.isElf(program)) {
return false;
}
return program.getMemory().getBlock(".dinit") != null;
@@ -4,9 +4,9 @@
* 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.
@@ -86,12 +86,12 @@ public class PowerPCAddressAnalyzer extends ConstantPropagationAnalyzer {
private boolean getDefaultPropagateR2Option(Program program) {
// TODO: R2 propagation had been disabled for PEF - should it be enabled by default?
boolean isELF = ElfLoader.ELF_NAME.equals(program.getExecutableFormat());
boolean isELF = ElfLoader.isElf(program);
return isELF && program.getLanguage().getLanguageDescription().getSize() == 64;
}
private boolean getDefaultPropagateR30Option(Program program) {
boolean isELF = ElfLoader.ELF_NAME.equals(program.getExecutableFormat());
boolean isELF = ElfLoader.isElf(program);
boolean is32bit = program.getLanguage().getLanguageDescription().getSize() == 32;
// The use of r30 as a GOT pointer during function calls can occurs with the V1.0 ABI
// for relocatable PIC code. The presence of the dynamic table entry DT_PPC_GOT
@@ -4,9 +4,9 @@
* 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.
@@ -65,7 +65,7 @@ public class ElfSH4RelocationFixupHandler extends ElfRelocationFixupHandler {
@Override
public boolean handlesProgram(Program program) {
if (!ElfLoader.ELF_NAME.equals(program.getExecutableFormat())) {
if (!ElfLoader.isElf(program)) {
return false;
}
Language language = program.getLanguage();
@@ -4,9 +4,9 @@
* 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.
@@ -66,7 +66,7 @@ public class Elfx86_32bitRelocationFixupHandler extends ElfRelocationFixupHandle
@Override
public boolean handlesProgram(Program program) {
if (!ElfLoader.ELF_NAME.equals(program.getExecutableFormat())) {
if (!ElfLoader.isElf(program)) {
return false;
}
Language language = program.getLanguage();
@@ -4,9 +4,9 @@
* 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.
@@ -64,7 +64,7 @@ public class Elfx86_64bitRelocationFixupHandler extends ElfRelocationFixupHandle
@Override
public boolean handlesProgram(Program program) {
if (!ElfLoader.ELF_NAME.equals(program.getExecutableFormat())) {
if (!ElfLoader.isElf(program)) {
return false;
}
Language language = program.getLanguage();