mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-26 22:21:52 +00:00
Merge remote-tracking branch
'origin/GP-3926_ryanmkurtz_macho-obfuscated' (Closes #3876)
This commit is contained in:
commit
585a94399a
@ -18,11 +18,13 @@ package ghidra.app.util.bin.format.macho;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import ghidra.app.util.bin.*;
|
||||
import ghidra.app.util.bin.format.macho.commands.*;
|
||||
import ghidra.app.util.opinion.DyldCacheUtils.SplitDyldCache;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.util.DataConverter;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
@ -186,6 +188,7 @@ public class MachHeader implements StructConverter {
|
||||
LoadCommand lc = LoadCommandFactory.getLoadCommand(_reader, this, splitDyldCache);
|
||||
_commands.add(lc);
|
||||
}
|
||||
sanitizeSegmentSectionNames(getAllSegments());
|
||||
_parsed = true;
|
||||
return this;
|
||||
}
|
||||
@ -211,6 +214,7 @@ public class MachHeader implements StructConverter {
|
||||
_reader.setPointerIndex(_reader.getPointerIndex() + size - 8);
|
||||
}
|
||||
}
|
||||
sanitizeSegmentSectionNames(segments);
|
||||
return segments;
|
||||
}
|
||||
|
||||
@ -383,6 +387,30 @@ public class MachHeader implements StructConverter {
|
||||
return getDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes invalid segment/section names so they can be used as memory blocks and program tree
|
||||
* modules
|
||||
*
|
||||
* @param segments A {@link List} of {@link SegmentCommand segments} to sanitize
|
||||
*/
|
||||
private void sanitizeSegmentSectionNames(List<SegmentCommand> segments) {
|
||||
Function<String, Boolean> invalid = s -> s.isBlank() || !Memory.isValidMemoryBlockName(s);
|
||||
for (int i = 0; i < segments.size(); i++) {
|
||||
SegmentCommand segment = segments.get(i);
|
||||
if (invalid.apply(segment.getSegmentName())) {
|
||||
segment.setSegmentName("__INVALID.%d".formatted(i));
|
||||
}
|
||||
List<Section> sections = segment.getSections();
|
||||
for (int j = 0; j < sections.size(); j++) {
|
||||
Section section = sections.get(j);
|
||||
section.setSegmentName(segment.getSegmentName());
|
||||
if (invalid.apply(section.getSectionName())) {
|
||||
section.setSectionName("__invalid.%d".formatted(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Mach Header byte array
|
||||
*
|
||||
|
@ -166,10 +166,18 @@ public class Section implements StructConverter {
|
||||
return sectname;
|
||||
}
|
||||
|
||||
public void setSectionName(String name) {
|
||||
this.sectname = name;
|
||||
}
|
||||
|
||||
public String getSegmentName() {
|
||||
return segname;
|
||||
}
|
||||
|
||||
public void setSegmentName(String name) {
|
||||
this.segname = name;
|
||||
}
|
||||
|
||||
public long getAddress() {
|
||||
// Mask off possible chained fixup found in kernelcache section addresses
|
||||
if ((addr & 0xfff000000000L) == 0xfff000000000L) {
|
||||
|
@ -106,6 +106,10 @@ public class SegmentCommand extends LoadCommand {
|
||||
return segname;
|
||||
}
|
||||
|
||||
public void setSegmentName(String name) {
|
||||
this.segname = name;
|
||||
}
|
||||
|
||||
public long getVMaddress() {
|
||||
// Mask off possible chained fixup found in kernelcache segment addresses
|
||||
if ((vmaddr & 0xfff000000000L) == 0xfff000000000L) {
|
||||
|
@ -196,32 +196,26 @@ public class MachoProgramBuilder {
|
||||
}
|
||||
|
||||
// Create memory blocks for segments.
|
||||
ListIterator<SegmentCommand> it = header.getAllSegments().listIterator();
|
||||
while (it.hasNext()) {
|
||||
int i = it.nextIndex();
|
||||
final SegmentCommand segment = it.next();
|
||||
|
||||
for (SegmentCommand segment : header.getAllSegments()) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (segment.getFileSize() > 0 && (allowZeroAddr || segment.getVMaddress() != 0)) {
|
||||
String segmentName = segment.getSegmentName();
|
||||
if (segmentName.isBlank()) {
|
||||
segmentName = "SEGMENT." + i;
|
||||
}
|
||||
if (createMemoryBlock(segmentName, space.getAddress(segment.getVMaddress()),
|
||||
segment.getFileOffset(), segment.getFileSize(), segmentName, source,
|
||||
segment.isRead(), segment.isWrite(), segment.isExecute(), false) == null) {
|
||||
if (createMemoryBlock(segment.getSegmentName(),
|
||||
space.getAddress(segment.getVMaddress()), segment.getFileOffset(),
|
||||
segment.getFileSize(), segment.getSegmentName(), source, segment.isRead(),
|
||||
segment.isWrite(), segment.isExecute(), false) == null) {
|
||||
log.appendMsg(String.format("Failed to create block: %s 0x%x 0x%x",
|
||||
segment.getSegmentName(), segment.getVMaddress(), segment.getVMsize()));
|
||||
}
|
||||
if (segment.getVMsize() > segment.getFileSize()) {
|
||||
// Pad the remaining address range with uninitialized data
|
||||
if (createMemoryBlock(segmentName,
|
||||
if (createMemoryBlock(segment.getSegmentName(),
|
||||
space.getAddress(segment.getVMaddress()).add(segment.getFileSize()), 0,
|
||||
segment.getVMsize() - segment.getFileSize(), segmentName, source,
|
||||
segment.isRead(), segment.isWrite(), segment.isExecute(), true) == null) {
|
||||
segment.getVMsize() - segment.getFileSize(), segment.getSegmentName(),
|
||||
source, segment.isRead(), segment.isWrite(), segment.isExecute(),
|
||||
true) == null) {
|
||||
log.appendMsg(String.format("Failed to create block: %s 0x%x 0x%x",
|
||||
segment.getSegmentName(), segment.getVMaddress(), segment.getVMsize()));
|
||||
}
|
||||
@ -341,11 +335,7 @@ public class MachoProgramBuilder {
|
||||
*/
|
||||
protected void fixupProgramTree() throws Exception {
|
||||
ProgramModule rootModule = listing.getDefaultRootModule();
|
||||
ListIterator<SegmentCommand> it = machoHeader.getAllSegments().listIterator();
|
||||
while (it.hasNext()) {
|
||||
int i = it.nextIndex();
|
||||
SegmentCommand segment = it.next();
|
||||
|
||||
for (SegmentCommand segment : machoHeader.getAllSegments()) {
|
||||
if (segment.getVMsize() == 0) {
|
||||
continue;
|
||||
}
|
||||
@ -361,9 +351,6 @@ public class MachoProgramBuilder {
|
||||
// section fragments, it will represent the parts of the segment that weren't in any
|
||||
// section.
|
||||
String segmentName = segment.getSegmentName();
|
||||
if (segmentName.isBlank()) {
|
||||
segmentName = "SEGMENT." + i;
|
||||
}
|
||||
String noSectionsName = segmentName + " <no section>";
|
||||
ProgramFragment segmentFragment = null;
|
||||
for (Group group : rootModule.getChildren()) {
|
||||
|
Loading…
Reference in New Issue
Block a user