//
//  PlugIn name: IDA to SoftIce converter (only for 32bit programs)
//
//  Version: 0.01 prerelease
//
//
//  This file contains function that sets all sections.
//
//
#include "i2s.h"


//--------------------------------------------------------------------------
//Set STTB section.
//
// return - Memory pointer to section or FAILED_.
//
unsigned long* SetSoftIce::SetSection_STTB(void)
{
	unsigned long	sectionLength;
	unsigned long	currentOffset;	//offset of DWORDs

	unsigned long	stringsSize;
	unsigned long*	sttbSection;

//get the size of needed buffer => get memory
		//offsetCurrent=size of used strings buffer
		//size of offset buffer=cStrings*4
	stringsSize=*(sttb.offsetsCurrent);
	sectionLength=*(sttb.offsetsCurrent);
	stringsSize+=4-(sectionLength%4);	//could be a problem but solved in reAlloc

	sectionLength=stringsSize+sttb.cStrings*4+sizeof(STTB_HEADER);

	if ( 0==(sttbSection=(unsigned long*)LocalAlloc(LPTR, sectionLength)) ) return(FAILED_);

//set header
	*sttbSection=STTBs;
	*(sttbSection+1)=sectionLength;
	*(sttbSection+2)=sttb.cStrings;
//copy subsections
	currentOffset=sizeof(STTB_HEADER)/4;
		//copy offsets
	currentOffset+=CopyDWORDMemory(sttbSection+currentOffset, sttb.offsets, sttb.cStrings);

		//copy strings
	CopyDWORDMemory(sttbSection+currentOffset, (unsigned long*)sttb.strings, stringsSize/4 );

//return
	return(sttbSection);
}

//--------------------------------------------------------------------------
//Set NMTP section.
//
// return - Memory pointer to section or FAILED_.
//
unsigned long* SetSoftIce::SetSection_NMTP(void)
{
	unsigned long	sectionLength;
	unsigned long	currentOffset;	//offset of DWORDs

	unsigned long*	typeData;
	unsigned long	typesDataLength;
	unsigned long*	nmtpSection;

//get the size of needed buffer => get memory
	//size=sizeof(NMTP_HEADER)+sizeofTypesData+sizeofOffsets;

		//sizeofTypesData = (lastOffset+sizeof(lastType))
	typesDataLength=nmtp.typesOffsets[nmtp.cTypesData-1];	//get the last offset

	typeData=(unsigned long*)(nmtp.typesData+typesDataLength);	//get the last dataType
	if ( *typeData==TYPE_LF_ARRAY )
	{
		typesDataLength+=sizeof(DATAS_LF_ARRAY);
	}

//	else if ( *typeData==TYPE_LF_LABEL )	//it can't happen, both are defined at the begining
//	{
//	}

//	else if ( *typeData==TYPE_LF_STRUCT )	//it can't happen
//	{
//	}
//	else if ( *typeData==TYPE_LF_UNION )
//	{
//	}
//	else if ( *typeData==TYPE_LF_DERIVED )	//if struct/union type is defined as last,
//	{										//then LF_MEMBER is the last one
//	}
	else if ( *typeData==TYPE_LF_MEMBER )
	{
		typesDataLength+=sizeof(DATAS_LF_MEMBER);
	}

	else if ( *typeData==TYPE_LF_PROCEDURE )			//if procedure type is defined as last,
	{													//then LF_ARGLIST is the last one
		typesDataLength+=sizeof(DATAS_LF_PROCEDURE);	//Not completely true. If no additional nm type
														//is defined than our 0x1002 procedure type is
														//the last one.
	}
	else if ( *typeData==TYPE_LF_ARGLIST )
	{
		typesDataLength+=(3+ *(typeData+2) )*4;	//(3+argCount)*4
	}
		//size of everything else
	sectionLength=sizeof(NMTP_HEADER)+nmtp.cTypesData*4+typesDataLength;	//header + offsets + typesDataLength

		//get buffer
	if ( 0==(nmtpSection=(unsigned long*)LocalAlloc(LPTR, sectionLength)) ) return(FAILED_);

//set header
	*nmtpSection=NMTPs;
	*(nmtpSection+1)=sectionLength;
	*(nmtpSection+2)=nmtp.cTypesData;
//copy subsections
	currentOffset=sizeof(NMTP_HEADER)/4;
		//copy offsets
	currentOffset+=CopyDWORDMemory(nmtpSection+currentOffset, nmtp.typesOffsets, nmtp.cTypesData);
		//copy typesData
	CopyDWORDMemory(nmtpSection+currentOffset, (unsigned long*)nmtp.typesData, typesDataLength/4 );

//return
	return(nmtpSection);
}

