private static void readSection(PE pe, DataEntry entry, IDataReader dr) throws IOException { SectionTable st = pe.getSectionTable(); SectionHeader sh = st.getHeader(entry.index); SectionData sd = new SectionData(); // Read any preamble - store if non-zero byte[] pa = readPreambleData(sh.getPointerToRawData(), dr); if (pa != null) sd.setPreamble(pa); // Read in the raw data block dr.jumpTo(sh.getPointerToRawData()); byte[] b = new byte[sh.getSizeOfRawData()]; dr.read(b); sd.setData(b); st.put(entry.index, sd); // Check for an image directory within this section int ddc = pe.getOptionalHeader().getDataDirectoryCount(); for (int i = 0; i < ddc; i++) { if (i == ImageDataDirectoryType.CERTIFICATE_TABLE) continue; ImageDataDirectory idd = pe.getOptionalHeader().getDataDirectory(i); if (idd.getSize() > 0) { int vad = sh.getVirtualAddress(); int vex = vad + sh.getVirtualSize(); int dad = idd.getVirtualAddress(); if (dad >= vad && dad < vex) { int off = dad - vad; IDataReader idr = new ByteArrayDataReader(b, off, idd.getSize()); DataEntry de = new DataEntry(i, 0); de.baseAddress = sh.getVirtualAddress(); readImageData(pe, de, idr); } } } }
public static LoadConfigDirectory readLoadConfigDirectory(PE pe, byte[] b) throws IOException { DataReader dr = new DataReader(b); LoadConfigDirectory lcd = new LoadConfigDirectory(); lcd.set(b); lcd.setSize(dr.readDoubleWord()); lcd.setTimeDateStamp(dr.readDoubleWord()); lcd.setMajorVersion(dr.readWord()); lcd.setMinorVersion(dr.readWord()); lcd.setGlobalFlagsClear(dr.readDoubleWord()); lcd.setGlobalFlagsSet(dr.readDoubleWord()); lcd.setCriticalSectionDefaultTimeout(dr.readDoubleWord()); lcd.setDeCommitFreeBlockThreshold(pe.is64() ? dr.readLong() : dr.readDoubleWord()); lcd.setDeCommitTotalFreeThreshold(pe.is64() ? dr.readLong() : dr.readDoubleWord()); lcd.setLockPrefixTable(pe.is64() ? dr.readLong() : dr.readDoubleWord()); lcd.setMaximumAllocationSize(pe.is64() ? dr.readLong() : dr.readDoubleWord()); lcd.setVirtualMemoryThreshold(pe.is64() ? dr.readLong() : dr.readDoubleWord()); lcd.setProcessAffinityMask(pe.is64() ? dr.readLong() : dr.readDoubleWord()); lcd.setProcessHeapFlags(dr.readDoubleWord()); lcd.setCsdVersion(dr.readWord()); lcd.setReserved(dr.readWord()); lcd.setEditList(pe.is64() ? dr.readLong() : dr.readDoubleWord()); if (dr.hasMore()) // optional lcd.setSecurityCookie(pe.is64() ? dr.readLong() : dr.readDoubleWord()); if (dr.hasMore()) // optional lcd.setSeHandlerTable(pe.is64() ? dr.readLong() : dr.readDoubleWord()); if (dr.hasMore()) // optional lcd.setSeHandlerCount(pe.is64() ? dr.readLong() : dr.readDoubleWord()); return lcd; }
private static void readDebugRawData(PE pe, DataEntry entry, IDataReader dr) throws IOException { // Read any preamble data ImageData id = pe.getImageData(); byte[] pa = readPreambleData(entry.pointer, dr); if (pa != null) id.setDebugRawDataPreamble(pa); DebugDirectory dd = id.getDebug(); byte[] b = new byte[dd.getSizeOfData()]; dr.read(b); id.setDebugRawData(b); }
private static boolean isInsideSection(PE pe, ImageDataDirectory idd) { int prd = idd.getVirtualAddress(); int pex = prd + idd.getSize(); SectionTable st = pe.getSectionTable(); int ns = st.getNumberOfSections(); for (int i = 0; i < ns; i++) { SectionHeader sh = st.getHeader(i); int vad = sh.getVirtualAddress(); int vex = vad + sh.getVirtualSize(); if (prd >= vad && prd < vex && pex <= vex) return true; } return false; }
public static DataEntry findNextEntry(PE pe, int pos) { DataEntry de = new DataEntry(); // Check sections first int ns = pe.getCoffHeader().getNumberOfSections(); for (int i = 0; i < ns; i++) { SectionHeader sh = pe.getSectionTable().getHeader(i); if (sh.getSizeOfRawData() > 0 && sh.getPointerToRawData() >= pos && (de.pointer == 0 || sh.getPointerToRawData() < de.pointer)) { de.pointer = sh.getPointerToRawData(); de.index = i; de.isSection = true; } } // Now check image data directories RVAConverter rvc = pe.getSectionTable().getRVAConverter(); int dc = pe.getOptionalHeader().getDataDirectoryCount(); for (int i = 0; i < dc; i++) { ImageDataDirectory idd = pe.getOptionalHeader().getDataDirectory(i); if (idd.getSize() > 0) { int prd = idd.getVirtualAddress(); // Assume certificate live outside section ? if (i != ImageDataDirectoryType.CERTIFICATE_TABLE && isInsideSection(pe, idd)) { prd = rvc.convertVirtualAddressToRawDataPointer(idd.getVirtualAddress()); } if (prd >= pos && (de.pointer == 0 || prd < de.pointer)) { de.pointer = prd; de.index = i; de.isSection = false; } } } // Check debug ImageData id = pe.getImageData(); DebugDirectory dd = null; if (id != null) dd = id.getDebug(); if (dd != null) { int prd = dd.getPointerToRawData(); if (prd >= pos && (de.pointer == 0 || prd < de.pointer)) { de.pointer = prd; de.index = -1; de.isDebugRawData = true; de.isSection = false; de.baseAddress = prd; } } if (de.pointer == 0) return null; return de; }
public static SectionTable readSectionHeaders(PE pe, IDataReader dr) throws IOException { SectionTable st = new SectionTable(); int ns = pe.getCoffHeader().getNumberOfSections(); for (int i = 0; i < ns; i++) { st.add(readSectionHeader(dr)); } SectionHeader[] sorted = st.getHeadersPointerSorted(); int[] virtualAddress = new int[sorted.length]; int[] pointerToRawData = new int[sorted.length]; for (int i = 0; i < sorted.length; i++) { virtualAddress[i] = sorted[i].getVirtualAddress(); pointerToRawData[i] = sorted[i].getPointerToRawData(); } st.setRvaConverter(new RVAConverter(virtualAddress, pointerToRawData)); return st; }
public static PE read(IDataReader dr) throws IOException { PE pe = new PE(); pe.setDosHeader(readDos(dr)); // Check if we have an old file type if (pe.getDosHeader().getAddressOfNewExeHeader() == 0 || pe.getDosHeader().getAddressOfNewExeHeader() > 8192) { return pe; } pe.setStub(readStub(pe.getDosHeader(), dr)); pe.setSignature(readSignature(dr)); // Check signature to ensure we have a pe/coff file if (!pe.getSignature().isValid()) { return pe; } pe.setCoffHeader(readCOFF(dr)); pe.setOptionalHeader(readOptional(dr)); pe.setSectionTable(readSectionHeaders(pe, dr)); pe.set64(pe.getOptionalHeader().isPE32plus()); // Now read the rest of the file DataEntry entry = null; while ((entry = findNextEntry(pe, dr.getPosition())) != null) { if (entry.isSection) { readSection(pe, entry, dr); } else if (entry.isDebugRawData) { readDebugRawData(pe, entry, dr); } else { readImageData(pe, entry, dr); } } // Read any trailing data byte[] tb = dr.readAll(); if (tb.length > 0) { pe.getImageData().setTrailingData(tb); } return pe; }
private static void readImageData(PE pe, DataEntry entry, IDataReader dr) throws IOException { // Read any preamble data ImageData id = pe.getImageData(); byte[] pa = readPreambleData(entry.pointer, dr); if (pa != null) id.put(entry.index, pa); // Read the image data ImageDataDirectory idd = pe.getOptionalHeader().getDataDirectory(entry.index); byte[] b = new byte[idd.getSize()]; dr.read(b); switch (entry.index) { case ImageDataDirectoryType.EXPORT_TABLE: id.setExportTable(readExportDirectory(b)); break; case ImageDataDirectoryType.IMPORT_TABLE: id.setImportTable(readImportDirectory(b, entry.baseAddress)); break; case ImageDataDirectoryType.RESOURCE_TABLE: id.setResourceTable(readResourceDirectory(b, entry.baseAddress)); break; case ImageDataDirectoryType.EXCEPTION_TABLE: id.setExceptionTable(b); break; case ImageDataDirectoryType.CERTIFICATE_TABLE: id.setCertificateTable(b); break; case ImageDataDirectoryType.BASE_RELOCATION_TABLE: id.setBaseRelocationTable(b); break; case ImageDataDirectoryType.DEBUG: id.setDebug(readDebugDirectory(b)); break; case ImageDataDirectoryType.ARCHITECTURE: id.setArchitecture(b); break; case ImageDataDirectoryType.GLOBAL_PTR: id.setGlobalPtr(b); break; case ImageDataDirectoryType.TLS_TABLE: id.setTlsTable(b); break; case ImageDataDirectoryType.LOAD_CONFIG_TABLE: id.setLoadConfigTable(readLoadConfigDirectory(pe, b)); break; case ImageDataDirectoryType.BOUND_IMPORT: id.setBoundImports(readBoundImportDirectoryTable(b)); break; case ImageDataDirectoryType.IAT: id.setIat(b); break; case ImageDataDirectoryType.DELAY_IMPORT_DESCRIPTOR: id.setDelayImportDescriptor(b); break; case ImageDataDirectoryType.CLR_RUNTIME_HEADER: id.setClrRuntimeHeader(b); break; case ImageDataDirectoryType.RESERVED: id.setReserved(b); break; } }