Exemple #1
0
// retrieve the export directory structure for a given module,
// using information from the various headers
IMAGE_EXPORT_DIRECTORY *getExportDir(HMODULE module) {
	if (!module && CACHED_EXPORT_DIR) return CACHED_EXPORT_DIR;

	IMAGE_NT_HEADERS *nt_header = getNtHeader(module);
	IMAGE_DATA_DIRECTORY *datadir = &nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
	if (datadir->Size == 0) return NULL; // no export directory

	void *result = rva_to_addr(datadir->VirtualAddress, module);
	if (!module) /* i.e. "self" */ CACHED_EXPORT_DIR = result;
	return result;
}
Exemple #2
0
bool getPDBFiles(const QString &peExecutableFileName, QStringList *rc, QString *errorMessage)
{
    HANDLE hFile = NULL;
    HANDLE hFileMap = NULL;
    void *fileMemory = 0;
    bool success = false;

    rc->clear();
    do {
        // Create a memory mapping of the file
        hFile = CreateFile(reinterpret_cast<const WCHAR*>(peExecutableFileName.utf16()), GENERIC_READ, FILE_SHARE_READ, NULL,
                             OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile == INVALID_HANDLE_VALUE || hFile == NULL) {
            *errorMessage = QString::fromLatin1("Cannot open '%1': %2").arg(peExecutableFileName, winErrorMessage(GetLastError()));
            break;
        }

        hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
        if (hFileMap == NULL) {
            *errorMessage = QString::fromLatin1("Cannot create file mapping of '%1': %2").arg(peExecutableFileName, winErrorMessage(GetLastError()));
            break;
        }

        fileMemory = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
        if (!fileMemory) {
            *errorMessage = QString::fromLatin1("Cannot map '%1': %2").arg(peExecutableFileName, winErrorMessage(GetLastError()));
            break;
        }

        IMAGE_NT_HEADERS *ntHeaders = getNtHeader(fileMemory, errorMessage);
        if (!ntHeaders)
            break;

        int debugSectionCount;
        IMAGE_DEBUG_DIRECTORY *debugDir;
        if (!getDebugDirectory(ntHeaders, fileMemory, &debugDir, &debugSectionCount, errorMessage))
            return false;
        if (debugSectionCount)
            collectPDBfiles(fileMemory, debugDir, debugSectionCount, rc);
        success = true;
    } while(false);

    if (fileMemory)
        UnmapViewOfFile(fileMemory);

    if (hFileMap != NULL)
        CloseHandle(hFileMap);

    if (hFile != NULL && hFile != INVALID_HANDLE_VALUE)
        CloseHandle(hFile);

    return success;
}
Exemple #3
0
// retrieve section header
IMAGE_SECTION_HEADER *getSectionHeader(HMODULE module, int index) {
	IMAGE_NT_HEADERS *nt_header = getNtHeader(module);
	if (index < 1 || index > nt_header->FileHeader.NumberOfSections) {
		error("getSectionHeader(%p, %d): invalid section index", module, index);
		return NULL;
	}
	// the array of section descriptors starts right after the NT header,
	// so calculate the offset (= header's size)
	IMAGE_SECTION_HEADER *result = (void*)nt_header
		+ sizeof("ULONG") + sizeof("IMAGE_FILE_HEADER") + nt_header->FileHeader.SizeOfOptionalHeader;
	return (result + (index - 1));
}
Exemple #4
0
// returns the IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag
inline bool getDynamicBase(HMODULE module) {
	IMAGE_NT_HEADERS *nt_header = getNtHeader(module);
	return (nt_header->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) != 0;
}
Exemple #5
0
// Read a PE executable and determine dependent libraries, word size
// and debug flags.
bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage,
                      QStringList *dependentLibrariesIn, unsigned *wordSizeIn,
                      bool *isDebugIn, bool isMinGW)
{
    bool result = false;
    HANDLE hFile = NULL;
    HANDLE hFileMap = NULL;
    void *fileMemory = 0;

    if (dependentLibrariesIn)
        dependentLibrariesIn->clear();
    if (wordSizeIn)
        *wordSizeIn = 0;
    if (isDebugIn)
        *isDebugIn = false;

    do {
        // Create a memory mapping of the file
        hFile = CreateFile(reinterpret_cast<const WCHAR*>(peExecutableFileName.utf16()), GENERIC_READ, FILE_SHARE_READ, NULL,
                             OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile == INVALID_HANDLE_VALUE || hFile == NULL) {
            *errorMessage = QString::fromLatin1("Cannot open '%1': %2").arg(peExecutableFileName, winErrorMessage(GetLastError()));
            break;
        }

        hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
        if (hFileMap == NULL) {
            *errorMessage = QString::fromLatin1("Cannot create file mapping of '%1': %2").arg(peExecutableFileName, winErrorMessage(GetLastError()));
            break;
        }

        fileMemory = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
        if (!fileMemory) {
            *errorMessage = QString::fromLatin1("Cannot map '%1': %2").arg(peExecutableFileName, winErrorMessage(GetLastError()));
            break;
        }

        const IMAGE_NT_HEADERS *ntHeaders = getNtHeader(fileMemory, errorMessage);
        if (!ntHeaders)
            break;

        const unsigned wordSize = ntHeaderWordSize(ntHeaders);
        if (wordSizeIn)
            *wordSizeIn = wordSize;
        bool debug = false;
        if (wordSize == 32) {
            const IMAGE_NT_HEADERS32 *ntHeaders32 = reinterpret_cast<const IMAGE_NT_HEADERS32 *>(ntHeaders);

            if (!isMinGW) {
                debug = ntHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
            } else {
                // Use logic that's used e.g. in objdump / pfd library
                debug = !(ntHeaders32->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
            }

            if (dependentLibrariesIn)
                *dependentLibrariesIn = readImportSections(ntHeaders32, fileMemory, errorMessage);

        } else {
            const IMAGE_NT_HEADERS64 *ntHeaders64 = reinterpret_cast<const IMAGE_NT_HEADERS64 *>(ntHeaders);

            if (!isMinGW) {
                debug = ntHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
            } else {
                // Use logic that's used e.g. in objdump / pfd library
                debug = !(ntHeaders64->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
            }

            if (dependentLibrariesIn)
                *dependentLibrariesIn = readImportSections(ntHeaders64, fileMemory, errorMessage);
        }

        if (isDebugIn)
            *isDebugIn = debug;
        result = true;
        if (optVerboseLevel > 1)
            std::wcout << __FUNCTION__ << ": " << peExecutableFileName
                       << ' ' << wordSize << " bit, debug: " << debug << '\n';
    } while (false);

    if (fileMemory)
        UnmapViewOfFile(fileMemory);

    if (hFileMap != NULL)
        CloseHandle(hFileMap);

    if (hFile != NULL && hFile != INVALID_HANDLE_VALUE)
        CloseHandle(hFile);

    return result;
}