예제 #1
0
  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);
        }
      }
    }
  }
예제 #2
0
  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;
  }
예제 #3
0
 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);
 }
예제 #4
0
 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;
 }
예제 #5
0
  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;
  }
예제 #6
0
  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;
  }
예제 #7
0
  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;
  }
예제 #8
0
  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;
    }
  }