Skip to content

Commit 6353559

Browse files
committed
Things are closer to working
1 parent a65d245 commit 6353559

File tree

7 files changed

+107
-28
lines changed

7 files changed

+107
-28
lines changed

GhidraESP8266_2/ESP8266.bt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//------------------------------------------------
2+
//--- 010 Editor v9.0.1 Binary Template
3+
//
4+
// File:
5+
// Authors:
6+
// Version:
7+
// Purpose:
8+
// Category:
9+
// File Mask:
10+
// ID Bytes:
11+
// History:
12+
//------------------------------------------------
13+
string CheckMagic(int magic)
14+
{
15+
if(0xe9 == magic)
16+
return "Valid Magic";
17+
else
18+
return "Not a valid image";
19+
}
20+
struct header
21+
{
22+
BYTE magic<comment=CheckMagic>;
23+
BYTE sections;
24+
BYTE flash_mode;
25+
BYTE flash_size_free<format=decimal>;
26+
int entrypoint<format=hex>;
27+
};
28+
struct section
29+
{
30+
DWORD offset<format=hex>;
31+
DWORD size;
32+
BYTE data[size];
33+
};
34+
header Header;
35+
FSeek(0x1000);
36+
header UserHeader;
37+
local int i<hidden=true>;
38+
for(i=0; i < UserHeader.sections; i++)
39+
{
40+
section Section;
41+
Printf("Section: %x %u", Section.offset, Section.size);
42+
}

GhidraESP8266_2/src/main/java/ghidraesp8266_2/ESP8266Constants.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
public final class ESP8266Constants {
44
/** ESP magic value */
55
public final static byte ESP_MAGIC_BASE = (byte) 0xe9;
6-
public final static String PRIMARY_KEY = "1";
7-
public final static String SECONDARY_KEY = "2";
86
public final static int IROM_MAP_START = 0x40200000;
97
public final static int IROM_MAP_END = 0x40300000;
108
public final static int SEGMENT_USER_CODE_BASE = 0x40100000;
119
public final static int SEGMENT_USER_DATA_BASE = 0x3FFE8000;
1210
public final static int SEGMENT_DATA_END = 0x3FFFFFFF;
1311
public final static int SEGMENT_CODE_BASE = 0x40100000;
12+
public final static int SECTION_TYPE_CODE = 1;
13+
public final static int SECTION_TYPE_DATA = 2;
1414
}

GhidraESP8266_2/src/main/java/ghidraesp8266_2/ESP8266Header.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import ghidra.program.model.data.DataType;
88
import ghidra.program.model.data.Structure;
99
import ghidra.program.model.data.StructureDataType;
10+
import ghidra.util.Msg;
1011
import ghidra.util.exception.DuplicateNameException;
1112

