Exemple #1
0
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
}
Exemple #2
0
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();
}
Exemple #3
0
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);
}
Exemple #4
0
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;
	}
Exemple #7
0
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;
}
Exemple #8
0
	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;
	}