mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-27 23:17:03 +08:00
GP-2210: More MzLoader fixes/improvements
This commit is contained in:
@@ -19,8 +19,6 @@ import java.io.IOException;
|
|||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.bin.StructConverter;
|
|
||||||
import ghidra.app.util.bin.format.Writeable;
|
|
||||||
import ghidra.app.util.bin.format.ne.InvalidWindowsHeaderException;
|
import ghidra.app.util.bin.format.ne.InvalidWindowsHeaderException;
|
||||||
import ghidra.app.util.bin.format.ne.WindowsHeader;
|
import ghidra.app.util.bin.format.ne.WindowsHeader;
|
||||||
import ghidra.app.util.bin.format.pe.InvalidNTHeaderException;
|
import ghidra.app.util.bin.format.pe.InvalidNTHeaderException;
|
||||||
@@ -61,10 +59,12 @@ import ghidra.util.exception.DuplicateNameException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DOSHeader extends OldDOSHeader implements StructConverter, Writeable {
|
public class DOSHeader extends OldDOSHeader {
|
||||||
|
|
||||||
/** The name to use when converting into a structure data type. */
|
/** The name to use when converting into a structure data type. */
|
||||||
public final static String NAME = "IMAGE_DOS_HEADER";
|
public final static String NAME = "IMAGE_DOS_HEADER";
|
||||||
public final static int SIZEOF_DOS_HEADER = 64;
|
|
||||||
|
public final static int SIZEOF_DOS_HEADER = 64;
|
||||||
|
|
||||||
private short [] e_res = new short[4]; // Reserved words
|
private short [] e_res = new short[4]; // Reserved words
|
||||||
private short e_oemid; // OEM identifier (for e_oeminfo)
|
private short e_oemid; // OEM identifier (for e_oeminfo)
|
||||||
@@ -74,12 +74,11 @@ public class DOSHeader extends OldDOSHeader implements StructConverter, Writeabl
|
|||||||
|
|
||||||
private byte [] stubBytes;
|
private byte [] stubBytes;
|
||||||
|
|
||||||
private BinaryReader reader;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new DOS header.
|
* Constructs a new DOS header.
|
||||||
* @param reader the binary reader
|
* @param reader the binary reader
|
||||||
*/
|
* @throws IOException if there was an IO-related error
|
||||||
|
*/
|
||||||
public DOSHeader(BinaryReader reader) throws IOException {
|
public DOSHeader(BinaryReader reader) throws IOException {
|
||||||
super(reader);
|
super(reader);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.util.bin.format.mz;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to manage loading old-style DOS MZ executables
|
||||||
|
*/
|
||||||
|
public class MzExecutable {
|
||||||
|
|
||||||
|
private BinaryReader reader;
|
||||||
|
private OldDOSHeader header;
|
||||||
|
private List<MzRelocation> relocations = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance of an old-style MZ executable
|
||||||
|
*
|
||||||
|
* @param provider The bytes
|
||||||
|
* @throws IOException if an I/O error occurs
|
||||||
|
*/
|
||||||
|
public MzExecutable(ByteProvider provider) throws IOException {
|
||||||
|
reader = new BinaryReader(provider, true);
|
||||||
|
header = new OldDOSHeader(reader);
|
||||||
|
reader.setPointerIndex(header.e_lfarlc());
|
||||||
|
for (int i = 0; i < header.e_crlc(); i++) {
|
||||||
|
relocations.add(new MzRelocation(reader));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the underlying binary reader
|
||||||
|
*
|
||||||
|
* @return the underlying binary reader
|
||||||
|
*/
|
||||||
|
public BinaryReader getBinaryReader() {
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the DOS Header from this old-style MZ executable
|
||||||
|
*
|
||||||
|
* @return the DOS Header from this old-style MZ executable
|
||||||
|
*/
|
||||||
|
public OldDOSHeader getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the old-style MZ relocations
|
||||||
|
*
|
||||||
|
* @return the old-style MZ relocations
|
||||||
|
*/
|
||||||
|
public List<MzRelocation> getRelocations() {
|
||||||
|
return relocations;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.util.bin.format.mz;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.StructConverter;
|
||||||
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
|
public class MzRelocation implements StructConverter {
|
||||||
|
|
||||||
|
/** The name to use when converting into a structure data type. */
|
||||||
|
public static final String NAME = "OLD_IMAGE_DOS_RELOC";
|
||||||
|
|
||||||
|
private int segment;
|
||||||
|
private int offset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new old-style MZ relocation
|
||||||
|
*
|
||||||
|
* @param reader A {@link BinaryReader} positioned at the start of the relocation
|
||||||
|
* @throws IOException if there was an IO-related error
|
||||||
|
*/
|
||||||
|
public MzRelocation(BinaryReader reader) throws IOException {
|
||||||
|
offset = Short.toUnsignedInt(reader.readNextShort());
|
||||||
|
segment = Short.toUnsignedInt(reader.readNextShort());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the segment
|
||||||
|
*
|
||||||
|
* @return The segment
|
||||||
|
*/
|
||||||
|
public int getSegment() {
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the offset
|
||||||
|
*
|
||||||
|
* @return The offset
|
||||||
|
*/
|
||||||
|
public int getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataType toDataType() throws DuplicateNameException {
|
||||||
|
StructureDataType struct = new StructureDataType(NAME, 0);
|
||||||
|
struct.add(WORD, "offset", null);
|
||||||
|
struct.add(WORD, "segment", null);
|
||||||
|
struct.setCategoryPath(new CategoryPath("/DOS"));
|
||||||
|
return struct;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("%04x:%04x", segment, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,8 +51,8 @@ public class OldDOSHeader implements StructConverter, Writeable {
|
|||||||
|
|
||||||
/** The name to use when converting into a structure data type. */
|
/** The name to use when converting into a structure data type. */
|
||||||
public static final String NAME = "OLD_IMAGE_DOS_HEADER";
|
public static final String NAME = "OLD_IMAGE_DOS_HEADER";
|
||||||
|
|
||||||
public static final int IMAGE_DOS_SIGNATURE = 0x5A4D;
|
public static final int IMAGE_DOS_SIGNATURE = 0x5A4D;
|
||||||
public static final int SIZEOF_DOS_HEADER = 28;
|
|
||||||
|
|
||||||
private short e_magic;
|
private short e_magic;
|
||||||
private short e_cblp;
|
private short e_cblp;
|
||||||
@@ -68,11 +68,13 @@ public class OldDOSHeader implements StructConverter, Writeable {
|
|||||||
private short e_cs;
|
private short e_cs;
|
||||||
private short e_lfarlc;
|
private short e_lfarlc;
|
||||||
private short e_ovno;
|
private short e_ovno;
|
||||||
|
|
||||||
protected BinaryReader reader;
|
protected BinaryReader reader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new DOS header.
|
* Constructs a new DOS header.
|
||||||
* @param reader the binary reader
|
* @param reader the binary reader
|
||||||
|
* @throws IOException if there was an IO-related error
|
||||||
*/
|
*/
|
||||||
public OldDOSHeader(BinaryReader reader) throws IOException {
|
public OldDOSHeader(BinaryReader reader) throws IOException {
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
@@ -223,9 +225,6 @@ public class OldDOSHeader implements StructConverter, Writeable {
|
|||||||
return e_magic == IMAGE_DOS_SIGNATURE;
|
return e_magic == IMAGE_DOS_SIGNATURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
public DataType toDataType() throws DuplicateNameException {
|
||||||
StructureDataType struct = new StructureDataType(getName(), 0);
|
StructureDataType struct = new StructureDataType(getName(), 0);
|
||||||
@@ -301,9 +300,6 @@ public class OldDOSHeader implements StructConverter, Writeable {
|
|||||||
e_ovno = reader.readNextShort();
|
e_ovno = reader.readNextShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.format.Writeable#write(java.io.RandomAccessFile, ghidra.util.DataConverter)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void write(RandomAccessFile raf, DataConverter dc) throws IOException {
|
public void write(RandomAccessFile raf, DataConverter dc) throws IOException {
|
||||||
raf.write(dc.getBytes(e_magic));
|
raf.write(dc.getBytes(e_magic));
|
||||||
|
|||||||
-57
@@ -1,57 +0,0 @@
|
|||||||
/* ###
|
|
||||||
* IP: GHIDRA
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package ghidra.app.util.bin.format.mz;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
|
||||||
import ghidra.app.util.bin.ByteProvider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class to manage loading Old-style (MZ) Executables.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class OldStyleExecutable {
|
|
||||||
private BinaryReader reader;
|
|
||||||
private OldDOSHeader dosHeader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new instance of an old-style executable
|
|
||||||
* @param bp the byte provider
|
|
||||||
* @throws IOException if an I/O error occurs
|
|
||||||
*/
|
|
||||||
public OldStyleExecutable(ByteProvider bp) throws IOException {
|
|
||||||
reader = new BinaryReader(bp, true);
|
|
||||||
dosHeader = new OldDOSHeader(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the underlying binary reader.
|
|
||||||
* @return the underlying binary reader
|
|
||||||
*/
|
|
||||||
public BinaryReader getBinaryReader() {
|
|
||||||
return reader;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the DOS Header from this old-style executable.
|
|
||||||
* @return the DOS Header from this old-style executable
|
|
||||||
*/
|
|
||||||
public OldDOSHeader getOldDOSHeader() {
|
|
||||||
return dosHeader;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user