//--------------------------------------------------------------------------
//Set TYTB section.
//
// return - Memory pointer to section or FAILED_.
//
unsigned long* SetSoftIce::SetSection_TYTB(void)
{
	unsigned long	sectionLength;

	unsigned long*	tytbSection;

//get the size of needed buffer => get memory
	sectionLength=sizeof(TYTB_HEADER)+(tytb.cTypeTables)*sizeof(TYPETABLE);

	if ( 0==(tytbSection=(unsigned long*)LocalAlloc(LPTR, sectionLength)) ) return(FAILED_);

//set header
	*tytbSection=TYTBs;
	*(tytbSection+1)=sectionLength;
	*(tytbSection+2)=tytb.cTypeTables;
	*(tytbSection+3)=sizeof(TYTB_HEADER);		//in SetSection_NM32 we'll have to add offset to TYTB section
												//to make this variable right
//copy subsections
	CopyDWORDMemory(tytbSection+sizeof(TYTB_HEADER)/4, (unsigned long*)tytb.typeTables, tytb.cTypeTables*sizeof(TYPETABLE)/4);

//return
	return(tytbSection);
}

//--------------------------------------------------------------------------
//Set HSHT section.
//
// return - Memory pointer to section or FAILED_.
//
unsigned long* SetSoftIce::SetSection_HSHT(void)
{
	unsigned long	sectionLength;
	unsigned long	currentOffset;	//offset of DWORDs

	unsigned long*	hshtSection;

//get the size of needed buffer => get memory
	sectionLength=sizeof(HSHT_HEADER)+0x25*4+hsht.cHashTables*sizeof(HSHT_TYPETABLE);

	if ( 0==(hshtSection=(unsigned long*)LocalAlloc(LPTR, sectionLength)) ) return(FAILED_);

//set header
	*hshtSection=HSHTs;
	*(hshtSection+1)=sectionLength;
	*(hshtSection+2)=0x25;		//sizeTableOffsets
	*(hshtSection+3)=hsht.cHashTables;
	*(hshtSection+4)=sizeof(HSHT_HEADER);			//in SetSection_NM32 we'll have to add offset to HSHT section
	*(hshtSection+5)=sizeof(HSHT_HEADER)+0x25*4;	//in SetSection_NM32 we'll have to add offset to HSHT section

//copy subsections
	currentOffset=sizeof(HSHT_HEADER)/4;
		//copy offsets
	currentOffset+=CopyDWORDMemory(hshtSection+currentOffset, (unsigned long*)&hsht.hashOffsets, 0x25);
		//copy typesData
	CopyDWORDMemory(hshtSection+currentOffset, (unsigned long*)hsht.hashTables, hsht.cHashTables*sizeof(HSHT_TYPETABLE)/4 );

//return
	return(hshtSection);
}

//--------------------------------------------------------------------------
//Set SYMD section.
//
// return - Memory pointer to section or FAILED_.
//
unsigned long* SetSoftIce::SetSection_SYMD(void)
{
	unsigned long	sectionLength=0;
	unsigned long	currentOffset;		//in bytes

	char*			symdSection;
	SEGMENT_DATA*	currentSegment;
	unsigned long	dataOffset;			//in bytes
	SEGMENTDATA*	segmentData;

	unsigned long	i;
//get the size of needed buffer => get memory
	i=0;
	currentSegment=symd.segments;
	while( i<symd.cSegments )
	{
		sectionLength+=sizeof(SEGMENTDATA);		//SEGMENT HEADER
		sectionLength+=(currentSegment->cProcDefinitions)*sizeof(SEGDATA_PROCEDURE);	//number of procedures
		sectionLength+=(currentSegment->cLocalVariables)*sizeof(SEGDATA_VLPTABLE);	//number of localVariables
		sectionLength+=(currentSegment->cSourceLines)*sizeof(SEGDATA_SOURCELINES);	//number of sourceLines
		sectionLength+=(currentSegment->cVLP)*sizeof(SEGDATA_VLPTABLE);		//number VLP
		sectionLength+=(currentSegment->cVLP)*4;	//VLP offsets
		//update
		currentSegment=currentSegment->pNext;
		++i;
	}
		//odd number of segments
			//between SegmentData and VariablesData we'll add 2 zero bytes for DWORD boundary
	if ( 0!=((symd.cSegments)&(0x1)) ) sectionLength+=2;
		//source
	sectionLength+=cSourceFiles*(sizeof(SEGDATA_SOURCESECTION)+sizeof(SEGDATA_SOURCEFILE));
		//SYMD HEADERS
	sectionLength+=sizeof(SYMD_HEADER)+sizeof(SEGMENTDATA_HEADER);
		//dword boundary (of whole buffer)
	sectionLength+=4-(sectionLength%4);

	if ( 0==(symdSection=(char*)LocalAlloc(LPTR, sectionLength)) ) return(FAILED_);

//set header
	*(unsigned long*)symdSection=SYMDs;
	*(unsigned long*)(symdSection+1*4)=sectionLength;
	*(unsigned long*)(symdSection+2*4)=sizeof(SYMD_HEADER);		//we'll have to update thi number SetSection_NM32

	currentOffset=sizeof(SYMD_HEADER);
//set segmentdata header
	*(unsigned long*)(symdSection+currentOffset)=sectionLength-sizeof(SYMD_HEADER);
	*(unsigned long*)(symdSection+currentOffset+1*4)=cSourceFiles;
	*(unsigned long*)(symdSection+currentOffset+2*4)=symd.cSegments;

	currentOffset+=sizeof(SEGMENTDATA_HEADER);	//to 1st segmentData table
//set segmentData tables
	i=0;
		//pointer to SEGMENT_DATA
	currentSegment=symd.segments;
		//offset to free space (VariableData(segX) read in nm32.h)
	dataOffset=(symd.cSegments)*sizeof(SEGMENTDATA);	//points to SEGMENT DATA section in SYMD
	if ( 0!=((symd.cSegments)&(0x1)) ) dataOffset+=2;
		//pointer to SEGMENTDATA
	segmentData=(SEGMENTDATA*)(symdSection+currentOffset);

	while( i<symd.cSegments )
	{
		auto unsigned long	cProcDefinitions;
		auto unsigned long	cVLP;
		auto unsigned long	lengthTemp;

		segmentData->nSeg=(unsigned short)currentSegment->nSeg;	//nSeg
		segmentData->iNameSegment=currentSegment->iNameSegment;	//iName
		segmentData->physSize=currentSegment->physSize;			//physSize

		cProcDefinitions=currentSegment->cProcDefinitions;
		if ( 0!=cProcDefinitions )
		{
			//PROCEDURE
				//procedure
			segmentData->offProcDef=dataOffset;				//offProcDef
			segmentData->cProcedures=cProcDefinitions;		//cProcedures
			lengthTemp=cProcDefinitions*sizeof(SEGDATA_PROCEDURE);
			CopyMemory( (symdSection+currentOffset)+dataOffset, (currentSegment->procDefinitions), lengthTemp );
			            //offset segmentData       + offset variableData
			dataOffset+=lengthTemp;

				//local variables
					//if cLocalvariables==0 than nothing is changed/copied
			segmentData->offLVarDef=dataOffset;
			lengthTemp=(currentSegment->cLocalVariables)*sizeof(SEGDATA_VLPTABLE);
			CopyMemory( (symdSection+currentOffset)+dataOffset, (currentSegment->localVariables), lengthTemp );
			dataOffset+=lengthTemp;
	
				//source lines
			segmentData->offSCLineDef=dataOffset;
			segmentData->offSCLineDef2=dataOffset;	//read in nm32.h about this one
			lengthTemp=(currentSegment->cSourceLines)*sizeof(SEGDATA_SOURCELINES);
			CopyMemory( (symdSection+currentOffset)+dataOffset, (currentSegment->sourceLines), lengthTemp );
			dataOffset+=lengthTemp;

			//SOURCE SECTIONS
			segmentData->offSourceSDef=dataOffset;
			segmentData->cSourceSec=1;
			CopyMemory( (symdSection+currentOffset)+dataOffset, &(currentSegment->sourceSection), sizeof(SEGDATA_SOURCESECTION) );
			dataOffset+=sizeof(SEGDATA_SOURCESECTION);
		}
		else
		{
			//PROCEDURE
				//procedure
			segmentData->offProcDef=dataOffset;
			segmentData->cProcedures=0;
				//local variables
			segmentData->offLVarDef=dataOffset;
				//source lines
			segmentData->offSCLineDef=dataOffset;
			segmentData->offSCLineDef2=dataOffset;	//read in nm32.h about this one

			//SOURCE SECTIONS
			segmentData->offSourceSDef=dataOffset;
			segmentData->cSourceSec=0;
		}

		cVLP=currentSegment->cVLP;
		if ( 0!=cVLP )
		{
			//VLP
				//table
			segmentData->offVLPDef=dataOffset;
			segmentData->cVLP=cVLP;
			lengthTemp=cVLP*sizeof(SEGDATA_VLPTABLE);
			CopyMemory( (symdSection+currentOffset)+dataOffset, (currentSegment->VLP), lengthTemp );
			dataOffset+=lengthTemp;

				//offsets
			segmentData->offVLPOffsets=dataOffset;
			lengthTemp=cVLP*4;
			CopyMemory( (symdSection+currentOffset)+dataOffset, (unsigned long*)(currentSegment->VLPOffsets), lengthTemp );
			dataOffset+=lengthTemp;
		}
		else
		{
			//VLP
				//table
			segmentData->offVLPDef=dataOffset;
			segmentData->cVLP=0;
				//offsets
			segmentData->offVLPOffsets=dataOffset;
		}

	//update
		currentSegment=currentSegment->pNext;
			//offset from next segment to free space  (VariableData(segX) read in nm32.h)
		dataOffset-=sizeof(SEGMENTDATA);
	
		currentOffset+=sizeof(SEGMENTDATA);
		segmentData=(SEGMENTDATA*)(symdSection+currentOffset);

		++i;
	}
	
	//symdSection+currentOffset=end of segmentData(start of variablesData)
	//(symdSection+currentOffset+dataOffset)=end of variablesData(start of sourceFilesDef.)
	currentOffset+=dataOffset;
	CopyMemory( symdSection+currentOffset, &(symd.segments->sourceFile), sizeof(SEGDATA_SOURCEFILE) );


//return
	return((unsigned long*)symdSection);
	
}

//--------------------------------------------------------------------------
//Set whole file.
//
// return -  Memory pointer to mappedFile or FAILED_.
//
unsigned long* SetSoftIce::SetSection_NM32(unsigned long flags)
{
	unsigned long*	nm32;
	unsigned long	currentOffset;		//offset in bytes
	unsigned long	currentOffsetDWORD;	//offset in DWORDs

	unsigned long	nm32Size;
	unsigned long	nmtpSize;
	unsigned long	sttbSize;
	unsigned long	tytbSize;
	unsigned long	hshtSize;
	unsigned long	symdSize;
	unsigned long	fpodSize;
	unsigned long	srcpSize;
	unsigned long	gtypSize;

	unsigned long	nmtpOffset;
	unsigned long	sttbOffset;
	unsigned long	tytbOffset;
	unsigned long	hshtOffset;
	unsigned long	symdOffset;
	unsigned long	fpodOffset;
	unsigned long	srcpOffset;
	unsigned long	gtypOffset;
	unsigned long	nmdrOffset;


//*********************************************************
//get the size of needed buffer => get memory
	nmtpSize=*(sections.nmtp+1);
	sttbSize=*(sections.sttb+1);
	if ( 0!=*(sections.tytb+2))	//do we have any types
	{
		tytbSize=*(sections.tytb+1);
		hshtSize=*(sections.hsht+1);
	}
	else
	{
		tytbSize=0;
		hshtSize=0;
	}
	symdSize=*(sections.symd+1);
//	fpodSize=*(sections.fpod+1);
	fpodSize=sizeof(FPOD_HEADER);
//	srcpSize=*(sections.srcp+1);
	srcpSize=sizeof(SRCP_HEADER);
//	gtypSize=*(sections.gtyp+1);	
	gtypSize=sizeof(GTYP_HEADER);

	
	nm32Size=sizeof(NM32_HEADER)+nmtpSize+sttbSize+tytbSize+hshtSize+symdSize+fpodSize+srcpSize+gtypSize+sizeof(NMDR_HEADER)+sizeof(NMDE_S)*8+4;
	if ( 0==(nm32=(unsigned long*)LocalAlloc(LPTR, nm32Size)) ) return(FAILED_);

//*********************************************************
//copy subsections
	currentOffset=sizeof(NM32_HEADER);
		//nmtp
//	nmtpOffset=currentOffset;
	nmtpOffset=sizeof(NM32_HEADER);				//always
	*(sections.gtyp+2)=sizeof(NM32_HEADER);		//set gtyp header
	CopyMemory( ((char*)nm32+currentOffset), sections.nmtp, nmtpSize );
	currentOffset+=nmtpSize;

		//sttb
	sttbOffset=currentOffset;
	*(sections.gtyp+3)=currentOffset;	//set gtyp header
	CopyMemory( ((char*)nm32+currentOffset), sections.sttb, sttbSize );
	currentOffset+=sttbSize;
		//tytb
	if ( 0!=tytbSize )
	{
		tytbOffset=currentOffset;
		*(sections.tytb+3)+=currentOffset;	//in SetSection_NM32 we'll have to add offset to TYTB section
											//to make this variable right
		*(sections.gtyp+4)=currentOffset;	//set gtyp header
		CopyMemory( ((char*)nm32+currentOffset), sections.tytb, tytbSize );
		currentOffset+=tytbSize;
		//hsht
		hshtOffset=currentOffset;
		*(sections.hsht+4)+=currentOffset;	//in SetSection_NM32 we'll have to add offset to HSHT section
		*(sections.hsht+5)+=currentOffset;	//in SetSection_NM32 we'll have to add offset to HSHT section
		*(sections.gtyp+5)=currentOffset;	//set gtyp header
		CopyMemory( ((char*)nm32+currentOffset), sections.hsht, hshtSize );
		currentOffset+=hshtSize;
	}
		//symd
	symdOffset=currentOffset;
	*(sections.symd+2)+=currentOffset;		//offSegmentData_header
	CopyMemory( ((char*)nm32+currentOffset), sections.symd, symdSize );
	currentOffset+=symdSize;
		//fpod
	fpodOffset=currentOffset;
	CopyMemory( ((char*)nm32+currentOffset), sections.fpod, fpodSize );
	currentOffset+=fpodSize;
		//srcp
	srcpOffset=currentOffset;
	CopyMemory( ((char*)nm32+currentOffset), sections.srcp, srcpSize );
	currentOffset+=srcpSize;
		//gtyp
	gtypOffset=currentOffset;
	CopyMemory( ((char*)nm32+currentOffset), sections.gtyp, gtypSize );
	currentOffset+=gtypSize;

//*********************************************************
//set nmdr
		//header
	nmdrOffset=currentOffset;
	currentOffsetDWORD=currentOffset/4;

	*(nm32+currentOffsetDWORD)=NMDRs;
	if ( 0!=tytbSize)
	{
		*(nm32+currentOffsetDWORD+1)=8;				//cNMDE
	}
	else
	{
		*(nm32+currentOffsetDWORD+1)=6;				//cNMDE
	}
	*(nm32+currentOffsetDWORD+2)=gtypOffset;		//offGTYP
	*(nm32+currentOffsetDWORD+3)=sttbOffset;		//offSTTB
	*(nm32+currentOffsetDWORD+4)=symdOffset;		//offSYMD
	*(nm32+currentOffsetDWORD+5)=srcpOffset;		//offSRCP
	*(nm32+currentOffsetDWORD+6)=fpodOffset;		//offFPOD
	currentOffsetDWORD+=sizeof(NMDR_HEADER)/4;
	//nmde
		//nmtp
	*(nm32+currentOffsetDWORD)=NMDEs;			//NMDE
	*(nm32+currentOffsetDWORD+1)=INDEX_NMTP;		//entryIndex
	*(nm32+currentOffsetDWORD+2)=nmtpOffset;		//offsetEntry
	*(nm32+currentOffsetDWORD+3)=nmtpSize;		//entryLength
	currentOffsetDWORD+=sizeof(NMDE_S)/4;
		//sttb
	*(nm32+currentOffsetDWORD)=NMDEs;			//NMDE
	*(nm32+currentOffsetDWORD+1)=INDEX_STTB;		//entryIndex
	*(nm32+currentOffsetDWORD+2)=sttbOffset;		//offsetEntry
	*(nm32+currentOffsetDWORD+3)=sttbSize;		//entryLength
	currentOffsetDWORD+=sizeof(NMDE_S)/4;
		//tytb
	if ( 0!=tytbSize )
	{
		*(nm32+currentOffsetDWORD)=NMDEs;			//NMDE
		*(nm32+currentOffsetDWORD+1)=INDEX_TYTB;		//entryIndex
		*(nm32+currentOffsetDWORD+2)=tytbOffset;		//offsetEntry
		*(nm32+currentOffsetDWORD+3)=tytbSize;		//entryLength
		currentOffsetDWORD+=sizeof(NMDE_S)/4;
		//hsht
		*(nm32+currentOffsetDWORD)=NMDEs;			//NMDE
		*(nm32+currentOffsetDWORD+1)=INDEX_HSHT;		//entryIndex
		*(nm32+currentOffsetDWORD+2)=hshtOffset;		//offsetEntry
		*(nm32+currentOffsetDWORD+3)=hshtSize;		//entryLength
		currentOffsetDWORD+=sizeof(NMDE_S)/4;
	}
		//symd
	*(nm32+currentOffsetDWORD)=NMDEs;			//NMDE
	*(nm32+currentOffsetDWORD+1)=INDEX_SYMD;		//entryIndex
	*(nm32+currentOffsetDWORD+2)=symdOffset;		//offsetEntry
	*(nm32+currentOffsetDWORD+3)=symdSize;		//entryLength
	currentOffsetDWORD+=sizeof(NMDE_S)/4;
		//fpod
	*(nm32+currentOffsetDWORD)=NMDEs;			//NMDE
	*(nm32+currentOffsetDWORD+1)=INDEX_FPOD;		//entryIndex
	*(nm32+currentOffsetDWORD+2)=fpodOffset;		//offsetEntry
	*(nm32+currentOffsetDWORD+3)=fpodSize;		//entryLength
	currentOffsetDWORD+=sizeof(NMDE_S)/4;
		//srcp
	*(nm32+currentOffsetDWORD)=NMDEs;			//NMDE
	*(nm32+currentOffsetDWORD+1)=INDEX_SRCP;		//entryIndex
	*(nm32+currentOffsetDWORD+2)=srcpOffset;		//offsetEntry
	*(nm32+currentOffsetDWORD+3)=srcpSize;		//entryLength
	currentOffsetDWORD+=sizeof(NMDE_S)/4;
		//gtyp
	*(nm32+currentOffsetDWORD)=NMDEs;			//NMDE
	*(nm32+currentOffsetDWORD+1)=INDEX_GTYP;		//entryIndex
	*(nm32+currentOffsetDWORD+2)=gtypOffset;		//offsetEntry
	*(nm32+currentOffsetDWORD+3)=gtypSize;		//entryLength
	currentOffsetDWORD+=sizeof(NMDE_S)/4;

//*********************************************************
//NRDS
	*(nm32+currentOffsetDWORD)=NRDSs;
	++currentOffsetDWORD;
	currentOffset=currentOffsetDWORD*4;

//*********************************************************
//set nm32 header
	*nm32=NM32s;
	*(nm32+1)=0x10;
	*(nm32+2)=0x1;
	*(nm32+3)=nmdrOffset;		//offNMDR
	*(nm32+4)=time(NULL);		//creationTime
	*(nm32+5)=flags;			//creationNumber
	auto unsigned long	fileType;
	if ( inf.filetype==f_PE )
	{
		if ( 0!=strstr(get_root_filename(), ".exe") ) fileType=FT_PEEXE;	//PE exe
		else fileType=FT_PEDLL;											//PE dll
	}
//	if ( inf.filetype==f_WIN ) fileType=FT_NE;		//NE (OS2, WIN32)
//	if ( inf.filetype==f_LE ) fileType=FT_LEVXD;	//LE (VXD)
//	if ( inf.filetype==f_LX ) fileType=FT_LX;		//LX (VXD)
//	if ( inf.filetype==f_EXE )fileType=0;			//MS-DOS
	*(nm32+6)=fileType;			//fileType
	*(nm32+7)=currentOffset;	//NMSFilelength

	strcpy( ((char*)nm32+0x40), get_input_file_path() );	//filePath
	strcpy( ((char*)nm32+0x144), copyright);				//copyrightString

//return
	return(nm32);
}