1213
public class ESP8266Header implements StructConverter {
@@ -19,13 +20,18 @@ public class ESP8266Header implements StructConverter {
1920

2021
public ESP8266Header(BinaryReader reader) throws IOException {
2122
magic = reader.readNextByte();
23+
Msg.info(this, String.format("Magic = %02x", magic));
24+
if (ESP8266Constants.ESP_MAGIC_BASE != getMagic()) {
25+
throw new IOException("not an ESP8266 file.");
26+
}
2227
segments = reader.readNextByte();
28+
Msg.info(this, String.format("Segments = %d", segments));
2329
flash_mode = reader.readNextByte();
30+
Msg.info(this, String.format("Flash Mode = %d", flash_mode));
2431
flash_size_free = reader.readNextByte();
32+
Msg.info(this, String.format("Flash Size Free = %d", flash_size_free));
2533
entrypoint = reader.readNextInt();
26-
if (ESP8266Constants.ESP_MAGIC_BASE != getMagic()) {
27-
throw new IOException("not an ESP8266 file.");
28-
}
34+
Msg.info(this, String.format("Entrypoint = %08x", entrypoint));
2935
}
3036

3137
@Override

GhidraESP8266_2/src/main/java/ghidraesp8266_2/ESP8266Module.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.util.List;
66

77
import ghidra.app.util.bin.BinaryReader;
8+
import ghidra.util.Msg;
89

910
public class ESP8266Module {
1011

@@ -21,6 +22,7 @@ public ESP8266Module(BinaryReader reader) throws IOException {
2122
reader.setPointerIndex(0x1000);
2223
userheader = new ESP8266Header(reader);
2324
for(int i=0; i < userheader.getSegmentCount(); ++i) {
25+
Msg.info(this, "Adding section");
2426
sections.add(new ESP8266Section(reader));
2527
}
2628
}

GhidraESP8266_2/src/main/java/ghidraesp8266_2/ESP8266Section.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import ghidra.program.model.data.DataType;
88
import ghidra.program.model.data.Structure;
99
import ghidra.program.model.data.StructureDataType;
10+
import ghidra.util.Msg;
1011
import ghidra.util.exception.DuplicateNameException;
1112

1213
public class ESP8266Section implements StructConverter {
@@ -17,6 +18,8 @@ public class ESP8266Section implements StructConverter {
1718
public ESP8266Section(BinaryReader reader) throws IOException {
1819
offset = reader.readNextInt();
1920
size = reader.readNextInt();
21+
Msg.info(this, String.format("Reading %d bytes", size));
22+
content = reader.readNextByteArray(size);
2023
}
2124

2225
@Override
@@ -53,4 +56,17 @@ else if(offset > ESP8266Constants.SEGMENT_CODE_BASE)
5356
else
5457
return ".unknown";
5558
}
59+
public int getType() {
60+
// Rules based on ranges
61+
if(offset == ESP8266Constants.SEGMENT_USER_CODE_BASE)
62+
return ESP8266Constants.SECTION_TYPE_CODE;
63+
else if(offset == ESP8266Constants.SEGMENT_USER_DATA_BASE)
64+
return ESP8266Constants.SECTION_TYPE_DATA;
65+
else if(offset <= ESP8266Constants.SEGMENT_DATA_END)
66+
return ESP8266Constants.SECTION_TYPE_DATA;
67+
else if(offset > ESP8266Constants.SEGMENT_CODE_BASE)
68+
return ESP8266Constants.SECTION_TYPE_CODE;
69+
else
70+
return ESP8266Constants.SECTION_TYPE_DATA;
71+
}
5672
}

GhidraESP8266_2/src/main/java/ghidraesp8266_2/GhidraESP8266_2Analyzer.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
*/
1616
package ghidraesp8266_2;
1717

18-
import java.io.IOException;
19-
2018
import ghidra.app.services.AbstractAnalyzer;
2119
import ghidra.app.services.AnalyzerType;
2220
import ghidra.app.util.bin.BinaryReader;
@@ -57,8 +55,9 @@ public boolean canAnalyze(Program program) {
5755

5856
// Examine 'program' to determine of this analyzer should analyze it. Return true
5957
// if it can.
60-
LanguageID lID = new LanguageID("Xtensa:LE:32:default");
61-
return program.getLanguageID() == lID;
58+
//LanguageID lID = new LanguageID("Xtensa:LE:32:default");
59+
//return program.getLanguageID() == lID;
60+
return false;
6261
}
6362

6463
@Override

GhidraESP8266_2/src/main/java/ghidraesp8266_2/GhidraESP8266_2Loader.java

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@
2727
import ghidra.app.util.importer.MessageLog;
2828
import ghidra.app.util.opinion.AbstractLibrarySupportLoader;
2929
import ghidra.app.util.opinion.LoadSpec;
30-
import ghidra.app.util.opinion.QueryOpinionService;
31-
import ghidra.app.util.opinion.QueryResult;
3230
import ghidra.framework.model.DomainObject;
3331
import ghidra.program.model.address.Address;
3432
import ghidra.program.model.address.AddressOverflowException;
3533
import ghidra.program.model.data.DataType;
3634
import ghidra.program.model.data.DataTypeConflictException;
3735
import ghidra.program.model.data.DataUtilities;
3836
import ghidra.program.model.data.DataUtilities.ClearDataMode;
37+
import ghidra.program.model.lang.LanguageCompilerSpecPair;
3938
import ghidra.program.model.listing.Data;
4039
import ghidra.program.model.listing.Listing;
4140
import ghidra.program.model.listing.Program;
41+
import ghidra.program.model.util.AddressSetPropertyMap;
4242
import ghidra.program.model.util.CodeUnitInsertionException;
4343
import ghidra.util.Msg;
4444
import ghidra.util.exception.CancelledException;
@@ -62,15 +62,9 @@ public Collection<LoadSpec> findSupportedLoadSpecs(ByteProvider provider) throws
6262
BinaryReader reader = new BinaryReader(provider, true);
6363
ESP8266Header header = new ESP8266Header(reader);
6464
if (ESP8266Constants.ESP_MAGIC_BASE == header.getMagic()) {
65-
Msg.info(this, "Magic Matched");
66-
List<QueryResult> queries =
67-
QueryOpinionService.query(getName(), ESP8266Constants.PRIMARY_KEY, null);
68-
for (QueryResult result : queries) {
69-
loadSpecs.add(new LoadSpec(this, 0, result));
70-
}
71-
if (loadSpecs.isEmpty()) {
72-
loadSpecs.add(new LoadSpec(this, 0, true));
73-
}
65+
Msg.info(this, "ESP Magic Matched");
66+
loadSpecs.add(new LoadSpec(this, 0,
67+
new LanguageCompilerSpecPair("Xtensa:LE:32:default", "default"), true));
7468
}
7569
return loadSpecs;
7670
}
@@ -102,24 +96,50 @@ private void markupHeader(Program program, ESP8266Header header, TaskMonitor mon
10296
}
10397
}
10498

99+
private void markAsCode(Program program, Address address) {
100+
AddressSetPropertyMap codeProp = program.getAddressSetPropertyMap("CodeMap");
101+
if (codeProp == null) {
102+
try {
103+
codeProp = program.createAddressSetPropertyMap("CodeMap");
104+
}
105+
catch (DuplicateNameException e) {
106+
codeProp = program.getAddressSetPropertyMap("CodeMap");
107+
}
108+
}
109+
110+
if (codeProp != null) {
111+
codeProp.add(address, address);
112+
}
113+
}
114+
105115
private void markupSections(Program program, ESP8266Module module, TaskMonitor monitor, InputStream reader) throws DuplicateNameException, IOException, AddressOverflowException {
106116
boolean r = true;
107117
boolean w = true;
108118
boolean x = true;
109119
String BLOCK_SOURCE_NAME = "ESP8266 Section";
110120
for (ESP8266Section section: module.getSections()) {
111121
Address start = program.getAddressFactory().getDefaultAddressSpace().getAddress(section.getOffset());
122+
Msg.info(this, String.format("Section at offset %08x, size %d", start.getOffset(), section.getSize()));
112123
mbu.createInitializedBlock(section.getName(), start, reader, section.getSize(), "", BLOCK_SOURCE_NAME, r, w, x, monitor);
113124
createData(program, program.getListing(), start, section.toDataType());
125+
// Mark code sections
126+
if(section.getType() == ESP8266Constants.SECTION_TYPE_CODE)
127+
{
128+
Msg.info(this, "Section is code");
129+
markAsCode(program, start);
130+
}
131+
else
132+
{
133+
Msg.info(this, "Section is not code");
134+
}
114135
}
115136
}
116137

117138
public Data createData(Program program, Listing listing, Address address, DataType dt) {
118139
try {
119140
Data d = listing.getDataAt(address);
120141
if (d == null || !dt.isEquivalent(d.getDataType())) {
121-
d = DataUtilities.createData(program, address, dt, -1, false,
122-
ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA);
142+
d = DataUtilities.createData(program, address, dt, -1, false, ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA);
123143
}
124144
return d;
125145
}
@@ -148,15 +168,9 @@ protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> optio
148168
BinaryReader reader = new BinaryReader( provider, true );
149169
ESP8266Module module = new ESP8266Module( reader );
150170

151-
// createMethodLookupMemoryBlock( program, monitor );
152-
// createMethodByteCodeBlock( program, length, monitor);
153171
markupHeader(program, module.getHeader(), monitor, inputStream);
154172
markupSections(program, module, monitor, inputStream);
155-
monitor.setMessage( "ESP8266 Loader: Create byte code" );
156173

157-
for (ESP8266Section section : module.getSections()) {
158-
monitor.setMessage("Loaded " + section.getName());
159-
}
160174
// Create entry point
161175
Address entryAddress = program.getAddressFactory().getDefaultAddressSpace().getAddress(module.getHeader().getEntrypoint(), true);
162176
program.getSymbolTable().addExternalEntryPoint(entryAddress);

0 commit comments

Comments
 (0)