int eatEntries = 0;
for (int i = 0; i < tmpEntries.length; i++) {
long rva = inBuf.readDWORD();
if (rva > 0) {
tmpEntries[i] = new ExportEntry((int)(i + imageExportDirectory.Base),
new AbsoluteAddress(rva + getBaseAddress()));
eatEntries++;
}
}
long namePtr = getFilePointerFromRVA(imageExportDirectory.AddressOfNames);
long ordPtr = getFilePointerFromRVA(imageExportDirectory.AddressOfNameOrdinals);
for (int i = 0; i < imageExportDirectory.NumberOfNames; i++) {
// read next ENT entry
inBuf.seek(namePtr);
long rva = inBuf.readDWORD();
namePtr = inBuf.getCurrent();
// read export name
inBuf.seek(getFilePointerFromRVA(rva));
String expName = inBuf.readASCII();
// read next EOT entry
inBuf.seek(ordPtr);
int ord = inBuf.readWORD();
ordPtr = inBuf.getCurrent();
tmpEntries[ord].setName(expName);
}
exportEntries = new ExportEntry[eatEntries];
int j = 0;
for (int i = 0; i < tmpEntries.length; i++)
if (tmpEntries[i] != null) exportEntries[j++] = tmpEntries[i];
logger.debug("-- Got " + exportEntries.length + " exported symbols.");
} else logger.debug("-- File contains no exports");
/////////////////////////////////////////////////////////////////
// Parse imports and build import table
importTable = new HashMap<AbsoluteAddress, Pair<String,String>>();
long impTableRVA =
pe_header.getDataDirectory()[ImageDataDirectory.IMPORT_TABLE_INDEX].VirtualAddress;
if (impTableRVA > 0) { // We have an import table
logger.debug("-- Reading image import descriptors...");
inBuf.seek(getFilePointerFromRVA(impTableRVA));
List<ImageImportDescriptor> imageImportDescriptors =
new LinkedList<ImageImportDescriptor>();
while(true) {
ImageImportDescriptor cur = new ImageImportDescriptor(inBuf);
if (cur.isZero()) break;
imageImportDescriptors.add(cur);
}
for (ImageImportDescriptor descriptor : imageImportDescriptors) {
inBuf.seek(getFilePointerFromRVA(descriptor.Name));
String libraryFileName = inBuf.readASCII();
logger.debug("-- Parsing imports from " + libraryFileName + "...");
// Normalize filenames to lower case
libraryFileName = libraryFileName.toLowerCase();
// Check if the library is bound.
boolean bound = descriptor.TimeDateStamp != 0;
/* Read Import Address Table or Import Name Table */
long iatFilePtr;
if (bound) iatFilePtr = getFilePointerFromRVA(descriptor.OriginalFirstThunk);
else iatFilePtr = getFilePointerFromRVA(descriptor.FirstThunk);
// import names will be associated to IAT addresses in any case
//AbsoluteAddress iatAddress = (new RVAPointer(this, descriptor.FirstThunk)).getVAPointer();
AbsoluteAddress iatAddress = new AbsoluteAddress(descriptor.FirstThunk + getBaseAddress());
while(true) {
inBuf.seek(iatFilePtr);
long thunk = inBuf.readDWORD();
iatFilePtr = inBuf.getCurrent(); // Save buffer position
if (thunk == 0) break;
if ((thunk & 0x80000000) != 0) {
/* Thunk contains ordinal value in low 31 bits.
* (for 64 bit files this would be the lower 63 bits. */
int ord = (int) (thunk & 0x7FFFFFFF);
String ordName = "ord(" + ord + ")";
importTable.put(iatAddress, Pair.create(libraryFileName, ordName));
} else {
/* Thunk contains an RVA of either a IMAGE_IMPORT_BY_NAME
* structure [word (ord hint) , string (function name)]
* or to a forwarder string. Forwarding not supported at
* the moment!*/
long rva = getFilePointerFromRVA(thunk);
if (rva < 0)
throw new BinaryParseException("RVA in thunk points outside of image!");
// Just skip the ord hint (WORD), we don't need it.
inBuf.seek(rva + 2);
String funcName = inBuf.readASCII();
importTable.put(iatAddress, Pair.create(libraryFileName, funcName));
}
// Advance IAT entry by one DWORD
iatAddress = new AbsoluteAddress(iatAddress.getValue() + 4);
}
}
}