1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.owasp.dependencycheck.utils;
15
16 import org.boris.pecoff4j.*;
17 import org.boris.pecoff4j.constant.ImageDataDirectoryType;
18 import org.boris.pecoff4j.util.IntMap;
19
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Comparator;
27 import java.util.List;
28 import org.boris.pecoff4j.io.ByteArrayDataReader;
29 import org.boris.pecoff4j.io.DataEntry;
30 import org.boris.pecoff4j.io.DataReader;
31 import org.boris.pecoff4j.io.IDataReader;
32
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 public class PEParser {
37
38
39
40
41 private static final Logger LOGGER = LoggerFactory.getLogger(PEParser.class);
42
43 public static PE parse(InputStream is) throws IOException {
44 return read(new DataReader(is));
45 }
46
47 public static PE parse(String filename) throws IOException {
48 return parse(new File(filename));
49 }
50
51 public static PE parse(File file) throws IOException {
52 return read(new DataReader(new FileInputStream(file)), file);
53 }
54
55 public static PE read(IDataReader dr) throws IOException {
56 return read(dr, null);
57 }
58
59 public static PE read(IDataReader dr, File file) throws IOException {
60 PE pe = new PE();
61 pe.setDosHeader(readDos(dr));
62
63
64 if (pe.getDosHeader().getAddressOfNewExeHeader() == 0
65 || pe.getDosHeader().getAddressOfNewExeHeader() > 8192) {
66 return pe;
67 }
68
69 pe.setStub(readStub(pe.getDosHeader(), dr));
70 pe.setSignature(readSignature(dr));
71
72
73 if (!pe.getSignature().isValid()) {
74 return pe;
75 }
76
77 pe.setCoffHeader(readCOFF(dr));
78 pe.setOptionalHeader(readOptional(dr));
79 pe.setSectionTable(readSectionHeaders(pe, dr));
80
81 pe.set64(pe.getOptionalHeader().isPE32plus());
82
83
84 DataEntry entry = null;
85 while ((entry = findNextEntry(pe, dr.getPosition())) != null) {
86 if (entry.isSection) {
87 readSection(pe, entry, dr);
88 } else if (entry.isDebugRawData) {
89 try {
90 readDebugRawData(pe, entry, dr);
91 } catch (java.io.EOFException eofEx) {
92 if (file != null) {
93 LOGGER.debug("Error reading debug raw data: " + file.getPath(), eofEx);
94 }
95 }
96
97 } else {
98 try {
99 readImageData(pe, entry, dr);
100 } catch (java.io.EOFException eofEx) {
101 if (file != null) {
102 LOGGER.debug("Error reading image data: " + file.getPath(), eofEx);
103 }
104 }
105
106 }
107 }
108
109
110 try {
111 byte[] tb = dr.readAll();
112 if (tb.length > 0) {
113 pe.getImageData().setTrailingData(tb);
114 }
115 } catch (java.io.EOFException eofEx) {
116 if (file != null) {
117 LOGGER.debug("Error reading trailing data: " + file.getPath(), eofEx);
118 }
119 }
120
121 return pe;
122 }
123
124 public static DOSHeader readDos(IDataReader dr) throws IOException {
125 DOSHeader dh = new DOSHeader();
126 dh.setMagic(dr.readWord());
127 dh.setUsedBytesInLastPage(dr.readWord());
128 dh.setFileSizeInPages(dr.readWord());
129 dh.setNumRelocationItems(dr.readWord());
130 dh.setHeaderSizeInParagraphs(dr.readWord());
131 dh.setMinExtraParagraphs(dr.readWord());
132 dh.setMaxExtraParagraphs(dr.readWord());
133 dh.setInitialSS(dr.readWord());
134 dh.setInitialSP(dr.readWord());
135 dh.setChecksum(dr.readWord());
136 dh.setInitialIP(dr.readWord());
137 dh.setInitialRelativeCS(dr.readWord());
138 dh.setAddressOfRelocationTable(dr.readWord());
139 dh.setOverlayNumber(dr.readWord());
140 int[] reserved = new int[4];
141 for (int i = 0; i < reserved.length; i++) {
142 reserved[i] = dr.readWord();
143 }
144 dh.setReserved(reserved);
145 dh.setOemId(dr.readWord());
146 dh.setOemInfo(dr.readWord());
147 int[] reserved2 = new int[10];
148 for (int i = 0; i < reserved2.length; i++) {
149 reserved2[i] = dr.readWord();
150 }
151 dh.setReserved2(reserved2);
152 dh.setAddressOfNewExeHeader(dr.readDoubleWord());
153
154
155 int stubSize = dh.getFileSizeInPages() * 512
156 - (512 - dh.getUsedBytesInLastPage());
157 if (stubSize > dh.getAddressOfNewExeHeader()) {
158 stubSize = dh.getAddressOfNewExeHeader();
159 }
160 stubSize -= dh.getHeaderSizeInParagraphs() * 16;
161 dh.setStubSize(stubSize);
162
163 return dh;
164 }
165
166 public static DOSStub readStub(DOSHeader header, IDataReader dr)
167 throws IOException {
168 DOSStub ds = new DOSStub();
169 int pos = dr.getPosition();
170 int add = header.getAddressOfNewExeHeader();
171 byte[] stub = new byte[add - pos];
172 dr.read(stub);
173 ds.setStub(stub);
174 return ds;
175 }
176
177 public static PESignature readSignature(IDataReader dr) throws IOException {
178 PESignature ps = new PESignature();
179 byte[] signature = new byte[4];
180 dr.read(signature);
181 ps.setSignature(signature);
182 return ps;
183 }
184
185 public static COFFHeader readCOFF(IDataReader dr) throws IOException {
186 COFFHeader h = new COFFHeader();
187 h.setMachine(dr.readWord());
188 h.setNumberOfSections(dr.readWord());
189 h.setTimeDateStamp(dr.readDoubleWord());
190 h.setPointerToSymbolTable(dr.readDoubleWord());
191 h.setNumberOfSymbols(dr.readDoubleWord());
192 h.setSizeOfOptionalHeader(dr.readWord());
193 h.setCharacteristics(dr.readWord());
194 return h;
195 }
196
197 public static OptionalHeader readOptional(IDataReader dr)
198 throws IOException {
199 OptionalHeader oh = new OptionalHeader();
200 oh.setMagic(dr.readWord());
201 boolean is64 = oh.isPE32plus();
202 oh.setMajorLinkerVersion(dr.readByte());
203 oh.setMinorLinkerVersion(dr.readByte());
204 oh.setSizeOfCode(dr.readDoubleWord());
205 oh.setSizeOfInitializedData(dr.readDoubleWord());
206 oh.setSizeOfUninitializedData(dr.readDoubleWord());
207 oh.setAddressOfEntryPoint(dr.readDoubleWord());
208 oh.setBaseOfCode(dr.readDoubleWord());
209
210 if (!is64) {
211 oh.setBaseOfData(dr.readDoubleWord());
212 }
213
214
215 oh.setImageBase(is64 ? dr.readLong() : dr.readDoubleWord());
216 oh.setSectionAlignment(dr.readDoubleWord());
217 oh.setFileAlignment(dr.readDoubleWord());
218 oh.setMajorOperatingSystemVersion(dr.readWord());
219 oh.setMinorOperatingSystemVersion(dr.readWord());
220 oh.setMajorImageVersion(dr.readWord());
221 oh.setMinorImageVersion(dr.readWord());
222 oh.setMajorSubsystemVersion(dr.readWord());
223 oh.setMinorSubsystemVersion(dr.readWord());
224 oh.setWin32VersionValue(dr.readDoubleWord());
225 oh.setSizeOfImage(dr.readDoubleWord());
226 oh.setSizeOfHeaders(dr.readDoubleWord());
227 oh.setCheckSum(dr.readDoubleWord());
228 oh.setSubsystem(dr.readWord());
229 oh.setDllCharacteristics(dr.readWord());
230 oh.setSizeOfStackReserve(is64 ? dr.readLong() : dr.readDoubleWord());
231 oh.setSizeOfStackCommit(is64 ? dr.readLong() : dr.readDoubleWord());
232 oh.setSizeOfHeapReserve(is64 ? dr.readLong() : dr.readDoubleWord());
233 oh.setSizeOfHeapCommit(is64 ? dr.readLong() : dr.readDoubleWord());
234 oh.setLoaderFlags(dr.readDoubleWord());
235 oh.setNumberOfRvaAndSizes(dr.readDoubleWord());
236
237
238 ImageDataDirectory[] dds = new ImageDataDirectory[16];
239 for (int i = 0; i < dds.length; i++) {
240 dds[i] = readImageDD(dr);
241 }
242 oh.setDataDirectories(dds);
243
244 return oh;
245 }
246
247 public static ImageDataDirectory readImageDD(IDataReader dr)
248 throws IOException {
249 ImageDataDirectory idd = new ImageDataDirectory();
250 idd.setVirtualAddress(dr.readDoubleWord());
251 idd.setSize(dr.readDoubleWord());
252 return idd;
253 }
254
255 public static SectionTable readSectionHeaders(PE pe, IDataReader dr)
256 throws IOException {
257 SectionTable st = new SectionTable();
258 int ns = pe.getCoffHeader().getNumberOfSections();
259 for (int i = 0; i < ns; i++) {
260 st.add(readSectionHeader(dr));
261 }
262
263 SectionHeader[] sorted = st.getHeadersPointerSorted();
264 int[] virtualAddress = new int[sorted.length];
265 int[] pointerToRawData = new int[sorted.length];
266 for (int i = 0; i < sorted.length; i++) {
267 virtualAddress[i] = sorted[i].getVirtualAddress();
268 pointerToRawData[i] = sorted[i].getPointerToRawData();
269 }
270
271 st.setRvaConverter(new RVAConverter(virtualAddress, pointerToRawData));
272 return st;
273 }
274
275 public static SectionHeader readSectionHeader(IDataReader dr)
276 throws IOException {
277 SectionHeader sh = new SectionHeader();
278 sh.setName(dr.readUtf(8));
279 sh.setVirtualSize(dr.readDoubleWord());
280 sh.setVirtualAddress(dr.readDoubleWord());
281 sh.setSizeOfRawData(dr.readDoubleWord());
282 sh.setPointerToRawData(dr.readDoubleWord());
283 sh.setPointerToRelocations(dr.readDoubleWord());
284 sh.setPointerToLineNumbers(dr.readDoubleWord());
285 sh.setNumberOfRelocations(dr.readWord());
286 sh.setNumberOfLineNumbers(dr.readWord());
287 sh.setCharacteristics(dr.readDoubleWord());
288 return sh;
289 }
290
291 public static DataEntry findNextEntry(PE pe, int pos) {
292 DataEntry de = new DataEntry();
293
294
295 int ns = pe.getCoffHeader().getNumberOfSections();
296 for (int i = 0; i < ns; i++) {
297 SectionHeader sh = pe.getSectionTable().getHeader(i);
298 if (sh.getSizeOfRawData() > 0
299 && sh.getPointerToRawData() >= pos
300 && (de.pointer == 0 || sh.getPointerToRawData() < de.pointer)) {
301 de.pointer = sh.getPointerToRawData();
302 de.index = i;
303 de.isSection = true;
304 }
305 }
306
307
308 RVAConverter rvc = pe.getSectionTable().getRVAConverter();
309 int dc = pe.getOptionalHeader().getDataDirectoryCount();
310 for (int i = 0; i < dc; i++) {
311 ImageDataDirectory idd = pe.getOptionalHeader().getDataDirectory(i);
312 if (idd.getSize() > 0) {
313 int prd = idd.getVirtualAddress();
314
315 if (i != ImageDataDirectoryType.CERTIFICATE_TABLE
316 && isInsideSection(pe, idd)) {
317 prd = rvc.convertVirtualAddressToRawDataPointer(idd
318 .getVirtualAddress());
319 }
320 if (prd >= pos && (de.pointer == 0 || prd < de.pointer)) {
321 de.pointer = prd;
322 de.index = i;
323 de.isSection = false;
324 }
325 }
326 }
327
328
329 ImageData id = pe.getImageData();
330 DebugDirectory dd = null;
331 if (id != null) {
332 dd = id.getDebug();
333 }
334 if (dd != null) {
335 int prd = dd.getPointerToRawData();
336 if (prd >= pos && (de.pointer == 0 || prd < de.pointer)) {
337 de.pointer = prd;
338 de.index = -1;
339 de.isDebugRawData = true;
340 de.isSection = false;
341 de.baseAddress = prd;
342 }
343 }
344
345 if (de.pointer == 0) {
346 return null;
347 }
348
349 return de;
350 }
351
352 private static boolean isInsideSection(PE pe, ImageDataDirectory idd) {
353 int prd = idd.getVirtualAddress();
354 int pex = prd + idd.getSize();
355 SectionTable st = pe.getSectionTable();
356 int ns = st.getNumberOfSections();
357 for (int i = 0; i < ns; i++) {
358 SectionHeader sh = st.getHeader(i);
359 int vad = sh.getVirtualAddress();
360 int vex = vad + sh.getVirtualSize();
361 if (prd >= vad && prd < vex && pex <= vex) {
362 return true;
363 }
364 }
365 return false;
366 }
367
368 private static void readImageData(PE pe, DataEntry entry, IDataReader dr)
369 throws IOException {
370
371
372 ImageData id = pe.getImageData();
373 byte[] pa = readPreambleData(entry.pointer, dr);
374 if (pa != null) {
375 id.put(entry.index, pa);
376 }
377
378
379 ImageDataDirectory idd = pe.getOptionalHeader().getDataDirectory(
380 entry.index);
381 byte[] b = new byte[idd.getSize()];
382 dr.read(b);
383
384 switch (entry.index) {
385 case ImageDataDirectoryType.EXPORT_TABLE:
386 id.setExportTable(readExportDirectory(b));
387 break;
388 case ImageDataDirectoryType.IMPORT_TABLE:
389 id.setImportTable(readImportDirectory(b, entry.baseAddress));
390 break;
391 case ImageDataDirectoryType.RESOURCE_TABLE:
392 id.setResourceTable(readResourceDirectory(b, entry.baseAddress));
393 break;
394 case ImageDataDirectoryType.EXCEPTION_TABLE:
395 id.setExceptionTable(b);
396 break;
397 case ImageDataDirectoryType.CERTIFICATE_TABLE:
398 id.setCertificateTable(readAttributeCertificateTable(b));
399 break;
400 case ImageDataDirectoryType.BASE_RELOCATION_TABLE:
401 id.setBaseRelocationTable(b);
402 break;
403 case ImageDataDirectoryType.DEBUG:
404 id.setDebug(readDebugDirectory(b));
405 break;
406 case ImageDataDirectoryType.ARCHITECTURE:
407 id.setArchitecture(b);
408 break;
409 case ImageDataDirectoryType.GLOBAL_PTR:
410 id.setGlobalPtr(b);
411 break;
412 case ImageDataDirectoryType.TLS_TABLE:
413 id.setTlsTable(b);
414 break;
415 case ImageDataDirectoryType.LOAD_CONFIG_TABLE:
416 id.setLoadConfigTable(readLoadConfigDirectory(pe, b));
417 break;
418 case ImageDataDirectoryType.BOUND_IMPORT:
419 id.setBoundImports(readBoundImportDirectoryTable(b));
420 break;
421 case ImageDataDirectoryType.IAT:
422 id.setIat(b);
423 break;
424 case ImageDataDirectoryType.DELAY_IMPORT_DESCRIPTOR:
425 id.setDelayImportDescriptor(b);
426 break;
427 case ImageDataDirectoryType.CLR_RUNTIME_HEADER:
428 id.setClrRuntimeHeader(b);
429 break;
430 case ImageDataDirectoryType.RESERVED:
431 id.setReserved(b);
432 break;
433 default:
434 break;
435 }
436 }
437
438 private static byte[] readPreambleData(int pointer, IDataReader dr)
439 throws IOException {
440 if (pointer > dr.getPosition()) {
441 byte[] pa = new byte[pointer - dr.getPosition()];
442 dr.read(pa);
443 boolean zeroes = true;
444 for (byte b : pa) {
445 if (b != 0) {
446 zeroes = false;
447 break;
448 }
449 }
450 if (!zeroes) {
451 return pa;
452 }
453 }
454
455 return null;
456 }
457
458 private static void readDebugRawData(PE pe, DataEntry entry, IDataReader dr)
459 throws IOException {
460
461 ImageData id = pe.getImageData();
462 byte[] pa = readPreambleData(entry.pointer, dr);
463 if (pa != null) {
464 id.setDebugRawDataPreamble(pa);
465 }
466 DebugDirectory dd = id.getDebug();
467 byte[] b = new byte[dd.getSizeOfData()];
468 dr.read(b);
469 id.setDebugRawData(b);
470 }
471
472 private static void readSection(PE pe, DataEntry entry, IDataReader dr)
473 throws IOException {
474 SectionTable st = pe.getSectionTable();
475 SectionHeader sh = st.getHeader(entry.index);
476 SectionData sd = new SectionData();
477
478
479 byte[] pa = readPreambleData(sh.getPointerToRawData(), dr);
480 if (pa != null) {
481 sd.setPreamble(pa);
482 }
483
484
485 dr.jumpTo(sh.getPointerToRawData());
486 byte[] b = new byte[sh.getSizeOfRawData()];
487 dr.read(b);
488 sd.setData(b);
489 st.put(entry.index, sd);
490
491
492 int ddc = pe.getOptionalHeader().getDataDirectoryCount();
493 for (int i = 0; i < ddc; i++) {
494 if (i == ImageDataDirectoryType.CERTIFICATE_TABLE) {
495 continue;
496 }
497 ImageDataDirectory idd = pe.getOptionalHeader().getDataDirectory(i);
498 if (idd.getSize() > 0) {
499 int vad = sh.getVirtualAddress();
500 int vex = vad + sh.getVirtualSize();
501 int dad = idd.getVirtualAddress();
502 if (dad >= vad && dad < vex) {
503 int off = dad - vad;
504 IDataReader idr = new ByteArrayDataReader(b, off,
505 idd.getSize());
506 DataEntry de = new DataEntry(i, 0);
507 de.baseAddress = sh.getVirtualAddress();
508 readImageData(pe, de, idr);
509 }
510 }
511 }
512 }
513
514 private static BoundImportDirectoryTable readBoundImportDirectoryTable(
515 byte[] b) throws IOException {
516 DataReader dr = new DataReader(b);
517 BoundImportDirectoryTable bidt = new BoundImportDirectoryTable();
518 List<BoundImport> imports = new ArrayList<>();
519 BoundImport bi = null;
520 while ((bi = readBoundImport(dr)) != null) {
521 bidt.add(bi);
522 imports.add(bi);
523 }
524 imports.sort((o1, o2) -> o1.getOffsetToModuleName() - o2.getOffsetToModuleName());
525 IntMap names = new IntMap();
526 for (BoundImport anImport : imports) {
527 bi = anImport;
528 int offset = bi.getOffsetToModuleName();
529 String n = (String) names.get(offset);
530 if (n == null) {
531 dr.jumpTo(offset);
532 n = dr.readUtf();
533 names.put(offset, n);
534 }
535 bi.setModuleName(n);
536 }
537 return bidt;
538 }
539
540 private static BoundImport readBoundImport(IDataReader dr)
541 throws IOException {
542 BoundImport bi = new BoundImport();
543 bi.setTimestamp(dr.readDoubleWord());
544 bi.setOffsetToModuleName(dr.readWord());
545 bi.setNumberOfModuleForwarderRefs(dr.readWord());
546
547 if (bi.getTimestamp() == 0 && bi.getOffsetToModuleName() == 0
548 && bi.getNumberOfModuleForwarderRefs() == 0) {
549 return null;
550 }
551
552 return bi;
553 }
554
555 public static ImportDirectory readImportDirectory(byte[] b, int baseAddress)
556 throws IOException {
557 DataReader dr = new DataReader(b);
558 ImportDirectory id = new ImportDirectory();
559 ImportDirectoryEntry ide = null;
560 while ((ide = readImportDirectoryEntry(dr)) != null) {
561 id.add(ide);
562 }
563
564
565
566
567
568
569
570
571
572
573
574 return id;
575 }
576
577 public static ImportDirectoryEntry readImportDirectoryEntry(IDataReader dr)
578 throws IOException {
579 ImportDirectoryEntry id = new ImportDirectoryEntry();
580 id.setImportLookupTableRVA(dr.readDoubleWord());
581 id.setTimeDateStamp(dr.readDoubleWord());
582 id.setForwarderChain(dr.readDoubleWord());
583 id.setNameRVA(dr.readDoubleWord());
584 id.setImportAddressTableRVA(dr.readDoubleWord());
585
586
587 if (id.getImportLookupTableRVA() == 0) {
588 return null;
589 }
590
591 return id;
592 }
593
594 public static ImportDirectoryTable readImportDirectoryTable(IDataReader dr,
595 int baseAddress) throws IOException {
596 ImportDirectoryTable idt = new ImportDirectoryTable();
597 ImportEntry ie = null;
598 while ((ie = readImportEntry(dr)) != null) {
599 idt.add(ie);
600 }
601
602 for (int i = 0; i < idt.size(); i++) {
603 ImportEntry iee = idt.getEntry(i);
604 if ((iee.getVal() & 0x80000000) != 0) {
605 iee.setOrdinal(iee.getVal() & 0x7fffffff);
606 } else {
607 dr.jumpTo(iee.getVal() - baseAddress);
608 dr.readWord();
609 iee.setName(dr.readUtf());
610 }
611 }
612 return idt;
613 }
614
615 public static ImportEntry readImportEntry(IDataReader dr)
616 throws IOException {
617 ImportEntry ie = new ImportEntry();
618 ie.setVal(dr.readDoubleWord());
619 if (ie.getVal() == 0) {
620 return null;
621 }
622
623 return ie;
624 }
625
626 public static ExportDirectory readExportDirectory(byte[] b)
627 throws IOException {
628 DataReader dr = new DataReader(b);
629 ExportDirectory edt = new ExportDirectory();
630 edt.set(b);
631 edt.setExportFlags(dr.readDoubleWord());
632 edt.setTimeDateStamp(dr.readDoubleWord());
633 edt.setMajorVersion(dr.readWord());
634 edt.setMinorVersion(dr.readWord());
635 edt.setNameRVA(dr.readDoubleWord());
636 edt.setOrdinalBase(dr.readDoubleWord());
637 edt.setAddressTableEntries(dr.readDoubleWord());
638 edt.setNumberOfNamePointers(dr.readDoubleWord());
639 edt.setExportAddressTableRVA(dr.readDoubleWord());
640 edt.setNamePointerRVA(dr.readDoubleWord());
641 edt.setOrdinalTableRVA(dr.readDoubleWord());
642 return edt;
643 }
644
645 public static LoadConfigDirectory readLoadConfigDirectory(PE pe, byte[] b)
646 throws IOException {
647 DataReader dr = new DataReader(b);
648 LoadConfigDirectory lcd = new LoadConfigDirectory();
649 lcd.set(b);
650 lcd.setSize(dr.readDoubleWord());
651 lcd.setTimeDateStamp(dr.readDoubleWord());
652 lcd.setMajorVersion(dr.readWord());
653 lcd.setMinorVersion(dr.readWord());
654 lcd.setGlobalFlagsClear(dr.readDoubleWord());
655 lcd.setGlobalFlagsSet(dr.readDoubleWord());
656 lcd.setCriticalSectionDefaultTimeout(dr.readDoubleWord());
657 lcd.setDeCommitFreeBlockThreshold(pe.is64() ? dr.readLong() : dr.readDoubleWord());
658 lcd.setDeCommitTotalFreeThreshold(pe.is64() ? dr.readLong() : dr.readDoubleWord());
659 lcd.setLockPrefixTable(pe.is64() ? dr.readLong() : dr.readDoubleWord());
660 lcd.setMaximumAllocationSize(pe.is64() ? dr.readLong() : dr.readDoubleWord());
661 lcd.setVirtualMemoryThreshold(pe.is64() ? dr.readLong() : dr.readDoubleWord());
662 lcd.setProcessAffinityMask(pe.is64() ? dr.readLong() : dr.readDoubleWord());
663 lcd.setProcessHeapFlags(dr.readDoubleWord());
664 lcd.setCsdVersion(dr.readWord());
665 lcd.setReserved(dr.readWord());
666 lcd.setEditList(pe.is64() ? dr.readLong() : dr.readDoubleWord());
667 if (dr.hasMore())
668 {
669 lcd.setSecurityCookie(pe.is64() ? dr.readLong() : dr.readDoubleWord());
670 }
671 if (dr.hasMore())
672 {
673 lcd.setSeHandlerTable(pe.is64() ? dr.readLong() : dr.readDoubleWord());
674 }
675 if (dr.hasMore())
676 {
677 lcd.setSeHandlerCount(pe.is64() ? dr.readLong() : dr.readDoubleWord());
678 }
679
680 return lcd;
681 }
682
683 public static DebugDirectory readDebugDirectory(byte[] b)
684 throws IOException {
685 return readDebugDirectory(b, new DataReader(b));
686 }
687
688 public static DebugDirectory readDebugDirectory(byte[] b, IDataReader dr)
689 throws IOException {
690 DebugDirectory dd = new DebugDirectory();
691 dd.set(b);
692 dd.setCharacteristics(dr.readDoubleWord());
693 dd.setTimeDateStamp(dr.readDoubleWord());
694 dd.setMajorVersion(dr.readWord());
695 dd.setMajorVersion(dr.readWord());
696 dd.setType(dr.readDoubleWord());
697 dd.setSizeOfData(dr.readDoubleWord());
698 dd.setAddressOfRawData(dr.readDoubleWord());
699 dd.setPointerToRawData(dr.readDoubleWord());
700 return dd;
701 }
702
703 private static ResourceDirectory readResourceDirectory(byte[] b,
704 int baseAddress) throws IOException {
705 IDataReader dr = new ByteArrayDataReader(b);
706 return readResourceDirectory(dr, baseAddress);
707 }
708
709 private static ResourceDirectory readResourceDirectory(IDataReader dr,
710 int baseAddress) throws IOException {
711 ResourceDirectory d = new ResourceDirectory();
712 d.setTable(readResourceDirectoryTable(dr));
713 int ne = d.getTable().getNumNameEntries()
714 + d.getTable().getNumIdEntries();
715 for (int i = 0; i < ne; i++) {
716 d.add(readResourceEntry(dr, baseAddress));
717 }
718
719 return d;
720 }
721
722 private static ResourceEntry readResourceEntry(IDataReader dr,
723 int baseAddress) throws IOException {
724 ResourceEntry re = new ResourceEntry();
725 int id = dr.readDoubleWord();
726 int offset = dr.readDoubleWord();
727 re.setOffset(offset);
728 int pos = dr.getPosition();
729 if ((id & 0x80000000) != 0) {
730 dr.jumpTo(id & 0x7fffffff);
731 re.setName(dr.readUnicode(dr.readWord()));
732 } else {
733 re.setId(id);
734 }
735 if ((offset & 0x80000000) != 0) {
736 dr.jumpTo(offset & 0x7fffffff);
737 re.setDirectory(readResourceDirectory(dr, baseAddress));
738 } else {
739 dr.jumpTo(offset);
740 int rva = dr.readDoubleWord();
741 int size = dr.readDoubleWord();
742 int cp = dr.readDoubleWord();
743 int res = dr.readDoubleWord();
744 re.setDataRVA(rva);
745 re.setCodePage(cp);
746 re.setReserved(res);
747 dr.jumpTo(rva - baseAddress);
748 byte[] b = new byte[size];
749 dr.read(b);
750 re.setData(b);
751 }
752 dr.jumpTo(pos);
753 return re;
754 }
755
756 private static ResourceDirectoryTable readResourceDirectoryTable(
757 IDataReader dr) throws IOException {
758 ResourceDirectoryTable t = new ResourceDirectoryTable();
759 t.setCharacteristics(dr.readDoubleWord());
760 t.setTimeDateStamp(dr.readDoubleWord());
761 t.setMajorVersion(dr.readWord());
762 t.setMinVersion(dr.readWord());
763 t.setNumNameEntries(dr.readWord());
764 t.setNumIdEntries(dr.readWord());
765
766 return t;
767 }
768
769 public static AttributeCertificateTable readAttributeCertificateTable(byte[] b)
770 throws IOException {
771 return readAttributeCertificateTable(b, new DataReader(b));
772 }
773
774 public static AttributeCertificateTable readAttributeCertificateTable(byte[] b, IDataReader dr)
775 throws IOException {
776 AttributeCertificateTable dd = new AttributeCertificateTable();
777 dd.set(b);
778 dd.setLength(dr.readDoubleWord());
779 dd.setRevision(dr.readWord());
780 dd.setCertificateType(dr.readWord());
781 byte[] certificate = new byte[dd.getLength() - 8];
782 dr.read(certificate);
783 dd.setCertificate(certificate);
784 return dd;
785 }
786
787 }