Пример #1
0
void ZapImage::SaveCorHeader()
{
    IMAGE_COR20_HEADER corHeader;

    ZeroMemory(&corHeader, sizeof(corHeader));

    corHeader.cb = VAL32(sizeof(IMAGE_COR20_HEADER));
    corHeader.MajorRuntimeVersion = VAL16(COR_VERSION_MAJOR);
    corHeader.MinorRuntimeVersion = VAL16(COR_VERSION_MINOR);
    corHeader.Flags = VAL32(COMIMAGE_FLAGS_IL_LIBRARY);

#ifdef _TARGET_X86_
    if (IsReadyToRunCompilation())
    {
        // Mark the ready-to-run image as x86-specific
        corHeader.Flags |= VAL32(COMIMAGE_FLAGS_32BITREQUIRED);
    }
#endif

    if (m_ModuleDecoder.HasManagedEntryPoint())
        corHeader.EntryPointToken = VAL32(m_ModuleDecoder.GetEntryPointToken());

    SetDirectoryData(&corHeader.ManagedNativeHeader, m_pNativeHeader);
    SetDirectoryData(&corHeader.Resources, m_pResources);
    SetDirectoryData(&corHeader.MetaData, m_pILMetaData);

    Write(&corHeader, sizeof(corHeader));
}
Пример #2
0
HRESULT CeeFileGenWriter::link()
{
    HRESULT hr = checkForErrors();
    if (! SUCCEEDED(hr))
        return hr;


    m_corHeader->Resources.VirtualAddress = VAL32(m_dwManifestRVA);
    m_corHeader->Resources.Size = VAL32(m_dwManifestSize);

    m_corHeader->StrongNameSignature.VirtualAddress = VAL32(m_dwStrongNameRVA);
    m_corHeader->StrongNameSignature.Size = VAL32(m_dwStrongNameSize);

    m_corHeader->VTableFixups.VirtualAddress = VAL32(m_dwVTableRVA);
    m_corHeader->VTableFixups.Size = VAL32(m_dwVTableSize);

    getPEWriter().setCharacteristics(
//#ifndef _WIN64
        IMAGE_FILE_32BIT_MACHINE |
//#endif
        IMAGE_FILE_EXECUTABLE_IMAGE | 
        IMAGE_FILE_LINE_NUMS_STRIPPED | 
        IMAGE_FILE_LOCAL_SYMS_STRIPPED
    );

    m_corHeader->cb = VAL32(sizeof(IMAGE_COR20_HEADER));
    m_corHeader->MajorRuntimeVersion = VAL16(COR_VERSION_MAJOR);
    m_corHeader->MinorRuntimeVersion = VAL16(COR_VERSION_MINOR);
    if (m_dllSwitch)
        getPEWriter().setCharacteristics(IMAGE_FILE_DLL);
    if (m_objSwitch)
        getPEWriter().clearCharacteristics(IMAGE_FILE_DLL | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LOCAL_SYMS_STRIPPED);
    m_corHeader->Flags = VAL32(m_comImageFlags);
    m_corHeader->EntryPointToken = VAL32(m_entryPoint);
    _ASSERTE(TypeFromToken(m_entryPoint) == mdtMethodDef || m_entryPoint == mdTokenNil || 
             TypeFromToken(m_entryPoint) == mdtFile);
    setDirectoryEntry(getCorHeaderSection(), IMAGE_DIRECTORY_ENTRY_COMHEADER, sizeof(IMAGE_COR20_HEADER), m_corHeaderOffset);

    if ((m_comImageFlags & COMIMAGE_FLAGS_IL_LIBRARY) == 0
        && !m_linked && !m_objSwitch)
    {
        hr = emitExeMain();
        if (FAILED(hr))
            return hr;

    }

    m_linked = true;

    IfFailRet(getPEWriter().link());

    return S_OK;
} // HRESULT CeeFileGenWriter::link()
Пример #3
0
BOOL PELoader::open(HMODULE hMod)
{
    IMAGE_DOS_HEADER * pdosHeader;
    
    // get the dos header...
    m_hMod = hMod;
    pdosHeader = (IMAGE_DOS_HEADER*) hMod;
    // If this is not a PE32+ image
    if (pdosHeader->e_magic == VAL16(IMAGE_DOS_SIGNATURE) &&
        0 < VAL32(pdosHeader->e_lfanew) && VAL32(pdosHeader->e_lfanew) < 0xFF0)   // has to start on first page
    {
        size_t fileAlignment;

        m_pNT32 = (IMAGE_NT_HEADERS32*) ((BYTE *)m_hMod + VAL32(pdosHeader->e_lfanew));

        m_bIsPE32 = (m_pNT32->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC));

        if (m_bIsPE32)
        {
            if ((m_pNT32->Signature != VAL32(IMAGE_NT_SIGNATURE)) ||
                (m_pNT32->FileHeader.SizeOfOptionalHeader != VAL16(sizeof(IMAGE_OPTIONAL_HEADER32))))
            {
                // Make this appear uninitalized because for some reason this file is toasted.
                m_pNT32 = NULL;
                m_hMod = NULL;
                return FALSE;
            }
            fileAlignment = VAL32(m_pNT32->OptionalHeader.FileAlignment)-1;
        }
        else //For now assume not i386 is IA64
        {
            if ((m_pNT64->Signature != VAL32(IMAGE_NT_SIGNATURE)) ||
                (m_pNT64->FileHeader.SizeOfOptionalHeader != VAL16(sizeof(IMAGE_OPTIONAL_HEADER64))))
            {
                // Make this appear uninitalized because for some reason this file is toasted.
                m_pNT64 = NULL;
                m_hMod = NULL;
                return FALSE;
            }
            fileAlignment = VAL32(m_pNT64->OptionalHeader.FileAlignment)-1;
        }
        m_FileSizeAligned = (m_FileSize + fileAlignment)&(~fileAlignment);
    }
    else
    {
        // Make this appear uninitalized because for some reason this file is toasted.
        m_hMod = NULL;
        return FALSE;
    }
    return TRUE;
}
Пример #4
0
static HRESULT FindObjMetaData(PVOID pImage, PVOID *ppMetaData, long *pcbMetaData)
{
    IMAGE_FILE_HEADER *pImageHdr;       // Header for the .obj file.
    IMAGE_SECTION_HEADER *pSectionHdr;  // Section header.
    WORD        i;                      // Loop control.

    // Get a pointer to the header and the first section.
    pImageHdr = (IMAGE_FILE_HEADER *) pImage;
    pSectionHdr = (IMAGE_SECTION_HEADER *)(pImageHdr + 1);

    // Avoid confusion.
    *ppMetaData = NULL;
    *pcbMetaData = 0;

    // Walk each section looking for .cormeta.
    for (i=0;  i<VAL16(pImageHdr->NumberOfSections);  i++, pSectionHdr++)
    {
        // Simple comparison to section name.
        if (strcmp((const char *) pSectionHdr->Name, g_szCORMETA) == 0)
        {
            *pcbMetaData = VAL32(pSectionHdr->SizeOfRawData);
            *ppMetaData = (void *) ((long) pImage + VAL32(pSectionHdr->PointerToRawData));
            break;
        }
    }

    // Check for errors.
    if (*ppMetaData == NULL || *pcbMetaData == 0)
        return (E_FAIL);
    return (S_OK);
}
Пример #5
0
EXTERN_C PIMAGE_SECTION_HEADER
Cor_RtlImageRvaRangeToSection(PTR_IMAGE_NT_HEADERS NtHeaders,
                              ULONG Rva,
                              ULONG Range,
                              ULONG FileLength)
{
    LIMITED_METHOD_CONTRACT;
    ULONG i;
    PTR_IMAGE_SECTION_HEADER NtSection;

    if (!Range)
        return Cor_RtlImageRvaToSection(NtHeaders, Rva, FileLength);

    NtSection = PTR_IMAGE_FIRST_SECTION( NtHeaders );
    for (i=0; i<VAL16(NtHeaders->FileHeader.NumberOfSections); i++) {
        if (FileLength &&
            ((VAL32(NtSection->PointerToRawData) > FileLength) ||
             (VAL32(NtSection->SizeOfRawData) > FileLength - VAL32(NtSection->PointerToRawData))))
            return NULL;
        if (Rva >= VAL32(NtSection->VirtualAddress) &&
            Rva + Range <= VAL32(NtSection->VirtualAddress) + VAL32(NtSection->SizeOfRawData))
            return NtSection;
        
        ++NtSection;
    }

    return NULL;
}
Пример #6
0
IMAGE_NT_HEADERS *Cor_RtlImageNtHeader(VOID *pvBase, ULONG FileLength)
{
    LIMITED_METHOD_CONTRACT;
    IMAGE_NT_HEADERS *pNtHeaders = NULL;
    if (pvBase && (pvBase != (VOID*)-1)) {
        struct Param
        {
            IMAGE_DOS_HEADER *pDos;
            ULONG FileLength;
            IMAGE_NT_HEADERS *pNtHeaders;
        } param;
        param.pDos = (IMAGE_DOS_HEADER*)pvBase;
        param.FileLength = FileLength;
        param.pNtHeaders = pNtHeaders;

        PAL_TRY(Param *, pParam, &param) {
            if (   (pParam->pDos->e_magic == VAL16(IMAGE_DOS_SIGNATURE)) 
                && ((DWORD)VAL32(pParam->pDos->e_lfanew) < RTLP_IMAGE_MAX_DOS_HEADER) 
                && ovadd_lt((DWORD)VAL32(pParam->pDos->e_lfanew), sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD), pParam->FileLength)) {
                pParam->pNtHeaders = (IMAGE_NT_HEADERS*)((BYTE*)pParam->pDos + VAL32(pParam->pDos->e_lfanew));
                if (pParam->pNtHeaders->Signature != VAL32(IMAGE_NT_SIGNATURE))
                    pParam->pNtHeaders = NULL;
            }
        }
        PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
            param.pNtHeaders = NULL;
        }
        PAL_ENDTRY

        pNtHeaders = param.pNtHeaders;
    }
    return pNtHeaders;
}
Пример #7
0
void
pci_cfgacc_acc(pci_cfgacc_req_t *req)
{
	if (!req->write)
		VAL64(req) = (uint64_t)-1;

	if (!pci_cfgacc_valid(req))
		return;

	if (req->write) {
		pci_cfgacc_set(req->rcdip, req->bdf, req->offset,
		    req->size, VAL64(req));
	} else {
		VAL64(req) = pci_cfgacc_get(req->rcdip, req->bdf,
		    req->offset, req->size);
		switch (req->size) {
		case 1:
			VAL8(req) = (uint8_t)VAL64(req);
			break;
		case 2:
			VAL16(req) = (uint16_t)VAL64(req);
			break;
		case 4:
			VAL32(req) = (uint32_t)VAL64(req);
			break;
		case 8:
			/* fall through, no special handling needed */
		default:
			break;
		}
	}
}
Пример #8
0
EXTERN_C PBYTE Cor_RtlImageRvaToVa(PTR_IMAGE_NT_HEADERS NtHeaders,
                                   PBYTE Base,
                                   ULONG Rva,
                                   ULONG FileLength)
{
    LIMITED_METHOD_CONTRACT;
    if (NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC))
        return Cor_RtlImageRvaToVa32((PTR_IMAGE_NT_HEADERS32)NtHeaders,
                                     Base, Rva, FileLength);
    else if(NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC))
        return Cor_RtlImageRvaToVa64((PTR_IMAGE_NT_HEADERS64)NtHeaders,
                                     Base, Rva, FileLength);
    else {
        _ASSERTE(!"Invalid File Type");
        return NULL;
    }
}
Пример #9
0
uint16_t
pci_cfgacc_get16(dev_info_t *rcdip, uint16_t bdf, uint16_t off)
{
	pci_cfgacc_req_t req;

	PCI_CFGACC_FILLREQ(req, rcdip, bdf, off, 2, B_FALSE, 0);
	(*pci_cfgacc_acc_p)(&req);
	return (VAL16(&req));
}
Пример #10
0
static void
pci_cfgacc_io(pci_cfgacc_req_t *req)
{
	uint8_t bus, dev, func;
	uint16_t ioacc_offset;	/* 4K config access with IO ECS */

	bus = PCI_BDF_BUS(req->bdf);
	dev = PCI_BDF_DEV(req->bdf);
	func = PCI_BDF_FUNC(req->bdf);
	ioacc_offset = req->offset;

	switch (req->size) {
	case 1:
		if (req->write)
			(*pci_putb_func)(bus, dev, func,
			    ioacc_offset, VAL8(req));
		else
			VAL8(req) = (*pci_getb_func)(bus, dev, func,
			    ioacc_offset);
		break;
	case 2:
		if (req->write)
			(*pci_putw_func)(bus, dev, func,
			    ioacc_offset, VAL16(req));
		else
			VAL16(req) = (*pci_getw_func)(bus, dev, func,
			    ioacc_offset);
		break;
	case 4:
		if (req->write)
			(*pci_putl_func)(bus, dev, func,
			    ioacc_offset, VAL32(req));
		else
			VAL32(req) = (*pci_getl_func)(bus, dev, func,
			    ioacc_offset);
		break;
	case 8:
		if (req->write) {
			(*pci_putl_func)(bus, dev, func,
			    ioacc_offset, VAL64(req) & 0xffffffff);
			(*pci_putl_func)(bus, dev, func,
			    ioacc_offset + 4, VAL64(req) >> 32);
		} else {
Пример #11
0
EXTERN_C PBYTE Cor_RtlImageDirToVa(PTR_IMAGE_NT_HEADERS NtHeaders,
                                   PBYTE Base,
                                   UINT  DirIndex,
                                   ULONG FileLength)
{
    LIMITED_METHOD_CONTRACT;
    if (NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC))
        return Cor_RtlImageRvaToVa32((PTR_IMAGE_NT_HEADERS32)NtHeaders, Base, 
                                     VAL32(((PTR_IMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.DataDirectory[DirIndex].VirtualAddress), 
                                     FileLength);
    else if(NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC))
        return Cor_RtlImageRvaToVa64((PTR_IMAGE_NT_HEADERS64)NtHeaders, Base, 
                                     VAL32(((PTR_IMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.DataDirectory[DirIndex].VirtualAddress), 
                                     FileLength);
    else {
        _ASSERTE(!"Invalid File Type");
        return NULL;
    }
}
Пример #12
0
static bool 
ReadValue16(const libunwindInfo* info, unw_word_t* addr, uint16_t* valp)
{
    uint16_t value;
    if (!info->ReadMemory((PVOID)*addr, &value, sizeof(value))) {
        return false;
    }
    *addr += sizeof(value);
    *valp = VAL16(value);
    return true;
}
Пример #13
0
gboolean mime_cache_load( MimeCache* cache, const char* file_path )
{
    guint majv, minv;
    int fd = -1;
    struct stat statbuf;
    char* buffer = NULL;
    guint32 offset;

    /* Unload old cache first if needed */
    if( file_path == cache->file_path )
        cache->file_path = NULL; /* steal the string to prevent it from being freed during unload */
    mime_cache_unload( cache, TRUE );

    /* Store the file path */
    cache->file_path = g_strdup( file_path );

    /* Open the file and map it into memory */
    fd = open ( file_path, O_RDONLY, 0 );

    if ( fd < 0 )
        return FALSE;

    if( fstat ( fd, &statbuf ) < 0 )
    {
        close( fd );
        return FALSE;
    }

#ifdef HAVE_MMAP
    buffer = mmap( NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0 );
#else
    buffer = g_malloc( statbuf.st_size );
    if( buffer )
        read( fd, buffer, statbuf.st_size );
    else
        buffer = (void*)-1;
#endif
    close( fd );

    if ( buffer == (void*)-1 )
        return FALSE;

    majv = VAL16( buffer, MAJOR_VERSION );
    minv = VAL16( buffer, MINOR_VERSION);

    /* Check version */
    if ( majv > LIB_MAJOR_VERSION || minv > LIB_MAX_MINOR_VERSION || minv < LIB_MIN_MINOR_VERSION )
    {
#ifdef HAVE_MMAP
        munmap ( buffer, statbuf.st_size );
#else
        g_free( buffer );
#endif
        return FALSE;
    }

    /* Since mime.cache v1.1, shared mime info v0.4
     * suffix tree is replaced with reverse suffix tree,
     * and glob and literal strings are sorted by weight. */
    if( minv >= 1 )
    {
        cache->has_reverse_suffix = TRUE;
        cache->has_str_weight = TRUE;
    }

    cache->buffer = buffer;
    cache->size = statbuf.st_size;

    offset = VAL32(buffer, ALIAS_LIST);
    cache->alias = buffer + offset + 4;
    cache->n_alias = VAL32( buffer, offset );

    offset = VAL32(buffer, PARENT_LIST);
    cache->parents = buffer + offset + 4;
    cache->n_parents = VAL32( buffer, offset );

    offset = VAL32(buffer, LITERAL_LIST);
    cache->literals = buffer + offset + 4;
    cache->n_literals = VAL32( buffer, offset );

    offset = VAL32(buffer, GLOB_LIST);
    cache->globs = buffer + offset + 4;
    cache->n_globs = VAL32( buffer, offset );

    offset = VAL32(buffer, SUFFIX_TREE);
    cache->suffix_roots = buffer + VAL32( buffer + offset, 4 );
    cache->n_suffix_roots = VAL32( buffer, offset );

    offset = VAL32(buffer, MAGIC_LIST);
    cache->n_magics = VAL32( buffer, offset );
    cache->magic_max_extent = VAL32( buffer + offset, 4 );
    cache->magics = buffer + VAL32( buffer + offset, 8 );

    return TRUE;
}
Пример #14
0
HRESULT CAsmLink::SetAssemblyProps(mdAssembly AssemblyID, mdToken FileToken, AssemblyOptions Option, VARIANT Value)
{
    ASSERT(m_bInited && !m_bPreClosed && m_pAssem && !m_bManifestEmitted);
    ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM);
    ASSERT((RidFromToken(FileToken) < m_pAssem->CountFiles() && TypeFromToken(FileToken) == mdtFile) ||
        (FileToken == AssemblyID));

    HRESULT hr = S_OK;
    if (Option >= optLastAssemOption || OptionCAs[Option].flag & 0x40)
        return E_INVALIDARG;
    if (AssemblyID == AssemblyIsUBM || (OptionCAs[Option].flag & 0x02)) {
        CFile *file = NULL;
        if (FileToken == AssemblyID)
            file = m_pAssem;
        else if (FAILED(hr = m_pAssem->GetFile(FileToken, &file)))
            return hr;

        ASSERT(file->GetEmitScope());
        IMetaDataEmit* pEmit = file->GetEmitScope();
        CComPtr<IMetaDataImport> pImport;
        mdToken tkAttrib = mdTokenNil, tkCtor;
        DWORD cbValue = 0, cbSig = 4;
        BYTE pbValue[2048];
        PBYTE pBlob = pbValue;
        COR_SIGNATURE newSig[9];
        LPCWSTR wszStr = NULL;
        ULONG wLen = 0;

        if (FAILED(hr = pEmit->QueryInterface(IID_IMetaDataImport, (void**)&pImport)))
            return hr;

        // Find or Create the TypeRef (This always scopes it to MSCORLIB)
        if (FAILED(hr = file->GetTypeRef(OptionCAs[Option].name, &tkAttrib)))
            return hr;

        // Make the Blob
        newSig[0] = (IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS);
        newSig[1] = 1; // One parameter
        newSig[2] = ELEMENT_TYPE_VOID;
        *(WORD*)pBlob = VAL16(1); // This is aligned
        pBlob += sizeof(WORD);

        if (V_VT(&Value) != OptionCAs[Option].vt)
            return E_INVALIDARG;
        switch(OptionCAs[Option].vt) {
        case VT_BOOL:
            *pBlob++ = (V_BOOL(&Value) == VARIANT_TRUE);
            newSig[3] = ELEMENT_TYPE_BOOLEAN;
            break;
        case VT_UI4:
            SET_UNALIGNED_VAL32(pBlob, V_UI4(&Value));
            pBlob += sizeof(ULONG);
            newSig[3] = ELEMENT_TYPE_U4;
            break;
        case VT_BSTR:
            if (Option == optAssemOS) {
                LPWSTR end = NULL;
                mdToken tkPlatform = mdTokenNil;
                newSig[1] = 2; // Two parameters
                newSig[3] = ELEMENT_TYPE_VALUETYPE;

                // Make the TypeRef
                if (FAILED(hr = file->GetTypeRef( PLATFORMID_NAME, &tkPlatform)))
                     break;

                cbSig = 5 + CorSigCompressToken(tkPlatform, newSig + 4);
                newSig[cbSig - 1] = ELEMENT_TYPE_STRING;
                SET_UNALIGNED_VAL32(pBlob, wcstoul(V_BSTR(&Value), &end, 0)); // Parse Hex, Octal, and Decimal
                pBlob += sizeof(ULONG);
                if (*end == L'.') {
                    wszStr = end++;
                    wLen = SysStringLen(V_BSTR(&Value)) - (UINT)(V_BSTR(&Value) - end);
                    goto ADDSTRING;
                } else {
                    hr = file->ReportError(ERR_InvalidOSString);
                    return hr;
                }
            } else {
                newSig[3] = ELEMENT_TYPE_STRING;
                wLen = SysStringLen(V_BSTR(&Value));
                wszStr = V_BSTR(&Value);
ADDSTRING:
                if (wLen == 0) {
                    // Too small for unilib
                    *pBlob++ = 0xFF;
                } else if (wLen & 0x80000000) {
                    // Too big!
                    return ReportOptionError(file, Option, E_INVALIDARG);
                } else if ((OptionCAs[Option].flag & 0x10) && wLen > MAX_PATH) {
                    // Too big!
                    return ReportOptionError(file, Option, HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW)); // File name too long
                } else {
                    CHAR pUTF8[2048];
                    int iLen = wLen;
    
                    wLen = (UINT)UnicodeToUTF8(wszStr, &iLen, pUTF8, lengthof(pUTF8));

                    iLen = (int)CorSigCompressData( wLen, pBlob);
                    pBlob += iLen;
                    if (wLen > (UINT)(pbValue + lengthof(pbValue) - pBlob)) {
                        // Too big!
                        return ReportOptionError(file, Option, HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW));
                    }
                    memcpy(pBlob, pUTF8, wLen);
                    pBlob += wLen;
                }
            }
            break;
        default:
            VSFAIL("Unknown Option Type!");
            newSig[3] = ELEMENT_TYPE_OBJECT;
            break;
        }
        hr = pImport->FindMemberRef(tkAttrib, L".ctor", newSig, cbSig, &tkCtor);
        if ((hr == CLDB_E_RECORD_NOTFOUND && FAILED(hr = pEmit->DefineMemberRef(tkAttrib, L".ctor", newSig, 4, &tkCtor))) ||
            FAILED(hr))
            return hr;
        cbValue = (DWORD)(pBlob - pbValue);

        // Emit the CA
        // This will also set the option if appropriate
        hr = EmitAssemblyCustomAttribute( AssemblyID, FileToken, tkCtor, pbValue, cbValue, 
            (OptionCAs[Option].flag & 0x08) ? TRUE : FALSE,
            (OptionCAs[Option].flag & 0x04) ? TRUE : FALSE);
    } else {
        // An assembly level custom attribute
        hr = m_pAssem->SetOption(Option, &Value);
    }
    return hr;
}
Пример #15
0
DWORD	DumpResourceToFile(WCHAR*	wzFileName)
{

	BYTE*	pbResBase;
	FILE*	pF = NULL;
	DWORD ret = 0;
	DWORD	dwResDirRVA;
	DWORD	dwResDirSize;
	
	if (g_pPELoader->IsPE32())
	{
	    IMAGE_OPTIONAL_HEADER32 *pOptHeader = &(g_pPELoader->ntHeaders32()->OptionalHeader);
	
		dwResDirRVA = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
		dwResDirSize = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
	}
	else
	{
	    IMAGE_OPTIONAL_HEADER64 *pOptHeader = &(g_pPELoader->ntHeaders64()->OptionalHeader);

		dwResDirRVA = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
		dwResDirSize = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
	}

	if(dwResDirRVA && dwResDirSize)
	{
		ULONG L = (ULONG)wcslen(wzFileName)*3+3;
		char* szFileNameANSI = new char[L];
		memset(szFileNameANSI,0,L);
		WszWideCharToMultiByte(CP_ACP,0,wzFileName,-1,szFileNameANSI,L,NULL,NULL);
		pF = fopen(szFileNameANSI,"wb");
		delete [] szFileNameANSI;
 		if(pF)
		{
			if(g_pPELoader->getVAforRVA(dwResDirRVA, (void **) &pbResBase))
			{
				// First, pull out all resource nodes (tree leaves), see ResourceNode struct
				PIMAGE_RESOURCE_DIRECTORY pirdType = (PIMAGE_RESOURCE_DIRECTORY)pbResBase;
				PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeType = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbResBase+sizeof(IMAGE_RESOURCE_DIRECTORY));
				DWORD	dwTypeID;
				unsigned short i,N = VAL16(pirdType->NumberOfNamedEntries)+VAL16(pirdType->NumberOfIdEntries);
				
				for(i=0; i < N; i++, pirdeType++)
				{
					dwTypeID = VAL32(IMAGE_RDE_NAME(pirdeType));
					if(IMAGE_RDE_OFFSET_FIELD(pirdeType, DataIsDirectory))
					{
						BYTE*	pbNameBase = pbResBase + VAL32(IMAGE_RDE_OFFSET_FIELD(pirdeType, OffsetToDirectory));
						PIMAGE_RESOURCE_DIRECTORY pirdName = (PIMAGE_RESOURCE_DIRECTORY)pbNameBase;
						PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeName = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbNameBase+sizeof(IMAGE_RESOURCE_DIRECTORY));
						DWORD	dwNameID;
						unsigned short i,N = VAL16(pirdName->NumberOfNamedEntries)+VAL16(pirdName->NumberOfIdEntries);

						for(i=0; i < N; i++, pirdeName++)
						{
							dwNameID = VAL32(IMAGE_RDE_NAME(pirdeName));
							if(IMAGE_RDE_OFFSET_FIELD(pirdeName, DataIsDirectory))
							{
								BYTE*	pbLangBase = pbResBase + VAL32(IMAGE_RDE_OFFSET_FIELD(pirdeName, OffsetToDirectory));
								PIMAGE_RESOURCE_DIRECTORY pirdLang = (PIMAGE_RESOURCE_DIRECTORY)pbLangBase;
								PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeLang = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbLangBase+sizeof(IMAGE_RESOURCE_DIRECTORY));
								DWORD	dwLangID;
								unsigned short i,N = VAL32(pirdLang->NumberOfNamedEntries)+VAL16(pirdLang->NumberOfIdEntries);

								for(i=0; i < N; i++, pirdeLang++)
								{
									dwLangID = IMAGE_RDE_NAME(pirdeLang);
									if(IMAGE_RDE_OFFSET_FIELD(pirdeLang, DataIsDirectory))
									{
										_ASSERTE(!"Resource hierarchy exceeds three levels");
									}
									else
									{
										if (g_prResNodePtr == NULL)
										{
											g_prResNodePtr = new DynamicArray<ResourceNode*>;
										}
										(*g_prResNodePtr)[ulNumResNodes++] = new ResourceNode(dwTypeID,dwNameID,dwLangID,pbResBase + VAL32(IMAGE_RDE_OFFSET(pirdeLang)));
									}
								}
							}
							else
							{
								if (g_prResNodePtr == NULL)
								{
									g_prResNodePtr = new DynamicArray<ResourceNode*>;
								}
								(*g_prResNodePtr)[ulNumResNodes++] = new ResourceNode(dwTypeID,dwNameID,0,pbResBase + VAL32(IMAGE_RDE_OFFSET(pirdeName)));
							}
						}
					}
					else
					{
						if (g_prResNodePtr == NULL)
						{
							g_prResNodePtr = new DynamicArray<ResourceNode*>;
						}
						(*g_prResNodePtr)[ulNumResNodes++] = new ResourceNode(dwTypeID,0,0,pbResBase + VAL32(IMAGE_RDE_OFFSET(pirdeType)));
					}
				}
				// OK, all tree leaves are in ResourceNode structs, and ulNumResNodes ptrs are in g_prResNodePtr
				// Dump them to pF
				if(ulNumResNodes)
				{
					BYTE* pbData;
					// Write dummy header
					ResourceHeader	*pRH = new ResourceHeader();
					fwrite(pRH,sizeof(ResourceHeader),1,pF);
					delete pRH;
					DWORD	dwFiller;
					BYTE	bNil[3] = {0,0,0};
					// For each resource write header and data
					for(i=0; i < ulNumResNodes; i++)
					{
						if(g_pPELoader->getVAforRVA(VAL32((*g_prResNodePtr)[i]->DataEntry.OffsetToData), (void **) &pbData))
						{
							fwrite(&((*g_prResNodePtr)[i]->ResHdr),sizeof(ResourceHeader),1,pF);
							fwrite(pbData,VAL32((*g_prResNodePtr)[i]->DataEntry.Size),1,pF);
							dwFiller = VAL32((*g_prResNodePtr)[i]->DataEntry.Size) & 3;
							if(dwFiller)
							{
								dwFiller = 4 - dwFiller;
								fwrite(bNil,dwFiller,1,pF);
							}
						}
						delete (*g_prResNodePtr)[i];
					}
				}
				if (g_prResNodePtr)
				{
					delete g_prResNodePtr;
					g_prResNodePtr = NULL;
				}
				ulNumResNodes = 0;
				ret = 1;
			}// end if got ptr to resource
			else ret = 0xFFFFFFFF;
			if(pF) fclose(pF);
		}// end if file opened
		else ret = 0xEFFFFFFF;
	} // end if there is resource
	else ret = 0;
	return ret;
}
Пример #16
0
DWORD   DumpResourceToFile(__in __nullterminated WCHAR*   wzFileName)
{

    BYTE*   pbResBase;
    FILE*   pF = NULL;
    DWORD ret = 0;
    DWORD   dwResDirRVA;
    DWORD   dwResDirSize;
    unsigned ulNumResNodes=0;
    DynamicArray<ResourceNode*> g_prResNodePtr;

    if (g_pPELoader->IsPE32())
    {
        IMAGE_OPTIONAL_HEADER32 *pOptHeader = &(g_pPELoader->ntHeaders32()->OptionalHeader);

        dwResDirRVA = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
        dwResDirSize = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
    }
    else
    {
        IMAGE_OPTIONAL_HEADER64 *pOptHeader = &(g_pPELoader->ntHeaders64()->OptionalHeader);

        dwResDirRVA = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
        dwResDirSize = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
    }

    if(dwResDirRVA && dwResDirSize)
    {
        if(g_pPELoader->getVAforRVA(dwResDirRVA, (void **) &pbResBase))
        {
            // First, pull out all resource nodes (tree leaves), see ResourceNode struct
            PIMAGE_RESOURCE_DIRECTORY pirdType = (PIMAGE_RESOURCE_DIRECTORY)pbResBase;
            PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeType = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbResBase+sizeof(IMAGE_RESOURCE_DIRECTORY));
            DWORD	dwTypeID;
            unsigned short i = 0,N = pirdType->NumberOfNamedEntries+pirdType->NumberOfIdEntries;
            PAL_CPP_TRY {
                for(i=0; i < N; i++, pirdeType++)
                {
                    dwTypeID = VAL32(IMAGE_RDE_NAME(pirdeType));
                    if(IMAGE_RDE_OFFSET_FIELD(pirdeType, DataIsDirectory))
                    {
                        BYTE*   pbNameBase = pbResBase + VAL32(IMAGE_RDE_OFFSET_FIELD(pirdeType, OffsetToDirectory));
                        PIMAGE_RESOURCE_DIRECTORY pirdName = (PIMAGE_RESOURCE_DIRECTORY)pbNameBase;
                        PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeName = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbNameBase+sizeof(IMAGE_RESOURCE_DIRECTORY));
                        DWORD   dwNameID;
                        unsigned short i,N = VAL16(pirdName->NumberOfNamedEntries)+VAL16(pirdName->NumberOfIdEntries);

                        for(i=0; i < N; i++, pirdeName++)
                        {
                            dwNameID = VAL32(IMAGE_RDE_NAME(pirdeName));
                            if(IMAGE_RDE_OFFSET_FIELD(pirdeName, DataIsDirectory))
                            {
                                BYTE*   pbLangBase = pbResBase + VAL32(IMAGE_RDE_OFFSET_FIELD(pirdeName, OffsetToDirectory));
                                PIMAGE_RESOURCE_DIRECTORY pirdLang = (PIMAGE_RESOURCE_DIRECTORY)pbLangBase;
                                PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeLang = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbLangBase+sizeof(IMAGE_RESOURCE_DIRECTORY));
                                DWORD   dwLangID;
                                unsigned short i,N = VAL16(pirdLang->NumberOfNamedEntries)+VAL16(pirdLang->NumberOfIdEntries);

                                for(i=0; i < N; i++, pirdeLang++)
                                {
                                    dwLangID = VAL32(IMAGE_RDE_NAME(pirdeLang));
                                    if(IMAGE_RDE_OFFSET_FIELD(pirdeLang, DataIsDirectory))
                                    {
                                        _ASSERTE(!"Resource hierarchy exceeds three levels");
                                    }
                                    else
                                    {
                                        g_prResNodePtr[ulNumResNodes++] = new ResourceNode(dwTypeID,dwNameID,dwLangID, VAL32(IMAGE_RDE_OFFSET(pirdeLang)),pbResBase);
                                    }
                                }
                            }
                            else
                            {
                                g_prResNodePtr[ulNumResNodes++] = new ResourceNode(dwTypeID,dwNameID,0,VAL32(IMAGE_RDE_OFFSET(pirdeName)),pbResBase);
                            }
                        }
                    }
                    else
                    {
                        g_prResNodePtr[ulNumResNodes++] = new ResourceNode(dwTypeID,0,0,VAL32(IMAGE_RDE_OFFSET(pirdeType)),pbResBase);
                    }
                }
            } PAL_CPP_CATCH_ALL {
                ret= 0xDFFFFFFF;
                ulNumResNodes = 0;
            }
            PAL_CPP_ENDTRY
            // OK, all tree leaves are in ResourceNode structs, and ulNumResNodes ptrs are in g_prResNodePtr
            if(ulNumResNodes)
            {
                ret = 1;
#ifdef RES_FILE_DUMP_ENABLED

                _wfopen_s(&pF,wzFileName,L"wb");
                if(pF)
                {
                    // Dump them to pF
                    // Write dummy header
                    ResourceHeader  *pRH = new ResourceHeader();
                    fwrite(pRH,sizeof(ResourceHeader),1,pF);
                    SDELETE(pRH);
                    // For each resource write header and data
                    PAL_CPP_TRY {
                        for(i=0; i < ulNumResNodes; i++)
                        {
                            /*
                            sprintf_s(szString,SZSTRING_SIZE,"// Res.# %d Type=0x%X Name=0x%X Lang=0x%X DataOffset=0x%X DataLength=%d",
                                i+1,
                                g_prResNodePtr[i]->ResHdr.dwTypeID,
                                g_prResNodePtr[i]->ResHdr.dwNameID,
                                g_prResNodePtr[i]->ResHdr.wLangID,
                                VAL32(g_prResNodePtr[i]->DataEntry.OffsetToData),
                                VAL32(g_prResNodePtr[i]->DataEntry.Size));
                            printLine(NULL,szString);
                            */
                            g_prResNodePtr[i]->Save(pF);
                            SDELETE(g_prResNodePtr[i]);
                        }
                    }
                    PAL_CPP_CATCH_ALL {
                        ret= 0xDFFFFFFF;
                    }
                    PAL_CPP_ENDTRY
                    fclose(pF);
                }// end if file opened
                else ret = 0xEFFFFFFF;
#else
                // Dump to text, using wzFileName as GUICookie
                //char szString[4096];
                void* GUICookie = (void*)wzFileName;
                BYTE* pbData;
                printLine(GUICookie,"");
                sprintf(szString,"// ========== Win32 Resource Entries (%d) ========",ulNumResNodes);
                for(i=0; i < ulNumResNodes; i++)
                {
                    printLine(GUICookie,"");
                    sprintf(szString,"// Res.# %d Type=0x%X Name=0x%X Lang=0x%X DataOffset=0x%X DataLength=%d",
                        i+1,
                        g_prResNodePtr[i]->ResHdr.dwTypeID,
                        g_prResNodePtr[i]->ResHdr.dwNameID,
                        g_prResNodePtr[i]->ResHdr.wLangID,
                        VAL32(g_prResNodePtr[i]->DataEntry.OffsetToData),
                        VAL32(g_prResNodePtr[i]->DataEntry.Size));
                    printLine(GUICookie,szString);
                    if(g_pPELoader->getVAforRVA(VAL32(g_prResNodePtr[i]->DataEntry.OffsetToData), (void **) &pbData))
                    {
                        strcat(g_szAsmCodeIndent,"//  ");
                        strcpy(szString,g_szAsmCodeIndent);
                        DumpByteArray(szString,pbData,VAL32(g_prResNodePtr[i]->DataEntry.Size),GUICookie);
                        printLine(GUICookie,szString);
                        g_szAsmCodeIndent[strlen(g_szAsmCodeIndent)-4] = 0;
                    }
                    SDELETE(g_prResNodePtr[i]);
                }
                ret = 1;
#endif
            } // end if there are nodes
        }// end if got ptr to resource
Пример #17
0
HRESULT CLiteWeightStgdbRW::FindObjMetaData(PVOID pImage, DWORD dwFileLength, PVOID *ppMetaData, ULONG *pcbMetaData)
{
    DWORD   dwSize = 0;
    DWORD   dwOffset = 0;
    
    ANON_OBJECT_HEADER2 *pAnonImageHdr = (ANON_OBJECT_HEADER2 *) pImage;    // Anonymous object header
    
    // Check to see if this is a LTCG object
    if (dwFileLength >= sizeof(ANON_OBJECT_HEADER2) &&
         pAnonImageHdr->Sig1 == VAL16(IMAGE_FILE_MACHINE_UNKNOWN) &&
         pAnonImageHdr->Sig2 == VAL16(IMPORT_OBJECT_HDR_SIG2))
    {
        // Version 1 anonymous objects don't have metadata info
        if (VAL16(pAnonImageHdr->Version) < 2)
            goto BadFormat;
        
        // Anonymous objects contain the metadata info in the header
        dwOffset = VAL32(pAnonImageHdr->MetaDataOffset);
        dwSize = VAL32(pAnonImageHdr->MetaDataSize);
    }
    else
    {
        // Check to see if we have enough data
        if (dwFileLength < sizeof(IMAGE_FILE_HEADER))
            goto BadFormat;
        
        IMAGE_FILE_HEADER *pImageHdr = (IMAGE_FILE_HEADER *) pImage;            // Header for the .obj file.
        
        // Walk each section looking for .cormeta.
        DWORD nSections = VAL16(pImageHdr->NumberOfSections);
        
        // Check to see if we have enough data
        S_UINT32 nSectionsSize = S_UINT32(sizeof(IMAGE_FILE_HEADER)) + S_UINT32(nSections) * S_UINT32(sizeof(IMAGE_SECTION_HEADER));
        if (nSectionsSize.IsOverflow() || (dwFileLength < nSectionsSize.Value()))
            goto BadFormat;
        
        IMAGE_SECTION_HEADER *pSectionHdr = (IMAGE_SECTION_HEADER *)(pImageHdr + 1);  // Section header.
        
        for (DWORD i=0; i<nSections;  i++, pSectionHdr++)
        {
            // Simple comparison to section name.
            if (memcmp((const char *) pSectionHdr->Name, g_szCORMETA, sizeof(pSectionHdr->Name)) == 0)
            {
                dwOffset = VAL32(pSectionHdr->PointerToRawData);
                dwSize = VAL32(pSectionHdr->SizeOfRawData);
                break;
            }
        }
    }
    
    if (dwOffset == 0 || dwSize == 0)
        goto BadFormat;
    
    // Check that raw data in the section is actually within the file.
    {
        S_UINT32 dwEndOffset = S_UINT32(dwOffset) + S_UINT32(dwSize);
        if ((dwOffset >= dwFileLength) || dwEndOffset.IsOverflow() || (dwEndOffset.Value() > dwFileLength))
            goto BadFormat;
    }

    *ppMetaData = (PVOID) ((ULONG_PTR) pImage + dwOffset);
    *pcbMetaData = dwSize;
    return (S_OK);
    
BadFormat:
    *ppMetaData = NULL;
    *pcbMetaData = 0;
    return (COR_E_BADIMAGEFORMAT);
}