5
5
// - fix XEX1 exports
6
6
7
7
#include < ida.hpp>
8
+ #include < idp.hpp>
8
9
#include < loader.hpp>
9
10
#include < auto.hpp>
10
11
#include < diskio.hpp>
11
12
#include < entry.hpp>
12
13
#include < typeinf.hpp>
13
14
#include < bytes.hpp>
14
15
16
+ struct exehdr {}; // needed for pe.h
17
+ #include < pe.h>
18
+ #include < common.h>
19
+
15
20
#include < filesystem>
16
21
#include < list>
17
22
@@ -168,37 +173,71 @@ void pe_add_sections(XEXFile& file)
168
173
}
169
174
}
170
175
171
- // from ldr/pe/pe.h
172
- #define PE_NODE " $ PE header" // netnode name for PE header
173
- // value() -> peheader_t
174
- // altval(segnum) -> s->start_ea
175
- #define PE_ALT_DBG_FPOS nodeidx_t (-1 ) // altval() -> translated fpos of debuginfo
176
- #define PE_ALT_IMAGEBASE nodeidx_t (-2 ) // altval() -> loading address (usually pe.imagebase)
177
- #define PE_ALT_PEHDR_OFF nodeidx_t (-3 ) // altval() -> offset of PE header
178
- #define PE_ALT_NEFLAGS nodeidx_t (-4 ) // altval() -> neflags
179
- #define PE_ALT_TDS_LOADED nodeidx_t (-5 ) // altval() -> tds already loaded(1) or invalid(-1)
180
- #define PE_ALT_PSXDLL nodeidx_t (-6 ) // altval() -> if POSIX(x86) imports from PSXDLL netnode
181
- #define PE_ALT_OVRVA nodeidx_t (-7 ) // altval() -> overlay rva (if present)
182
- #define PE_ALT_OVRSZ nodeidx_t (-8 ) // altval() -> overlay size (if present)
183
- #define PE_SUPSTR_PDBNM nodeidx_t (-9 ) // supstr() -> pdb file name
184
- // supval(segnum) -> pesection_t
185
- // blob(0, PE_NODE_RELOC) -> relocation info
186
- // blob(0, RSDS_TAG) -> rsds_t structure
187
- // blob(0, NB10_TAG) -> cv_info_pdb20_t structure
188
- #define PE_ALT_NTAPI nodeidx_t (-10 ) // altval() -> uses Native API
189
- #define PE_EMBED_PDB_OFF nodeidx_t (-11 ) // altval() -> offset of embedded PDB file
190
- #define PE_NODE_RELOC ' r'
191
- #define RSDS_TAG ' s'
192
- #define NB10_TAG ' n'
193
- #define UTDS_TAG ' t'
176
+ // marked virtual but not pure virtual, grr
177
+ bool pe_loader_t::vseek (linput_t * li, uint32 rva)
178
+ {
179
+ qlseek (li, rva, 0 );
180
+ return true ;
181
+ }
194
182
195
183
void pe_setup_netnode (XEXFile& file)
196
184
{
197
185
netnode penode;
198
186
penode.create (PE_NODE);
199
187
188
+ const uint8_t * pe_data = file.pe_data ();
189
+ IMAGE_DOS_HEADER* dos_header = (IMAGE_DOS_HEADER*)pe_data;
190
+
191
+ // Set PE header node data
192
+ // Make a copy of PE header and update with correct values first, since IDA/eh_parse reads some info from this
193
+ IMAGE_NT_HEADERS nt_header = *(IMAGE_NT_HEADERS*)(pe_data + dos_header->AddressOfNewExeHeader );
194
+ nt_header.OptionalHeader .ImageBase = file.base_address ();
195
+
196
+ penode.set (&nt_header, sizeof (IMAGE_NT_HEADERS));
197
+
198
+ // Update imagebase
200
199
penode.altset (PE_ALT_IMAGEBASE, file.base_address ());
201
200
201
+ // Ask eh_parse to parse .pdata for us
202
+ // IDA itself seems to handle parsing .pdata if PE header is set above, but only at end of autoanalysis, which could take a while on large games
203
+ // Requesting eh_parse after we've loaded in should allow the funcs there to be marked earlier
204
+ {
205
+ auto * plugin = find_plugin (" eh_parse" , true );
206
+ if (plugin)
207
+ {
208
+ run_plugin (plugin, 0 );
209
+
210
+ // TODO: Why isn't this included in IDASDK ;_; may cause breakage if eh_parse is ever updated!
211
+ struct eh_parse_t
212
+ {
213
+ virtual bool idaapi _0 () = 0;
214
+ virtual bool idaapi _8 () = 0;
215
+ virtual bool idaapi _10 () = 0;
216
+ virtual bool idaapi _18 () = 0;
217
+ virtual bool idaapi _20 () = 0;
218
+ virtual bool idaapi read_pdata_28 (pe_loader_t * a2, linput_t * a3, char a4) = 0;
219
+
220
+ uint64_t unk_8;
221
+ uint64_t unk_10;
222
+ uint64_t unk_18;
223
+ uint64_t imagebase_20;
224
+ };
225
+
226
+ eh_parse_t * eh_parse = (eh_parse_t *)processor_t::notify (processor_t ::event_t ::ev_broadcast, 0x45485F5041525345 , 0 );
227
+ if (eh_parse)
228
+ {
229
+ eh_parse->imagebase_20 = file.base_address ();
230
+
231
+ pe_loader_t pe;
232
+ pe.set_imagebase (file.base_address ());
233
+
234
+ linput_t * memory = create_memory_linput (file.base_address (), file.image_size ());
235
+ eh_parse->read_pdata_28 (&pe, memory, 0 );
236
+ close_linput (memory);
237
+ }
238
+ }
239
+ }
240
+
202
241
size_t cv_length = 0 ;
203
242
auto * cv_data = file.codeview_data (0 , &cv_length);
204
243
if (cv_data)
@@ -218,7 +257,7 @@ void pe_setup_netnode(XEXFile& file)
218
257
219
258
// Prompt for PDB load
220
259
msg (" Prompting for PDB load...\n (full X360 type loading may require pdb.cfg PDB_PROVIDER = PDB_PROVIDER_MSDIA !)\n " );
221
- auto * plugin = find_plugin (" pdb" , 1LL );
260
+ auto * plugin = find_plugin (" pdb" , true );
222
261
run_plugin (plugin, 1LL );
223
262
}
224
263
}
0 commit comments