void PeParser::alignAllSectionHeaders() { DWORD sectionAlignment = 0; DWORD fileAlignment = 0; DWORD newFileSize = 0; if (isPE32()) { sectionAlignment = pNTHeader32->OptionalHeader.SectionAlignment; fileAlignment = pNTHeader32->OptionalHeader.FileAlignment; } else { sectionAlignment = pNTHeader64->OptionalHeader.SectionAlignment; fileAlignment = pNTHeader64->OptionalHeader.FileAlignment; } std::sort(listPeSection.begin(), listPeSection.end(), PeFileSectionSortByPointerToRawData); //sort by PointerToRawData ascending newFileSize = pDosHeader->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + pNTHeader32->FileHeader.SizeOfOptionalHeader + (getNumberOfSections() * sizeof(IMAGE_SECTION_HEADER)); for (WORD i = 0; i < getNumberOfSections(); i++) { listPeSection[i].sectionHeader.VirtualAddress = alignValue(listPeSection[i].sectionHeader.VirtualAddress, sectionAlignment); listPeSection[i].sectionHeader.Misc.VirtualSize = alignValue(listPeSection[i].sectionHeader.Misc.VirtualSize, sectionAlignment); listPeSection[i].sectionHeader.PointerToRawData = alignValue(newFileSize, fileAlignment); listPeSection[i].sectionHeader.SizeOfRawData = alignValue(listPeSection[i].dataSize, fileAlignment); newFileSize = listPeSection[i].sectionHeader.PointerToRawData + listPeSection[i].sectionHeader.SizeOfRawData; } std::sort(listPeSection.begin(), listPeSection.end(), PeFileSectionSortByVirtualAddress); //sort by VirtualAddress ascending }
void PeParser::fixPeHeader() { DWORD dwSize = pDosHeader->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER); if (isPE32()) { //delete bound import directories pNTHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0; pNTHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0; //max 16, zeroing possible garbage values for (DWORD i = pNTHeader32->OptionalHeader.NumberOfRvaAndSizes; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) { pNTHeader32->OptionalHeader.DataDirectory[i].Size = 0; pNTHeader32->OptionalHeader.DataDirectory[i].VirtualAddress = 0; } pNTHeader32->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; pNTHeader32->FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER32); pNTHeader32->OptionalHeader.SizeOfImage = getSectionHeaderBasedSizeOfImage(); if (moduleBaseAddress) { pNTHeader32->OptionalHeader.ImageBase = (DWORD)moduleBaseAddress; } pNTHeader32->OptionalHeader.SizeOfHeaders = alignValue(dwSize + pNTHeader32->FileHeader.SizeOfOptionalHeader + (getNumberOfSections() * sizeof(IMAGE_SECTION_HEADER)), pNTHeader32->OptionalHeader.FileAlignment); } else { //delete bound import directories pNTHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0; pNTHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0; //max 16, zeroing possible garbage values for (DWORD i = pNTHeader64->OptionalHeader.NumberOfRvaAndSizes; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) { pNTHeader64->OptionalHeader.DataDirectory[i].Size = 0; pNTHeader64->OptionalHeader.DataDirectory[i].VirtualAddress = 0; } pNTHeader64->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; pNTHeader64->FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64); pNTHeader64->OptionalHeader.SizeOfImage = getSectionHeaderBasedSizeOfImage(); if (moduleBaseAddress) { pNTHeader64->OptionalHeader.ImageBase = moduleBaseAddress; } pNTHeader64->OptionalHeader.SizeOfHeaders = alignValue(dwSize + pNTHeader64->FileHeader.SizeOfOptionalHeader + (getNumberOfSections() * sizeof(IMAGE_SECTION_HEADER)), pNTHeader64->OptionalHeader.FileAlignment); } removeIatDirectory(); }
void lxMemoryList_init (lxMemoryListPTR self, lxMemoryAllocatorPTR allocator, uint numSizes, const uint* sizes, uint startsize, uint alignSize) { uint i,n; uint cnt = numSizes; memset(self,0,sizeof(lxMemoryList_t)); self->alignSize = alignSize; self->allocator = allocator; LUX_ASSERT(self->cnt <= MEMORY_LIST_MAXSLOTS); // correct sizs for alignment for (i = 0; i < numSizes; i++){ self->slots[i].size = alignValue(sizes[i],alignSize); } // remove double entries for (i = 1, n = 1; i < numSizes; i++,n++){ while (self->slots[i-1].size == self->slots[i].size && i < numSizes){ cnt--; i++; } if (i < numSizes){ self->slots[n].size = self->slots[i].size; } } self->cnt = cnt; lxMemoryList_addPage(self,startsize); }
static void lxMemoryList_addPage (lxMemoryListPTR self, uint size) { uint alignSize = self->alignSize; lxMemoryPage_t* oldchunk = (lxMemoryPage_t*)self->pagelist; lxMemoryPage_t* newchunk = (lxMemoryPage_t*)lxMemoryAllocator_malloc(self->allocator,size+sizeof(lxMemoryPage_t)+self->alignSize); LUX_DEBUGASSERT(newchunk); newchunk->next = oldchunk; newchunk->size = size; self->pagelist = newchunk; if (oldchunk){ // to prevent wasting old memory lets throw it in the first // largest fitting size (could use better heuristic here) uint chunksize = self->chunksize; uint chunkpos = self->chunkpos; int cnt = self->cnt; uint left = chunksize-chunkpos; int i; if (left){ for (i = cnt-1 ; i >= 0; i--){ lxMemorySizeSlot_t *cursl = &self->slots[i]; while (left >= cursl->size){ lxMemoryNode_t* block = (lxMemoryNode_t*)&self->chunk[chunkpos]; block->next = cursl->freelist; cursl->freelist = block; chunkpos += cursl->size; left -= cursl->size; } } } } self->chunk = (byte*)alignValue((size_t)(newchunk+1),self->alignSize); self->chunksize = size; self->chunkpos = 0; self->memAllocatedPages += size; }
GenericDataTypeStruct::GenericDataTypeStruct( GenericDataTypeCollection& collection, const string& name, GenericDataTypeMode mode, const GenericDataTypeStruct* pBaseType ) : GenericDataType( collection, name, mode ) , m_pBaseType( pBaseType ) { m_alignment = 0u; m_size = 0u; if ( m_pBaseType != nullptr ) { const List< GenericDataStructField >& fields = m_pBaseType->getFields(); for (uint i = 0u; i < fields.getCount(); ++i) { GenericDataStructField& field = m_fields.add(); field = fields[ i ]; field.isInherited = true; m_alignment = TIKI_MAX( m_alignment, field.pType->getAlignment() ); m_size = alignValue( m_size, field.pType->getAlignment() ); m_size = m_size + field.pType->getSize(); } } }
bool GenericDataTypeStruct::loadFromXml( const XmlReader& reader, const XmlElement* pTypeRoot ) { if ( pTypeRoot == nullptr ) { return false; } if ( !isStringEquals( pTypeRoot->name, "struct" ) ) { TIKI_TRACE_ERROR( "[GenericDataStruct(%s)::readFromXml] node has a wrong tag('%s' != 'struct') \n", getName().cStr(), pTypeRoot->name ); return false; } const XmlElement* pChildElement = pTypeRoot->elements; while ( pChildElement != nullptr ) { const bool isField = isStringEquals( pChildElement->name, "field" ); const bool isValue = isStringEquals( pChildElement->name, "value" ); if ( isField || isValue ) { const XmlAttribute* pNameAtt = reader.findAttributeByName( "name", pChildElement ); const XmlAttribute* pTypeAtt = reader.findAttributeByName( "type", pChildElement ); const XmlAttribute* pModeAtt = reader.findAttributeByName( "mode", pChildElement ); const XmlAttribute* pValueAtt = reader.findAttributeByName( "value", pChildElement ); if ( pNameAtt && pTypeAtt ) { const GenericDataType* pType = m_collection.parseType( pTypeAtt->content ); if ( pType == nullptr ) { TIKI_TRACE_WARNING( "[GenericDataStruct(%s)::readFromXml] Type(%s) for field with name '%s' can't be found.\n", getName().cStr(), pTypeAtt->content, pNameAtt->content ); return false; } GenericDataStructField* pValueField = nullptr; const string fieldName = pNameAtt->content; if ( isValue ) { for (uint i = 0u; i < m_fields.getCount(); ++i) { GenericDataStructField& field = m_fields[ i ]; if ( field.name == fieldName ) { pValueField = &field; break; } } if ( pValueField == nullptr ) { TIKI_TRACE_ERROR( "[GenericDataStruct(%s)::readFromXml] field with name '%s' can't found in base class.\n", getName().cStr(), pNameAtt->content ); return false; } } GenericDataStructField& field = (isValue ? *pValueField : m_fields.add()); if ( isField ) { field.name = fieldName; field.pType = pType; field.defaultValue = GenericDataValue( pType ); field.mode = GenericDataTypeMode_ToolAndRuntime; field.isInherited = false; m_alignment = TIKI_MAX( m_alignment, field.pType->getAlignment() ); m_size = alignValue( m_size, field.pType->getAlignment() ); m_size = m_size + field.pType->getSize(); } if ( isValue && field.pType != pType ) { TIKI_TRACE_ERROR( "[GenericDataStruct(%s)::readFromXml] field with name '%s' must have the same type like in base class.\n", getName().cStr(), pNameAtt->content ); return false; } if ( pModeAtt != nullptr ) { if ( !isValue ) { GenericDataTypeMode mode = m_collection.findModeByName( pModeAtt->content ); if ( mode == GenericDataTypeMode_Invalid ) { TIKI_TRACE_WARNING( "[GenericDataStruct(%s)::readFromXml] field with name '%s' has a invalid mode attribute. '%s' is not a valid mode.\n", getName().cStr(), pNameAtt->content, pModeAtt->content ); } else { field.mode = mode; } } else { TIKI_TRACE_WARNING( "[GenericDataStruct(%s)::readFromXml] can't override mode in value(%s).\n", getName().cStr(), pNameAtt->content ); } } if ( pValueAtt != nullptr ) { if ( !m_collection.parseValue( field.defaultValue, pValueAtt->content, pType, this ) ) { TIKI_TRACE_INFO( "[GenericDataStruct(%s)::readFromXml] default value of '%s' can't be parsed.\n", getName().cStr(), pNameAtt->content ); } } } else { TIKI_TRACE_ERROR( "[GenericDataStruct(%s)::readFromXml] field or array has not all required attributes. name and type are required.\n", getName().cStr() ); return false; } } pChildElement = pChildElement->next; } return true; }
bool PeParser::addNewLastSection(const CHAR * sectionName, DWORD sectionSize, BYTE * sectionData) { size_t nameLength = strlen(sectionName); DWORD fileAlignment = 0, sectionAlignment = 0; PeFileSection peFileSection; if (nameLength > IMAGE_SIZEOF_SHORT_NAME) { return false; } if (isPE32()) { fileAlignment = pNTHeader32->OptionalHeader.FileAlignment; sectionAlignment = pNTHeader32->OptionalHeader.SectionAlignment; //avoid PE relocation pNTHeader32->OptionalHeader.DllCharacteristics = 0x8100; } else { fileAlignment = pNTHeader64->OptionalHeader.FileAlignment; sectionAlignment = pNTHeader64->OptionalHeader.SectionAlignment; //avoid PE relocation pNTHeader64->OptionalHeader.DllCharacteristics = 0x8100; } memcpy_s(peFileSection.sectionHeader.Name, IMAGE_SIZEOF_SHORT_NAME, sectionName, nameLength); //last section doesn't need SizeOfRawData alignment peFileSection.sectionHeader.SizeOfRawData = sectionSize; //alignValue(sectionSize, fileAlignment); peFileSection.sectionHeader.Misc.VirtualSize = alignValue(sectionSize, sectionAlignment); peFileSection.sectionHeader.PointerToRawData = alignValue(getSectionHeaderBasedFileSize(), fileAlignment); peFileSection.sectionHeader.VirtualAddress = alignValue(getSectionHeaderBasedSizeOfImage(), sectionAlignment); peFileSection.sectionHeader.Characteristics = IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA; peFileSection.normalSize = peFileSection.sectionHeader.SizeOfRawData; peFileSection.dataSize = peFileSection.sectionHeader.SizeOfRawData; if (sectionData == 0) { peFileSection.data = new BYTE[peFileSection.sectionHeader.SizeOfRawData]; ZeroMemory(peFileSection.data , peFileSection.sectionHeader.SizeOfRawData); } else { peFileSection.data = sectionData; } for (WORD i = 0; i < getNumberOfSections(); i++) { listPeSection[i].sectionHeader.Characteristics = IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA; } listPeSection.push_back(peFileSection); setNumberOfSections(getNumberOfSections() + 1); return true; }
ReferenceKey ModelConverter::writeHierarchy( ResourceWriter& writer, const ToolModelHierarchy& hierarchy ) const { writer.openDataSection( 0u, AllocatorType_MainMemory ); const uint16 alignedJointCount = alignValue( (uint16)hierarchy.getJointCount(), (uint16)4u ); const ReferenceKey jointNamesKey = writer.addDataPoint(); for (uint j = 0u; j < hierarchy.getJointCount(); ++j) { writer.writeUInt32( hierarchy.getJointByIndex( j ).crc ); } const ReferenceKey parentIndicesKey = writer.addDataPoint(); for (uint j = 0u; j < hierarchy.getJointCount(); ++j) { writer.writeUInt16( uint16( hierarchy.getJointByIndex( j ).parentIndex ) ); } Array< Quaternion > dpRotation; Array< Vector3 > dpPosition; Array< Vector3 > dpScale; dpRotation.create( alignedJointCount ); dpPosition.create( alignedJointCount ); dpScale.create( alignedJointCount ); for (uint j = 0u; j < hierarchy.getJointCount(); ++j) { const ToolModelJoint& joint = hierarchy.getJointByIndex( j ); matrix::decompose( dpRotation[ j ], dpPosition[ j ], dpScale[ j ], joint.defaultPose ); } writer.writeAlignment( 16u ); const ReferenceKey defaultPoseKey = writer.addDataPoint(); for (uint j = 0u; j < alignedJointCount; ++j) { writer.writeFloat( dpRotation[ j ].x ); writer.writeFloat( dpRotation[ j ].y ); writer.writeFloat( dpRotation[ j ].z ); writer.writeFloat( dpRotation[ j ].w ); } for (uint j = 0u; j < alignedJointCount; ++j) { writer.writeFloat( dpPosition[ j ].x ); writer.writeFloat( dpPosition[ j ].y ); writer.writeFloat( dpPosition[ j ].z ); writer.writeFloat( 0.0f ); } for (uint j = 0u; j < alignedJointCount; ++j) { writer.writeFloat( dpScale[ j ].x ); writer.writeFloat( dpScale[ j ].y ); writer.writeFloat( dpScale[ j ].z ); writer.writeFloat( 0.0f ); } dpRotation.dispose(); dpPosition.dispose(); dpScale.dispose(); writer.writeAlignment( 16u ); const ReferenceKey skinToBoneKey = writer.addDataPoint(); for (uint i = 0u; i < hierarchy.getJointCount(); ++i) { const ToolModelJoint& joint = hierarchy.getJointByIndex( i ); writer.writeData( &joint.skinToBone.x.x, sizeof( Matrix44 ) ); } const ReferenceKey refKey = writer.addDataPoint(); writer.writeUInt16( uint16( hierarchy.getJointCount() ) ); writer.writeUInt16( alignedJointCount ); writer.writeReference( &jointNamesKey ); writer.writeReference( &parentIndicesKey ); writer.writeReference( &defaultPoseKey ); writer.writeReference( &skinToBoneKey ); writer.closeDataSection(); return refKey; }