Added x86:LE:16:Protected Mode

This commit is contained in:
caheckman 2019-08-22 16:44:59 -04:00
parent cbf7b80587
commit 8240d3c8db
9 changed files with 78 additions and 32 deletions

View file

@ -306,11 +306,6 @@ public class NeLoader extends AbstractLibrarySupportLoader {
}
}
private int getNextAvailableSegment(Program program) {
Address addr = program.getMemory().getMaxAddress();
return ((int) addr.getOffset() >> 4) + 1;
}
private void processResourceTable(MessageLog log, Program program, ResourceTable rt,
SegmentedAddressSpace space, TaskMonitor monitor) throws IOException {
Listing listing = program.getListing();
@ -326,7 +321,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
Resource[] resources = type.getResources();
for (Resource resource : resources) {
int segidx = getNextAvailableSegment(program);
int segidx = space.getNextOpenSegment(program.getMemory().getMaxAddress());
Address addr = space.getAddress(segidx, 0);
try {
@ -417,7 +412,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
for (LengthStringSet name : names) {
String[] callnames = getCallNamesForModule(name.getString(), mrt, st, imp);
int length = callnames.length * pointerSize;
int segment = getNextAvailableSegment(program);
int segment = space.getNextOpenSegment(program.getMemory().getMaxAddress());
Address start = space.getAddress(segment, 0);
if (length > 0) {
// This isn't a real block, just place holder addresses, so don't create an initialized block

View file

@ -176,10 +176,10 @@ public class ProgramMemoryUtil {
MemoryBlock[] blocks = mem.getBlocks();
MemoryBlock[] tmpBlocks = new MemoryBlock[blocks.length];
int j = 0;
for (int i = 0; i < blocks.length; i++) {
if ((blocks[i].isInitialized() && withBytes) ||
(!blocks[i].isInitialized() && !withBytes)) {
tmpBlocks[j++] = blocks[i];
for (MemoryBlock block : blocks) {
if ((block.isInitialized() && withBytes) ||
(!block.isInitialized() && !withBytes)) {
tmpBlocks[j++] = block;
}
}
MemoryBlock[] typeBlocks = new MemoryBlock[j];
@ -297,7 +297,7 @@ public class ProgramMemoryUtil {
}
// Just looking for the offset into the segment now, not the whole segment/offset pair
if (addrSize == 20) {
if (toAddress instanceof SegmentedAddress) {
SegmentedAddress segAddr = (SegmentedAddress) toAddress;
currentSegment = (short) segAddr.getSegment();
}
@ -322,10 +322,10 @@ public class ProgramMemoryUtil {
if (toAddress instanceof SegmentedAddress) {
short offsetShort = memory.getShort(a);
offsetShort &= offsetShort & 0xffff;
SegmentedAddress sega = ((SegmentedAddress) a);
short shortSega = (short) (sega.getSegment());
shortSega &= shortSega & 0xffff;
// this is checking to see if the ref is in the same segment as the toAddr - not sure this is needed anymore
// SegmentedAddress sega = ((SegmentedAddress) a);
// short shortSega = (short) (sega.getSegment());
// shortSega &= shortSega & 0xffff;
// if (offsetShort == shortCurrentOffset) {
//*** commenting this out is making it find the instances of 46 01's not the 0a 00's - closer though
// check for the case where the reference includes both the segment and offset
@ -441,8 +441,9 @@ public class ProgramMemoryUtil {
}
for (ReferenceAddressPair rap : directReferenceList) {
if (monitor.isCancelled())
if (monitor.isCancelled()) {
return null;
}
Address fromAddr = rap.getSource();
if (!results.contains(fromAddr)) {
results.add(fromAddr);
@ -624,18 +625,18 @@ public class ProgramMemoryUtil {
byte maskBytes[] = null;
MemoryBlock[] blocks = memory.getBlocks();
for (int i = 0; i < blocks.length; i++) {
if (!blocks[i].isInitialized()) {
for (MemoryBlock block : blocks) {
if (!block.isInitialized()) {
continue;
}
if (memoryRange != null &&
!memoryRange.intersects(blocks[i].getStart(), blocks[i].getEnd())) {
!memoryRange.intersects(block.getStart(), block.getEnd())) {
// skip blocks which do not correspond to currentSeg
continue;
}
Address start = blocks[i].getStart();
Address end = blocks[i].getEnd();
Address start = block.getStart();
Address end = block.getEnd();
Address found = null;
while (true) {
monitor.checkCanceled();

View file

@ -35,6 +35,7 @@ public class ProtectedAddressSpace extends SegmentedAddressSpace {
offsetMask = 1;
offsetMask <<= offsetSize;
offsetMask -= 1;
maxAddress = getUncheckedAddress(maxOffset);
}
@Override
@ -64,4 +65,11 @@ public class ProtectedAddressSpace extends SegmentedAddressSpace {
protected SegmentedAddress getAddressInSegment(long flat, int preferredSegment) {
return null; // The segment cannot be changed as the flat explicitly encodes it
}
@Override
public int getNextOpenSegment(Address addr) {
int res = getDefaultSegmentFromFlat(addr.getOffset());
res += 1;
return res;
}
}

View file

@ -46,10 +46,9 @@ public class SegmentedAddressSpace extends GenericAddressSpace {
*/
protected SegmentedAddressSpace(String name, int size, int unique) {
super(name, size, TYPE_RAM, unique);
spaceSize = 1;
spaceSize <<= size;
maxOffset = spaceSize - 1;
maxAddress = getUncheckedAddress(maxOffset);
// maxAddress = getUncheckedAddress(maxOffset);
// Constructors for derived classes that call this will
// need to reconstruct maxAddress themselves.
}
/**
@ -318,6 +317,18 @@ public class SegmentedAddressSpace extends GenericAddressSpace {
return new SegmentedAddress(this, segment, segmentOffset);
}
/**
* Get the segment index for the first segment whose start address
* comes after the given address
* @param addr is the given address
* @return the segment index
*/
public int getNextOpenSegment(Address addr) {
int res = (int) addr.getOffset(); // The "flat" offset (presumably real-mode encoded)
res = (res >> 4) + 1;
return res;
}
/**
*
* @see ghidra.program.model.address.AddressSpace#getPhysicalSpace()

View file

@ -27,6 +27,7 @@ data/languages/rdseed.sinc||GHIDRA||||END|
data/languages/sgx.sinc||GHIDRA||||END|
data/languages/sha.sinc||GHIDRA||||END|
data/languages/smx.sinc||GHIDRA||||END|
data/languages/x86-16-real.pspec||GHIDRA||||END|
data/languages/x86-16.cspec||GHIDRA||||END|
data/languages/x86-16.pspec||GHIDRA||||END|
data/languages/x86-64-gcc.cspec||GHIDRA||||END|

View file

@ -1387,10 +1387,7 @@ check_Rmr32_dest: is epsilon { }
check_rm32_dest: is epsilon { }
check_EAX_dest: is epsilon { }
# The far addresses listed here actually specify the CS segment to use
# but we do not model changing the CS segment in protected mode
# so we just use the offset portion of the address
ptr1616: reloc is imm16; j16 [ reloc = j16*16 + imm16; ] { CS = j16; export *[ram]:4 reloc; }
ptr1616: reloc is imm16; j16 [ reloc = j16*0x10000 + imm16; ] { CS = j16; export *[ram]:4 reloc; }
ptr1632: j16":"imm32 is imm32; j16 { CS = j16; export *:4 imm32; }

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Set up x86 16-bit in real mode -->
<processor_spec>
<properties>
<property key="useOperandReferenceAnalyzerSwitchTables" value="true"/>
</properties>
<programcounter register="EIP"/>
<segmented_address space="ram" type="real" />
<context_data>
<context_set space="ram">
<set name="addrsize" val="0"/>
<set name="opsize" val="0"/>
</context_set>
<tracked_set space="ram">
<set name="DF" val="0"/>
</tracked_set>
</context_data>
</processor_spec>

View file

@ -1,11 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Set up x86 16-bit in protected mode -->
<processor_spec>
<properties>
<property key="useOperandReferenceAnalyzerSwitchTables" value="true"/>
</properties>
<programcounter register="EIP"/>
<segmented_address space="ram"/>
<segmented_address space="ram" type="protected"/>
<context_data>
<context_set space="ram">
<set name="addrsize" val="0"/>

View file

@ -47,19 +47,31 @@
variant="Real Mode"
version="2.8"
slafile="x86.sla"
processorspec="x86-16.pspec"
processorspec="x86-16-real.pspec"
manualindexfile="../manuals/x86.idx"
id="x86:LE:16:Real Mode">
<description>Intel/AMD 16-bit x86 Real Mode</description>
<compiler name="default" spec="x86-16.cspec" id="default"/>
<external_name tool="IDA-PRO" name="8086"/>
<external_name tool="IDA-PRO" name="8086r"/>
<external_name tool="IDA-PRO" name="8086p"/>
<external_name tool="IDA-PRO" name="80386r"/>
<external_name tool="IDA-PRO" name="80486r"/>
<external_name tool="IDA-PRO" name="80586r"/>
<external_name tool="IDA-PRO" name="metapc"/>
</language>
<language processor="x86"
endian="little"
size="16"
variant="Protected Mode"
version="2.8"
slafile="x86.sla"
processorspec="x86-16.pspec"
manualindexfile="../manuals/x86.idx"
id="x86:LE:16:Protected Mode">
<description>Intel/AMD 16-bit x86 Protected Mode</description>
<compiler name="default" spec="x86-16.cspec" id="default"/>
<external_name tool="IDA-PRO" name="8086p"/>
</language>
<language processor="x86"
endian="little"
size="64"