Skip to content

Commit

Permalink
test: check contents of COFF symbol and relocation tables
Browse files Browse the repository at this point in the history
  • Loading branch information
boricj committed Jun 12, 2024
1 parent 6cf8cd2 commit 04338fd
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 7 deletions.
44 changes: 41 additions & 3 deletions src/test/java/ghidra/DelinkerIntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import ghidra.app.util.bin.FileByteProvider;
import ghidra.app.util.bin.format.coff.CoffFileHeader;
import ghidra.app.util.bin.format.coff.CoffSectionHeader;
import ghidra.app.util.bin.format.coff.CoffSymbolSectionNumber;
import ghidra.app.util.bin.format.elf.ElfException;
import ghidra.app.util.bin.format.elf.ElfHeader;
import ghidra.app.util.bin.format.elf.ElfRelocation;
Expand Down Expand Up @@ -194,13 +195,50 @@ public CoffObjectFile(Program program, File file) throws IOException {

@Override
public byte[] getSectionBytes(String name) throws IOException {
CoffSectionHeader section = getSection(name);
return byteProvider.readBytes(section.getPointerToRawData(),
section.getSize(program.getLanguage()));
}

public void hasSymbolAtAddress(String symbolName, String sectionName, int offset) {
assertTrue(header.getSymbols()
.stream()
.filter(symbol -> symbol.getName().equals(symbolName))
.anyMatch(symbol -> {
CoffSectionHeader section =
header.getSections().get(symbol.getSectionNumber() - 1);
return section.getName().equals(sectionName) && symbol.getValue() == offset;
}));
}

public void hasUndefinedSymbol(String symbolName) {
assertTrue(header.getSymbols()
.stream()
.filter(symbol -> symbol.getName().equals(symbolName))
.anyMatch(
symbol -> symbol.getSectionNumber() == CoffSymbolSectionNumber.N_UNDEF));
}

public void hasRelocationAtAddress(String sectionName, long offset, int type,
String symbolName) {
CoffSectionHeader section = getSection(sectionName);
assertTrue(section.getRelocations()
.stream()
.filter(r -> r.getAddress() == offset)
.anyMatch(r -> header.getSymbolAtIndex(r.getSymbolIndex())
.getName()
.equals(symbolName) &&
r.getType() == type));
}

private CoffSectionHeader getSection(String name) {
CoffSectionHeader section = header.getSections()
.stream()
.filter(s -> s.getName().equals(name))
.findFirst()
.get();
return byteProvider.readBytes(section.getPointerToRawData(),
section.getSize(program.getLanguage()));
.orElse(null);
assertNotNull(section);
return section;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.junit.Test;

import ghidra.DelinkerIntegrationTest;
import ghidra.app.util.bin.format.coff.relocation.X86_32_CoffRelocationHandler;
import ghidra.app.util.exporter.CoffRelocatableObjectExporter;
import ghidra.program.model.address.AddressFactory;
import ghidra.program.model.address.AddressSetView;
Expand All @@ -40,10 +41,89 @@ public void testExport_main_o() throws Exception {
File exportedFile = exportObjectFile(set, new CoffRelocatableObjectExporter(), null);

ObjectFile mainObjectFile = new CoffObjectFile(getProgram(), mainFile);
ObjectFile exportedObjectFile = new CoffObjectFile(getProgram(), exportedFile);
CoffObjectFile exported = new CoffObjectFile(getProgram(), exportedFile);

mainObjectFile.compareSectionBytes(".text$mn", exportedObjectFile, ".text");
mainObjectFile.compareSectionBytes(".data", exportedObjectFile, ".data");
mainObjectFile.compareSectionBytes(".rdata", exportedObjectFile, ".rdata");
mainObjectFile.compareSectionBytes(".text$mn", exported, ".text");
mainObjectFile.compareSectionBytes(".data", exported, ".data");
mainObjectFile.compareSectionBytes(".rdata", exported, ".rdata");

exported.hasSymbolAtAddress("_print_number", ".text", 0x00000000);
exported.hasSymbolAtAddress("_print_ascii_entry", ".text", 0x00000070);
exported.hasSymbolAtAddress("_main", ".text", 0x00000120);
exported.hasSymbolAtAddress("_NUM_ASCII_PROPERTIES", ".rdata", 0x00000000);
exported.hasSymbolAtAddress("_s_ascii_properties", ".rdata", 0x00000008);
exported.hasSymbolAtAddress("_COLUMNS", ".data", 0x00000000);

exported.hasUndefinedSymbol("_putchar");
exported.hasUndefinedSymbol("_isalnum");
exported.hasUndefinedSymbol("_isalpha");
exported.hasUndefinedSymbol("_iscntrl");
exported.hasUndefinedSymbol("_isdigit");
exported.hasUndefinedSymbol("_isgraph");
exported.hasUndefinedSymbol("_islower");
exported.hasUndefinedSymbol("_isprint");
exported.hasUndefinedSymbol("_ispunct");
exported.hasUndefinedSymbol("_isspace");
exported.hasUndefinedSymbol("_isupper");

exported.hasRelocationAtAddress(".text", 0x00000047,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_REL32, "_putchar");
exported.hasRelocationAtAddress(".text", 0x00000058,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_REL32, "_putchar");
exported.hasRelocationAtAddress(".text", 0x0000007C,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_REL32, "_print_number");
exported.hasRelocationAtAddress(".text", 0x00000086,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_REL32, "_putchar");
exported.hasRelocationAtAddress(".text", 0x00000093,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_REL32, "_isgraph");
exported.hasRelocationAtAddress(".text", 0x000000A4,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_REL32, "_putchar");
exported.hasRelocationAtAddress(".text", 0x000000B0,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_REL32, "_putchar");
exported.hasRelocationAtAddress(".text", 0x000000BA,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_REL32, "_putchar");
exported.hasRelocationAtAddress(".text", 0x00000103,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_REL32, "_putchar");
exported.hasRelocationAtAddress(".text", 0x0000010F,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_REL32, "_putchar");
exported.hasRelocationAtAddress(".text", 0x00000147,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_COLUMNS");
exported.hasRelocationAtAddress(".text", 0x00000154,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_COLUMNS");
exported.hasRelocationAtAddress(".text", 0x00000164,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_COLUMNS");
exported.hasRelocationAtAddress(".text", 0x00000170,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_NUM_ASCII_PROPERTIES");
exported.hasRelocationAtAddress(".text", 0x00000176,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_s_ascii_properties");
exported.hasRelocationAtAddress(".text", 0x00000180,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_REL32, "_print_ascii_entry");
exported.hasRelocationAtAddress(".text", 0x0000018D,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_COLUMNS");
exported.hasRelocationAtAddress(".text", 0x00000192,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_COLUMNS");
exported.hasRelocationAtAddress(".text", 0x000001B2,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_REL32, "_putchar");

exported.hasRelocationAtAddress(".rdata", 0x00000008,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_isgraph");
exported.hasRelocationAtAddress(".rdata", 0x00000010,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_isprint");
exported.hasRelocationAtAddress(".rdata", 0x00000018,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_iscntrl");
exported.hasRelocationAtAddress(".rdata", 0x00000020,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_isspace");
exported.hasRelocationAtAddress(".rdata", 0x00000028,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_ispunct");
exported.hasRelocationAtAddress(".rdata", 0x00000030,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_isalnum");
exported.hasRelocationAtAddress(".rdata", 0x00000038,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_isalpha");
exported.hasRelocationAtAddress(".rdata", 0x00000040,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_isdigit");
exported.hasRelocationAtAddress(".rdata", 0x00000048,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_isupper");
exported.hasRelocationAtAddress(".rdata", 0x00000050,
X86_32_CoffRelocationHandler.IMAGE_REL_I386_DIR32, "_islower");
}
}

0 comments on commit 04338fd

Please sign in to comment.