⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cryptstuff.cpp

📁 I think this the first time every one can look at a PE crypter source in top level language such VC
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	//_GetModuleHandle			DD 0
	dwRO = dwRO - 4;
	dwRO_GetModuleHandle=dwRO;
	CopyMemory(Base+dwRO,&_GetModuleHandle,4);

	//szGetModuleHandle			DB "GetModuleHandleA",0
	l=DWORD(strlen(szGetModuleHandle))+1;
	dwRO = dwRO - l;
	dwRO_szGetModuleHandle=dwRO;
	CopyMemory(Base+dwRO,szGetModuleHandle,l);

	//dwKernelBase				DD 0
	dwRO = dwRO - 4;
	dwRO_dwKernelBase=dwRO;
	CopyMemory(Base+dwRO,&dwKernelBase ,4);

	//szKernel32				DB "Kernel32.dll",0
	l=DWORD(strlen(szKernel32))+1;
	dwRO = dwRO - l;
	dwRO_szKernel32=dwRO;
	CopyMemory(Base+dwRO,szKernel32,l);

	//_GetProcAddress			DD 0
	dwRO = dwRO - 4;
	dwRO_GetProcAddress	= dwRO;
	CopyMemory(Base+dwRO,&_GetProcAddress,4);
	
	//_LoadLibrary				DD 0
	dwRO = dwRO - 4;
	dwRO_LoadLibrary		= dwRO;
	CopyMemory(Base+dwRO,&_LoadLibrary,4);
	
	//SEH						sSEH <0>
	dwRO = dwRO - sizeof(sSEH);
	dwRO_SEH			= dwRO;
	CopyMemory(Base+dwRO,&SEH,sizeof(sSEH));

	//IIDInfo  db (SIZEOF sItInfo * MAX_IID_NUM) dup (0)
	l=sizeof(IIDInfo);
	dwRO = dwRO - sizeof(IIDInfo);
	dwRO_IIDInfo			= dwRO;
	CopyMemory(Base+dwRO,&IIDInfo,sizeof(IIDInfo));

	//bNT						DD 0
	dwRO = dwRO - 4;
	dwRO_bNT				= dwRO;
	CopyMemory(Base+dwRO,&bNT,4);

	//dwLoaderCRC				DD 0
	dwRO = dwRO - 4;
	dwRO_dwLoaderCRC		= dwRO;
	CopyMemory(Base+dwRO,&dwLoaderCRC,4);

	//dwCalcedCRC				DD 0
	dwRO = dwRO - 4;
	dwRO_dwCalcedCRC		= dwRO;
	CopyMemory(Base+dwRO,&dwCalcedCRC,4);

	//PROTECTION_FLAGS			DD 0
	dwRO = dwRO - 4;
	dwRO_PROTECTION_FLAGS	= dwRO;
	CopyMemory(Base+dwRO,&PROTECTION_FLAGS,4);

	//dwOrgEntryPoint			DD 0
	dwRO = dwRO - 4;
	dwRO_dwOrgEntryPoint	= dwRO;
	CopyMemory(Base+dwRO,&dwOrgEntryPoint,4);

	//dwImageBase				DD 0
	dwRO = dwRO - 4;
	dwRO_dwImageBase		= dwRO;
	CopyMemory(Base+dwRO,&dwImageBase,4);
}
//----------------------------------------------------------------
//return Raw Data address of Loader Crypter Codes
void GetLoaderCryptRO(char* pFuncBody)
{
	DWORD l=0;
	DWORD tmp;
	unsigned char _temp;
#ifdef _DEBUG
	do
	{
		CopyMemory(&tmp,pFuncBody+l,4);
		l++;
	}while(tmp!=0xCCCCCCCC);
	l=l+3;
#endif
	do
	{
		CopyMemory(&tmp,pFuncBody+l,4);
		l++;
	}while(tmp!=0xCCCCCCCC);
	tmp=0xC201EB90;
	CopyMemory(pFuncBody+l-1,&tmp,4);
	l=l+3;
	do
	{
		CopyMemory(&_temp,pFuncBody+l,1);
		l++;
	}while((_temp!=0xAC));
	dwRO_VAR_DECRYPTION=l;
	l=l+3;
	do
	{
		CopyMemory(&tmp,pFuncBody+l,4);
		l++;
	}while(tmp!=0xCCCCCCCC);
	tmp=0xE901EB90;
	CopyMemory(pFuncBody+l-1,&tmp,4);
	l=l+3;
	do
	{
		CopyMemory(&_temp,pFuncBody+l,1);
		l++;
	}while((_temp!=0xAC));
	dwRO_SEC_DECRYPT=l;
}
//----------------------------------------------------------------
//return Raw Data address of OEP JUMP Codes
void GetOepJumpCodeRO(char* pFuncBody)
{
	DWORD l=DEPACKER_CODE_SIZE-2;
	DWORD tmp;
	do
	{
		l--;
	}while(UCHAR(pFuncBody[l])==0xCC);
	l=l-4;
	do
	{
		CopyMemory(&tmp,pFuncBody+l,4);
		l--;
	}while(tmp!=0xCCCCCCCC);
	tmp=0xC201EB90;
	CopyMemory(pFuncBody+l+1,&tmp,4);
	dwRO_OEP_JUMP_CODE_END=l;
	l=l-4;
	do
	{
		l--;
		CopyMemory(&tmp,pFuncBody+l,4);
	}while(tmp!=0xCCCCCCCC);
	tmp=0xE901EB90;
	CopyMemory(pFuncBody+l,&tmp,4);
	l=l+4;
	dwRO_OEP_JUMP_CODE_START=l;
	OEP_JUMP_CODE_SIZE=dwRO_OEP_JUMP_CODE_END-dwRO_OEP_JUMP_CODE_START;
}
//----------------------------------------------------------------
// This functin encryptes the OEP JUMP Codes
void OepJumpEncrypt(char* Base)
{
	DWORD i;
	UCHAR _temp=0;
	UCHAR _tempC=UCHAR(OEP_JUMP_CODE_SIZE);
	for(i=dwRO_OEP_JUMP_CODE_START;i<=dwRO_OEP_JUMP_CODE_END;i++)
	{
		CopyMemory(&_temp,Base+i,1);
		_asm
		{
			MOV AL,_temp
   			ROR  AL, 2
   			ADD  AL, _tempC
   			XOR  AL, OEP_JUMP_ENCRYPT_NUM	
			MOV _temp,AL
			DEC _tempC
		}
		CopyMemory(Base+i,&_temp,1);
	}
}
//----------------------------------------------------------------
// returns aligned value
DWORD PEAlign(DWORD dwTarNum,DWORD dwAlignTo)
{	
	DWORD dwtemp;
	dwtemp=dwTarNum/dwAlignTo;
	if((dwTarNum%dwAlignTo)!=0)
	{
		dwtemp++;
	}
	dwtemp=dwtemp*dwAlignTo;
	return(dwtemp);
}
//----------------------------------------------------------------
// return Check Sum of buffer
//CYCLIC REDUNDANCY CHECKS (CRC)
DWORD GetChecksum(char* Base,DWORD FileSize)
{
	DWORD	checksum,dwhold,dwdata;
	DWORD64 dwtemp64;
	UCHAR	_temp;
	checksum=dwhold=0;
	for(DWORD i=0;i<FileSize;i++)
	{
		CopyMemory(&_temp,Base+i,1);
		dwtemp64=_temp*dwhold;
		dwdata=DWORD(dwtemp64);
		dwtemp64=dwtemp64>>32;
		dwhold=DWORD(dwtemp64);
		checksum=checksum+dwdata;
		dwhold++;
	}
	return(checksum);
}
//----------------------------------------------------------------
// This function reads the dll name strings, turn it back.
// and destroys them.
// return values:
//	char* - the dll name strings
char* ReadStringFrom(char* Base,DWORD dwRVA)
{
	int l=0;
	for(int i=0;i<255;i++)
	{
		if(Base[dwRVA+i]==0x00) break;
		l++;
	}
	char *filename=new TCHAR[l+1];
	strncpy(filename,Base+dwRVA,l+1);
	return(filename);
}
//----------------------------------------------------------------
// This function encrypts the dll name strings, saves the ImageImportDescriptors to the loader data 
// and destroys them.
// return values:
// 1 - success
// 0 - too much IID's !
DWORD EnDeCryptString(char* Base,DWORD dwRO)
{
	UCHAR _temp;
	for(int i=0;i<255;i++)//DllCryptLoop
	{
		CopyMemory(&_temp,Base+dwRO+i,1);
		__asm ROR _temp,4;
		CopyMemory(Base+dwRO+i,&_temp,1);
		if(_temp==0x00) break;
	}
	if(i>223) return(0);
	return(1);
}
//----------------------------------------------------------------
// This function encrypts the dll name strings, saves the ImageImportDescriptors to the loader data 
// and destroys them.
// return values:
// 1 - success
// 0 - too much IID's !
DWORD ProcessOrgIT(char* pFileImage,DWORD pITBaseRO)
{
	DWORD stupid_num;
	DWORD dwIIDNum;
	char *dllname,*dllfunc;
	for(int i=0;i<MAX_IID_NUM;i++)// clear the IIDInfo array
	{
		IIDInfo[i].DllNameRVA=0;
		IIDInfo[i].FirstThunk=0;
		IIDInfo[i].OrgFirstThunk=0;
	}
	stupid_num=GetTickCount();// get a random number
	stupid_num=stupid_num ^ 'yoda';// EDX -> stupid number :)
	// start
	IMAGE_IMPORT_DESCRIPTOR import_descriptor;// -> IID
	dwIIDNum=0;
	CopyMemory(&import_descriptor,
			   pFileImage+pITBaseRO+dwIIDNum*sizeof(IMAGE_IMPORT_DESCRIPTOR),
			   sizeof(IMAGE_IMPORT_DESCRIPTOR));
	while(import_descriptor.Name)
	{
	   	dwIIDNum++;
		if(dwIIDNum == (MAX_IID_NUM))// too much IID's ?
		{
			return 0;
		}	   
		// save IID Infos -> Loader IT data array
		IIDInfo[dwIIDNum-1].DllNameRVA=import_descriptor.Name;
		IIDInfo[dwIIDNum-1].OrgFirstThunk=import_descriptor.OriginalFirstThunk;
		IIDInfo[dwIIDNum-1].FirstThunk=import_descriptor.FirstThunk;
		//-> get dll pointer
		DWORD dllpoint=RVA2Offset(pFileImage,import_descriptor.Name);
		dllname=ReadStringFrom(pFileImage,dllpoint);
		EnDeCryptString(pFileImage,dllpoint);//-> crypt string
		dllname=ReadStringFrom(pFileImage,dllpoint);	   
		//--- CRYPT API name strings ---
  		DWORD dllfileRef=import_descriptor.OriginalFirstThunk;
  		if(!dllfileRef)
		{
			dllfileRef=import_descriptor.FirstThunk;
		}
		dllfileRef=RVA2Offset(pFileImage,dllfileRef);
		DWORD _dllfileRef=dllfileRef;
		DWORD dllfilePoint;
		CopyMemory(&dllfilePoint,pFileImage+_dllfileRef,4);
  		while( dllfilePoint!=0)// ESI -> Thunk pointer
		{			
			if((_dllfileRef&IMAGE_ORDINAL_FLAG32)==0)// is it an Ordinal Import ?
			{
				dllfilePoint=RVA2Offset(pFileImage,dllfilePoint);
  				if(dllfilePoint!=0)
				{
					dllfunc=ReadStringFrom(pFileImage,dllfilePoint+2);
					EnDeCryptString(pFileImage,dllfilePoint+2);//-> crypt string; skip the HINT
					dllfunc=ReadStringFrom(pFileImage,dllfilePoint+2);
				}
			}	      
			_dllfileRef=_dllfileRef+4;
			CopyMemory(&dllfilePoint,pFileImage+_dllfileRef,4);
		}		
  		// destroy Original IID*/
		import_descriptor.Name=stupid_num;
		import_descriptor.OriginalFirstThunk=stupid_num;
		import_descriptor.FirstThunk=stupid_num;
		import_descriptor.TimeDateStamp=stupid_num;
		import_descriptor.ForwarderChain=stupid_num;
		CopyMemory(pFileImage+pITBaseRO+(dwIIDNum-1)*sizeof(IMAGE_IMPORT_DESCRIPTOR),
				   &import_descriptor,
			       sizeof(IMAGE_IMPORT_DESCRIPTOR));
		CopyMemory(&import_descriptor,
			       pFileImage+pITBaseRO+dwIIDNum*sizeof(IMAGE_IMPORT_DESCRIPTOR),
			       sizeof(IMAGE_IMPORT_DESCRIPTOR));//-> point to next IID
	}
	return 1;
}
//----------------------------------------------------------------
// This function assembles Import Table for new section
void AssembleIT(char* Base,DWORD dwNewSectionRO,DWORD dwNewSectionRVA)
{
	char* pAddress4IT=Base+dwNewSectionRO;//-> base of the new IT		
	// Zero the memory for the new IT
	FillMemory(Base+dwNewSectionRO,IT_SIZE,0x00);
	// build a new,nice ImportTable :)
	IMAGE_IMPORT_DESCRIPTOR import_descriptor;//assume esi:ptr IMAGE_IMPORT_DESCRIPTOR
	CopyMemory(&import_descriptor,
			   pAddress4IT,
			   sizeof(IMAGE_IMPORT_DESCRIPTOR));
	// make ebx point after the terminating IID	
	DWORD dwRO=dwNewSectionRO+2*sizeof(IMAGE_IMPORT_DESCRIPTOR);
	import_descriptor.Name=dwNewSectionRVA+2*sizeof(IMAGE_IMPORT_DESCRIPTOR);// process the IID Name
	CopyMemory(Base+dwRO
			  ,szKernel,strlen(szKernel));
	dwRO=dwRO+strlen(szKernel)+1;
	// process the FirstThunk pointers
    import_descriptor.FirstThunk=dwRO-dwNewSectionRO+dwNewSectionRVA;
	DWORD dwRO_,dwRO1;
	dwRO1=dwRO+10;
	dwRO_=dwRO1-dwNewSectionRO+dwNewSectionRVA;
	CopyMemory(Base+dwRO,&dwRO_,4);
	dwRO1=dwRO1+2;

	CopyMemory(Base+dwRO1
		      ,szLoadLibrary,strlen(szLoadLibrary));
	dwRO1=dwRO1+strlen(szLoadLibrary);
	dwRO=dwRO+4;
	dwRO_=dwRO1-dwNewSectionRO+dwNewSectionRVA;
	CopyMemory(Base+dwRO,&dwRO_,4);
	dwRO1=dwRO1+2;
	CopyMemory(Base+dwRO1
			  ,szGetProcAddress,strlen(szGetProcAddress));
	CopyMemory(Base+dwNewSectionRO,
			   &import_descriptor,
			   sizeof(IMAGE_IMPORT_DESCRIPTOR));
}
//----------------------------------------------------------------
// This function relocates the Thread Local Storage (TLS) Table
// in different place
void ProcessTlsTable(char* Base,DWORD dwCryptSectionRVA)
{
	DWORD TlsDirAddr;
	// check whether there's a tls table
	IMAGE_NT_HEADERS nt_headers;
	DWORD dwPE_Offset;
	CopyMemory(&dwPE_Offset,Base+0x3c,4);//-> pointer to PE header
	CopyMemory(&nt_headers,Base+dwPE_Offset,sizeof(IMAGE_NT_HEADERS));

	TlsDirAddr=nt_headers.OptionalHeader.DataDirectory[9].VirtualAddress;
	DWORD dwRO;
	if(TlsDirAddr!=0)// check if no tls section
	{
		// get a RAW pointer to the tls table
		dwRO=RVA2Offset(Base,TlsDirAddr);//-> pointer to tls tables
		if(dwRO!=0)
		{
			dwRO_TlsBackup =DEPACKER_CODE_SIZE-(9+sizeof(IMAGE_TLS_DIRECTORY32));;
			// copy the whole TLS table into the loader data part
			CopyMemory(&TlsBackup,Base+dwRO,sizeof(IMAGE_TLS_DIRECTORY32));			
			// fix the TLS DIRECTORY VA
			DWORD dwTLS_D_VA=dwCryptSectionRVA+IT_SIZE+dwRO_TlsBackup;
			nt_headers.OptionalHeader.DataDirectory[9].VirtualAddress=dwTLS_D_VA;
			CopyMemory(Base+dwPE_Offset,&nt_headers,sizeof(IMAGE_NT_HEADERS));
			FillMemory(Base+dwRO,sizeof(IMAGE_TLS_DIRECTORY32),0x00);
		}
	}
}
//----------------------------------------------------------------
// return values:
// 0 - no room for a new section
// 1 - file already encrypted
// else: returns a pointer to the IMAGE_SECTION_HEADER struct of the new section
PIMAGE_SECTION_HEADER AddSection(char* Base)
{
	IMAGE_NT_HEADERS nt_headers;
	DWORD dwSecNum,dwPE_Offset;
	DWORD SectionOffset,newSectionOffset;
	CopyMemory(&dwPE_Offset,Base+0x3c,4);
	CopyMemory(&nt_headers,Base+dwPE_Offset,sizeof(IMAGE_NT_HEADERS));// edi -> pointer to PE header
	dwSecNum=nt_headers.FileHeader.NumberOfSections;
	// contains the size of the whole section header except the size being needed for our new section
	SectionOffset=dwPE_Offset+sizeof(IMAGE_NT_HEADERS);
	newSectionOffset=SectionOffset+dwSecNum*sizeof(IMAGE_SECTION_HEADER);
	// check whether there's room for a new section
	if(nt_headers.OptionalHeader.SizeOfHeaders<(newSectionOffset+sizeof(IMAGE_SECTION_HEADER)))
	{
		return NULL;
	}
	// create a new section
	IMAGE_SECTION_HEADER section;//-> pointer to section headers
	// go to the last section
	for(DWORD i=0;i<(dwSecNum-1);i++)
	{
		CopyMemory(&section,Base+SectionOffset+i*0x28,sizeof(IMAGE_SECTION_HEADER));
		section.Characteristics=section.Characteristics | 0x80000000;
		CopyMemory(Base+SectionOffset+i*0x28,&section,sizeof(IMAGE_SECTION_HEADER));
	}
	// start to build the new section
	IMAGE_SECTION_HEADER newsection=section;//-> pointer to the new section
	CopyMemory(&section,Base+SectionOffset+(dwSecNum-1)*0x28,sizeof(IMAGE_SECTION_HEADER));
	// VirtualAddress...
	newsection.VirtualAddress=PEAlign(section.VirtualAddress
									  +section.Misc.VirtualSize,0x1000);
	// VirtualSize..
	newsection.Misc.VirtualSize=0x2000;
	// RawSize..
	newsection.SizeOfRawData=IT_SIZE+DEPACKER_CODE_SIZE;
	// Section name
	int l=(int)strlen(DEPACKER_SECTION_NAME);
	for(int i=0;i<=7;i++)
	{
		if(i<l)newsection.Name[i]=DEPACKER_SECTION_NAME[i];
		else newsection.Name[i]=0x00;
	}
	// Characteristics
	newsection.Characteristics=0xE00000E0;
	// RawOffset
	newsection.PointerToRawData=PEAlign(section.PointerToRawData
										+section.SizeOfRawData,0x200);
	CopyMemory(Base+newSectionOffset,&newsection,sizeof(IMAGE_SECTION_HEADER));
	// update the PE header
	nt_headers.FileHeader.NumberOfSections++;
	CopyMemory(Base+dwPE_Offset,&nt_headers,sizeof(IMAGE_NT_HEADERS));
	// newsection -> will be returned
	return ((PIMAGE_SECTION_HEADER)&newsection);
}
//----------------------------------------------------------------
// Base   = pointer to file memory
// dwMode: 0 - RawCrypt mode
//         1 - VirtualCrypt mode
void CryptPE(char* Base,DWORD dwMode)
{
	DWORD SectionName;
	DWORD CryptStart;
	DWORD CryptSize;						
	IMAGE_SECTION_HEADER section;
	IMAGE_NT_HEADERS nt_headers;
	DWORD dwPE_Offset;
	DWORD SectionOffset;
	CopyMemory(&dwPE_Offset,Base+0x3c,4);
	CopyMemory(&nt_headers,Base+dwPE_Offset,sizeof(IMAGE_NT_HEADERS));// edi -> pointer to PE header
	SectionOffset=dwPE_Offset+sizeof(IMAGE_NT_HEADERS);
	for(int i=0;i<nt_headers.FileHeader.NumberOfSections;i++)
	{
		CopyMemory(&section,Base+SectionOffset+i*0x28,sizeof(IMAGE_SECTION_HEADER));
		// -> skip some special sections !
		CopyMemory(&SectionName,section.Name,4);
		if((SectionName!='crsr')&&	//rsrc
		   (SectionName!='rsr.')&&	//.rsrc
		   (SectionName!='oler')&&	//reloc
		   (SectionName!='ler.')&&	//.reloc
		   (SectionName!='Cy')&&	//yC
		   (SectionName!='ade.')&&	//.edata
		   (SectionName!='adr.')&&	//.rdata
		   (SectionName!='adi.')&&	//.idata
		   (SectionName!='slt.')&&	//.tls
		   (section.PointerToRawData!=0)&&
		   (section.SizeOfRawData!=0))//-> skip also some other sections
		{
			//-> en-/decrypt it

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -