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)); }
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()
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; }
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); }
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; }
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, ¶m) { 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; }
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; } } }
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; } }
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)); }
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 {
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; } }
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; }
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; }
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; }
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; }
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
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); }