mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
Added x86:LE:16:Protected Mode
This commit is contained in:
parent
cbf7b80587
commit
8240d3c8db
9 changed files with 78 additions and 32 deletions
|
@ -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,
|
private void processResourceTable(MessageLog log, Program program, ResourceTable rt,
|
||||||
SegmentedAddressSpace space, TaskMonitor monitor) throws IOException {
|
SegmentedAddressSpace space, TaskMonitor monitor) throws IOException {
|
||||||
Listing listing = program.getListing();
|
Listing listing = program.getListing();
|
||||||
|
@ -326,7 +321,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||||
Resource[] resources = type.getResources();
|
Resource[] resources = type.getResources();
|
||||||
for (Resource resource : resources) {
|
for (Resource resource : resources) {
|
||||||
|
|
||||||
int segidx = getNextAvailableSegment(program);
|
int segidx = space.getNextOpenSegment(program.getMemory().getMaxAddress());
|
||||||
Address addr = space.getAddress(segidx, 0);
|
Address addr = space.getAddress(segidx, 0);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -417,7 +412,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||||
for (LengthStringSet name : names) {
|
for (LengthStringSet name : names) {
|
||||||
String[] callnames = getCallNamesForModule(name.getString(), mrt, st, imp);
|
String[] callnames = getCallNamesForModule(name.getString(), mrt, st, imp);
|
||||||
int length = callnames.length * pointerSize;
|
int length = callnames.length * pointerSize;
|
||||||
int segment = getNextAvailableSegment(program);
|
int segment = space.getNextOpenSegment(program.getMemory().getMaxAddress());
|
||||||
Address start = space.getAddress(segment, 0);
|
Address start = space.getAddress(segment, 0);
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
// This isn't a real block, just place holder addresses, so don't create an initialized block
|
// This isn't a real block, just place holder addresses, so don't create an initialized block
|
||||||
|
|
|
@ -176,10 +176,10 @@ public class ProgramMemoryUtil {
|
||||||
MemoryBlock[] blocks = mem.getBlocks();
|
MemoryBlock[] blocks = mem.getBlocks();
|
||||||
MemoryBlock[] tmpBlocks = new MemoryBlock[blocks.length];
|
MemoryBlock[] tmpBlocks = new MemoryBlock[blocks.length];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (int i = 0; i < blocks.length; i++) {
|
for (MemoryBlock block : blocks) {
|
||||||
if ((blocks[i].isInitialized() && withBytes) ||
|
if ((block.isInitialized() && withBytes) ||
|
||||||
(!blocks[i].isInitialized() && !withBytes)) {
|
(!block.isInitialized() && !withBytes)) {
|
||||||
tmpBlocks[j++] = blocks[i];
|
tmpBlocks[j++] = block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MemoryBlock[] typeBlocks = new MemoryBlock[j];
|
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
|
// 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;
|
SegmentedAddress segAddr = (SegmentedAddress) toAddress;
|
||||||
currentSegment = (short) segAddr.getSegment();
|
currentSegment = (short) segAddr.getSegment();
|
||||||
}
|
}
|
||||||
|
@ -322,10 +322,10 @@ public class ProgramMemoryUtil {
|
||||||
if (toAddress instanceof SegmentedAddress) {
|
if (toAddress instanceof SegmentedAddress) {
|
||||||
short offsetShort = memory.getShort(a);
|
short offsetShort = memory.getShort(a);
|
||||||
offsetShort &= offsetShort & 0xffff;
|
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
|
// 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) {
|
// if (offsetShort == shortCurrentOffset) {
|
||||||
//*** commenting this out is making it find the instances of 46 01's not the 0a 00's - closer though
|
//*** 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
|
// check for the case where the reference includes both the segment and offset
|
||||||
|
@ -441,8 +441,9 @@ public class ProgramMemoryUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ReferenceAddressPair rap : directReferenceList) {
|
for (ReferenceAddressPair rap : directReferenceList) {
|
||||||
if (monitor.isCancelled())
|
if (monitor.isCancelled()) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
Address fromAddr = rap.getSource();
|
Address fromAddr = rap.getSource();
|
||||||
if (!results.contains(fromAddr)) {
|
if (!results.contains(fromAddr)) {
|
||||||
results.add(fromAddr);
|
results.add(fromAddr);
|
||||||
|
@ -624,18 +625,18 @@ public class ProgramMemoryUtil {
|
||||||
byte maskBytes[] = null;
|
byte maskBytes[] = null;
|
||||||
|
|
||||||
MemoryBlock[] blocks = memory.getBlocks();
|
MemoryBlock[] blocks = memory.getBlocks();
|
||||||
for (int i = 0; i < blocks.length; i++) {
|
for (MemoryBlock block : blocks) {
|
||||||
if (!blocks[i].isInitialized()) {
|
if (!block.isInitialized()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (memoryRange != null &&
|
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
|
// skip blocks which do not correspond to currentSeg
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Address start = blocks[i].getStart();
|
Address start = block.getStart();
|
||||||
Address end = blocks[i].getEnd();
|
Address end = block.getEnd();
|
||||||
Address found = null;
|
Address found = null;
|
||||||
while (true) {
|
while (true) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
|
|
|
@ -35,6 +35,7 @@ public class ProtectedAddressSpace extends SegmentedAddressSpace {
|
||||||
offsetMask = 1;
|
offsetMask = 1;
|
||||||
offsetMask <<= offsetSize;
|
offsetMask <<= offsetSize;
|
||||||
offsetMask -= 1;
|
offsetMask -= 1;
|
||||||
|
maxAddress = getUncheckedAddress(maxOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -64,4 +65,11 @@ public class ProtectedAddressSpace extends SegmentedAddressSpace {
|
||||||
protected SegmentedAddress getAddressInSegment(long flat, int preferredSegment) {
|
protected SegmentedAddress getAddressInSegment(long flat, int preferredSegment) {
|
||||||
return null; // The segment cannot be changed as the flat explicitly encodes it
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,10 +46,9 @@ public class SegmentedAddressSpace extends GenericAddressSpace {
|
||||||
*/
|
*/
|
||||||
protected SegmentedAddressSpace(String name, int size, int unique) {
|
protected SegmentedAddressSpace(String name, int size, int unique) {
|
||||||
super(name, size, TYPE_RAM, unique);
|
super(name, size, TYPE_RAM, unique);
|
||||||
spaceSize = 1;
|
// maxAddress = getUncheckedAddress(maxOffset);
|
||||||
spaceSize <<= size;
|
// Constructors for derived classes that call this will
|
||||||
maxOffset = spaceSize - 1;
|
// need to reconstruct maxAddress themselves.
|
||||||
maxAddress = getUncheckedAddress(maxOffset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -318,6 +317,18 @@ public class SegmentedAddressSpace extends GenericAddressSpace {
|
||||||
return new SegmentedAddress(this, segment, segmentOffset);
|
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()
|
* @see ghidra.program.model.address.AddressSpace#getPhysicalSpace()
|
||||||
|
|
|
@ -27,6 +27,7 @@ data/languages/rdseed.sinc||GHIDRA||||END|
|
||||||
data/languages/sgx.sinc||GHIDRA||||END|
|
data/languages/sgx.sinc||GHIDRA||||END|
|
||||||
data/languages/sha.sinc||GHIDRA||||END|
|
data/languages/sha.sinc||GHIDRA||||END|
|
||||||
data/languages/smx.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.cspec||GHIDRA||||END|
|
||||||
data/languages/x86-16.pspec||GHIDRA||||END|
|
data/languages/x86-16.pspec||GHIDRA||||END|
|
||||||
data/languages/x86-64-gcc.cspec||GHIDRA||||END|
|
data/languages/x86-64-gcc.cspec||GHIDRA||||END|
|
||||||
|
|
|
@ -1387,10 +1387,7 @@ check_Rmr32_dest: is epsilon { }
|
||||||
check_rm32_dest: is epsilon { }
|
check_rm32_dest: is epsilon { }
|
||||||
check_EAX_dest: is epsilon { }
|
check_EAX_dest: is epsilon { }
|
||||||
|
|
||||||
# The far addresses listed here actually specify the CS segment to use
|
ptr1616: reloc is imm16; j16 [ reloc = j16*0x10000 + imm16; ] { CS = j16; export *[ram]:4 reloc; }
|
||||||
# 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; }
|
|
||||||
ptr1632: j16":"imm32 is imm32; j16 { CS = j16; export *:4 imm32; }
|
ptr1632: j16":"imm32 is imm32; j16 { CS = j16; export *:4 imm32; }
|
||||||
|
|
||||||
|
|
||||||
|
|
19
Ghidra/Processors/x86/data/languages/x86-16-real.pspec
Normal file
19
Ghidra/Processors/x86/data/languages/x86-16-real.pspec
Normal 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>
|
|
@ -1,11 +1,13 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!-- Set up x86 16-bit in protected mode -->
|
||||||
|
|
||||||
<processor_spec>
|
<processor_spec>
|
||||||
<properties>
|
<properties>
|
||||||
<property key="useOperandReferenceAnalyzerSwitchTables" value="true"/>
|
<property key="useOperandReferenceAnalyzerSwitchTables" value="true"/>
|
||||||
</properties>
|
</properties>
|
||||||
<programcounter register="EIP"/>
|
<programcounter register="EIP"/>
|
||||||
<segmented_address space="ram"/>
|
<segmented_address space="ram" type="protected"/>
|
||||||
<context_data>
|
<context_data>
|
||||||
<context_set space="ram">
|
<context_set space="ram">
|
||||||
<set name="addrsize" val="0"/>
|
<set name="addrsize" val="0"/>
|
||||||
|
|
|
@ -47,19 +47,31 @@
|
||||||
variant="Real Mode"
|
variant="Real Mode"
|
||||||
version="2.8"
|
version="2.8"
|
||||||
slafile="x86.sla"
|
slafile="x86.sla"
|
||||||
processorspec="x86-16.pspec"
|
processorspec="x86-16-real.pspec"
|
||||||
manualindexfile="../manuals/x86.idx"
|
manualindexfile="../manuals/x86.idx"
|
||||||
id="x86:LE:16:Real Mode">
|
id="x86:LE:16:Real Mode">
|
||||||
<description>Intel/AMD 16-bit x86 Real Mode</description>
|
<description>Intel/AMD 16-bit x86 Real Mode</description>
|
||||||
<compiler name="default" spec="x86-16.cspec" id="default"/>
|
<compiler name="default" spec="x86-16.cspec" id="default"/>
|
||||||
<external_name tool="IDA-PRO" name="8086"/>
|
<external_name tool="IDA-PRO" name="8086"/>
|
||||||
<external_name tool="IDA-PRO" name="8086r"/>
|
<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="80386r"/>
|
||||||
<external_name tool="IDA-PRO" name="80486r"/>
|
<external_name tool="IDA-PRO" name="80486r"/>
|
||||||
<external_name tool="IDA-PRO" name="80586r"/>
|
<external_name tool="IDA-PRO" name="80586r"/>
|
||||||
<external_name tool="IDA-PRO" name="metapc"/>
|
<external_name tool="IDA-PRO" name="metapc"/>
|
||||||
</language>
|
</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"
|
<language processor="x86"
|
||||||
endian="little"
|
endian="little"
|
||||||
size="64"
|
size="64"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue