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

📄 erika.c

📁 KByS是一个PE文件压缩壳,在这里你可以学到壳是怎么制作的
💻 C
📖 第 1 页 / 共 3 页
字号:
		mov esi, dword ptr [esp+0x28]
		lods byte ptr [esi]
		mov edx, eax
	copy:
		lods dword ptr [esi]
		mov edi, eax
		add edi, ebp
		lods dword ptr [esi]
		mov ecx, eax
		rep movsb                          ;恢复各段
		dec edx
		jnz copy
		pop ecx
		pop edx
		pop eax
		mov edi, [esp]
		test eax, eax
		je noe8e9;
	nexte8e9:
		mov al, byte ptr [edi]
		inc edi
		sub al, 0xe8
		cmp al, 1
		ja nexte8e9
		mov eax, [edi]
		cmp al, dl
		jne nexte8e9
		xor al, al
		bswap eax
		add eax, [esp]
		sub eax, edi
		stos dword ptr [edi]                ;E8 E9过滤
		loop nexte8e9
	noe8e9:
		push ebp
	nextdll:
		lods dword ptr [esi]
		test eax, eax
		je over
		mov edi, eax
		add edi, [esp]
		push esi
		call dword ptr [ebx]
		mov ebp, eax
	dllname:
		lods byte ptr [esi]
		test al, al
		jnz dllname
	apiname:                                ;输入表恢复
		lods dword ptr [esi]
		test eax, eax
		je nextdll
		sub esi, 0x04
		lods dword ptr [esi]
		test eax, 0x80000000
		jnz ordinal
		sub esi, 0x04
		push esi
		push ebp
		call dword ptr [ebx+0x04]
		stos dword ptr [edi]
		jmp dllname
	ordinal:
		and eax, 0x7FFFFFFF
		push eax
		push ebp
		call dword ptr [ebx+0x04]
		stos dword ptr [edi]
    	jmp apiname
	over:
		pop ebp
		pop edi
		ret
	}
}

void __declspec(naked) loader_end()
{
	__asm
	{
		lea ebx, [edi-0x04]
	reloc:
		xor eax, eax
		lods byte ptr [esi]
		test al, al
		je over
		cmp al, 0xEF
		ja reloc2
	reloc1:
		add ebx, eax
		add [ebx], edi
		jmp reloc
	reloc2:
		and al, 0x0F
		shl eax, 0x10
		lods word ptr [esi]
		test eax, eax
		jnz reloc1
		lods dword ptr [esi]
		jmp reloc1
	over:
		ret
	}
}

void __declspec(naked) loader_end2()
{
	__asm __emit 0xCC
}

///////////////////////////////////////////////////////////////
void MakeShell()
{
	//这里再不写点注释以后就记不清了
	DWORD	dwLastSection;
	DWORD	dwSizeOfLoader;
	DWORD	dwSizeOfHeader;
	DWORD	dwSizeOfFile;
	DWORD	dwSize;
	DWORD	i;

	//通过最后一个区段信息计算壳段起始地址
	dwLastSection = PE->FileHeader.NumberOfSections-1;
	AddrOfShell = (SH+dwLastSection)->VirtualAddress + (SH+dwLastSection)->Misc.VirtualSize;
	AddrOfShell = (AddrOfShell+0xFFF)/0x1000*0x1000;

	dwSizeOfLoader = (DWORD)loader_end - (DWORD)loader;
	if (MapOfReloc != NULL && SizeOfReloc != 0)
		dwSizeOfLoader += (DWORD)loader_end2 - (DWORD)loader_end - 1;

	//壳段总长
	SizeOfShell = SizeOfRSRC + sizeof(ShellIAT) + dwSizeOfLoader + SizeOfPacked + SizeOfTLS;
	//dll重定位
	if (MapOfReloc != NULL && SizeOfReloc != 0)
		SizeOfShell += 0x0C; 

	MapOfShell = VirtualAlloc(NULL, SizeOfShell, MEM_COMMIT, PAGE_READWRITE);

	dwSize = 0;
	//先写入资源
	if (MapOfRSRC != 0 && SizeOfRSRC != 0)
	{
		if (CountOfICON != 0 && ICONOffset != NULL)
		{
			for (i=0; i<CountOfICON; i++)
			{
				*(LPDWORD)(*(LPDWORD)(ICONOffset+i*8+4)) += AddrOfShell;
			}
		}
		if (GICONOffset != 0)
			*GICONOffset += AddrOfShell;
		if (VERSNOffset != 0)
			*VERSNOffset += AddrOfShell;
		if (XML18Offset != 0)
			*XML18Offset += AddrOfShell;
		memcpy(MapOfShell+dwSize, MapOfRSRC, SizeOfRSRC);
		dwSize += SizeOfRSRC;
	}

	//再是输入表
	memcpy(MapOfShell+dwSize, ShellIAT, sizeof(ShellIAT));
	*(LPDWORD)(MapOfShell+dwSize+0x0C) += AddrOfShell+dwSize;
	*(LPDWORD)(MapOfShell+dwSize+0x10) += AddrOfShell+dwSize;
	*(LPDWORD)(MapOfShell+dwSize+0x70) += AddrOfShell+dwSize;
	*(LPDWORD)(MapOfShell+dwSize+0x74) += AddrOfShell+dwSize;
	*(LPDWORD)(MapOfShell+dwSize+0x78) += AddrOfShell+dwSize;
	*(LPDWORD)(MapOfShell+dwSize+0x7C) += AddrOfShell+dwSize;
	dwSize += sizeof(ShellIAT);

	//再是loader
	memcpy(MapOfShell+dwSize, &loader, (DWORD)loader_end - (DWORD)loader);
	*(LPDWORD)(MapOfShell+dwSize+0x02) = AddrOfShell + dwSize + 19;
	*(LPDWORD)(MapOfShell+dwSize+0x07) = PE->OptionalHeader.ImageBase;
	*(LPDWORD)(MapOfShell+dwSize+0x0F) = SH->VirtualAddress 
		                                 + sizeof(EP) + sizeof(Aplib) + sizeof(LZMA);
	dwSize += (DWORD)loader_end - (DWORD)loader;
	if (MapOfReloc != NULL && SizeOfReloc != 0)
	{
		memcpy(MapOfShell+dwSize-1, &loader_end, (DWORD)loader_end2-(DWORD)loader_end);
		dwSize += (DWORD)loader_end2-(DWORD)loader_end-1;
	}

	//再是压缩数据
	memcpy(MapOfShell+dwSize, MapOfPack+0x0E, SizeOfPacked);
	dwSize += SizeOfPacked;

	//再是新重定位表
	if (MapOfReloc != NULL && SizeOfReloc != 0)
	{
		i = AddrOfShell + SizeOfRSRC + sizeof(ShellIAT) + 0x07;
		*(LPDWORD)(MapOfShell+dwSize+0x00) = i/0x1000*0x1000;
		*(LPDWORD)(MapOfShell+dwSize+0x04) = 0x0C;
		*(LPWORD)(MapOfShell+dwSize+0x08) = 0x3000 | (i%0x1000);
		*(LPWORD)(MapOfShell+dwSize+0x00A) = 0;
	}

	//再是TLS
	if (MapOfTLS != NULL && SizeOfTLS != 0)
	{
		memcpy(MapOfShell+dwSize, MapOfTLS, SizeOfTLS);
		dwSize += SizeOfTLS;
	}

	//计算新的PE头的长度
	dwSizeOfHeader = 4 + 40 + (DWORD)&(SH+dwLastSection)->Characteristics;
	dwSizeOfHeader -= (DWORD)MapOfFile;
	dwSizeOfHeader = (dwSizeOfHeader+0x1FF)/0x200*0x200;
	PE->OptionalHeader.SizeOfHeaders = dwSizeOfHeader;

	//更新各个新区段
	dwSizeOfFile = dwSizeOfHeader;
	for (i=0; i<PE->FileHeader.NumberOfSections; i++)
	{
		if (i==0)
		{
			memset(MapOfFile+(SH+i)->VirtualAddress, 0, 0x600);
			memcpy(MapOfFile+(SH+i)->VirtualAddress, EP, sizeof(EP));
			memcpy(MapOfFile+(SH+i)->VirtualAddress+sizeof(EP), Aplib, sizeof(Aplib));
			memcpy(MapOfFile+(SH+i)->VirtualAddress+sizeof(EP)+sizeof(Aplib), LZMA, sizeof(LZMA));
			memcpy(MapOfFile+(SH+i)->VirtualAddress+0x600-sizeof(INFO), INFO, sizeof(INFO));
			*(LPDWORD)(MapOfFile+(SH+i)->VirtualAddress+1) = PE->OptionalHeader.ImageBase + AddrOfShell + SizeOfRSRC + sizeof(ShellIAT) + 1;
			(SH+i)->PointerToRawData = dwSizeOfFile;
			(SH+i)->SizeOfRawData = 0x600;
			dwSizeOfFile += 0x600;
			continue ;
		}
		(SH+i)->PointerToRawData = dwSizeOfFile;
		(SH+i)->SizeOfRawData = 0;
	}
	//增加壳段到PE头中
	(SH+i)->VirtualAddress = AddrOfShell;
	(SH+i)->PointerToRawData = dwSizeOfFile;
	(SH+i)->SizeOfRawData = (dwSize+0x1FF)/0x200*0x200;
	dwSizeOfFile += dwSize;
	dwSize = (dwSize+0xFFF)/0x1000*0x1000;
	(SH+i)->Misc.VirtualSize = dwSize;
	(SH+i)->Characteristics = 0xE00000E0;
	strcpy((SH+i)->Name, ".shoooo");

	//更新总映象大小和区段数等等
	PE->OptionalHeader.SizeOfImage = AddrOfShell+dwSize;
	PE->FileHeader.NumberOfSections++;
	PE->OptionalHeader.FileAlignment = 0x200;
	PE->OptionalHeader.SectionAlignment = 0x1000;

	//填壳信息
	ShellInfo = (LPDWORD)(MapOfFile+SH->VirtualAddress+sizeof(EP)+sizeof(Aplib)+sizeof(LZMA));
	*(ShellInfo+0) = PE->OptionalHeader.AddressOfEntryPoint;//OEP
	*(ShellInfo+1) = AddrOfShell + SizeOfRSRC + sizeof(ShellIAT) - 0x14;//壳IAT
	*(ShellInfo+2) = 0;
	*(ShellInfo+3) = SH->VirtualAddress + sizeof(EP)+sizeof(Aplib); //LZMA块
	*(ShellInfo+4) = SH->VirtualAddress + sizeof(EP); //Aplib解压函数
	*(ShellInfo+5) = SizeOfPack;//解压后的数据长度
	*(ShellInfo+6) = SizeOfPacked; //压缩包的长度
	*(ShellInfo+7) = AddrOfShell + SizeOfShell - SizeOfPacked - SizeOfTLS; //压缩数据起始
	if (MapOfReloc != NULL && SizeOfReloc != 0)
		*(ShellInfo+7) -= 0x0C;
	*(ShellInfo+8) = SH->VirtualAddress; //第一段起始
	if (MagicMark != 0xFE)
		*(ShellInfo+9) = 1;
	else
		*(ShellInfo+9) = 0;
	*(ShellInfo+10) = MagicMark;
	*(ShellInfo+11) = MagicNumber;

	//更新ep
	PE->OptionalHeader.AddressOfEntryPoint = SH->VirtualAddress;
	if (MapOfReloc != NULL && SizeOfReloc != 0)
		PE->OptionalHeader.AddressOfEntryPoint = AddrOfShell + SizeOfRSRC + sizeof(ShellIAT) + 1;


	//更新资源表和输入表
	PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = AddrOfShell+SizeOfRSRC;
	PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = sizeof(ShellIAT);
	if (MapOfRSRC != NULL && SizeOfRSRC != 0)
	{
		PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = AddrOfShell;
		PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SizeOfRSRC;
	}
	if (MapOfTLS != NULL && SizeOfTLS != 0)
	{
		PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = AddrOfShell+SizeOfShell-SizeOfTLS;
		PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = SizeOfTLS;
	}
	if (MapOfReloc != NULL && SizeOfReloc != 0)
	{
		PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = AddrOfShell+SizeOfShell-0x0C-SizeOfTLS;;
		PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0x0C;
	}

	//清段垃圾表
	PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
	PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
	PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = 0;
	PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = 0;
	PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = 0;
	PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = 0;
	
	return ;
}

///////////////////////////////////////////////////////////////
void OutputFile(HANDLE hFile)
{
	DWORD	dwWritten;
	int		i;
  
	WriteFile(hFile, MapOfFile, PE->OptionalHeader.SizeOfHeaders, &dwWritten, NULL);

	for (i=0; i<PE->FileHeader.NumberOfSections-1; i++)
	{
		WriteFile(hFile, (SH+i)->VirtualAddress+MapOfFile, (SH+i)->SizeOfRawData, &dwWritten, NULL);
	}
	WriteFile(hFile, MapOfShell, (SizeOfShell+0x1FF)/0x200*0x200, &dwWritten, NULL);
	if (MapOfOverlay !=0 && SizeOfOverlay !=0)
	{
		WriteFile(hFile, MapOfOverlay, SizeOfOverlay, &dwWritten, NULL);
	}
}

///////////////////////////////////////////////////////////////
void jobdone()
{
	memset(szFileName, 0, sizeof(szFileName));
	if (MapOfFile != NULL)
	{
		VirtualFree(MapOfFile, 0, MEM_RELEASE);
		MapOfFile = NULL;
	}
	if (MapOfOverlay != NULL)
	{
		VirtualFree(MapOfOverlay, 0, MEM_RELEASE);	
		MapOfOverlay = NULL;
	}
	SizeOfOverlay = 0;
	if (MapOfIAT != NULL)
	{
		VirtualFree(MapOfIAT, 0, MEM_RELEASE);
		MapOfIAT = NULL;
	}
	SizeOfIAT = 0;
	if (MapOfRSRC != NULL)
	{
		VirtualFree(MapOfRSRC, 0, MEM_RELEASE);
		MapOfRSRC = NULL;
	}
	SizeOfRSRC = 0;
	CountOfICON = 0;
	if (ICONOffset != NULL)
	{
		VirtualFree(ICONOffset, 0, MEM_RELEASE);
		ICONOffset = NULL;
	}
	GICONOffset = NULL;
	VERSNOffset = NULL;
	XML18Offset = NULL;
	if (MapOfTLS != NULL)
	{
		VirtualFree(MapOfTLS, 0, MEM_RELEASE);
		MapOfTLS = NULL;
	}
	SizeOfTLS = 0;
	if (MapOfReloc != NULL)
	{
		VirtualFree(MapOfReloc, 0, MEM_RELEASE);
		MapOfReloc = NULL;
	}
	SizeOfReloc = 0;
	if (MapOfPack != NULL)
	{
		VirtualFree(MapOfPack, 0, MEM_RELEASE);
		MapOfPack = NULL;
	}
	SizeOfPack = 0;
	SizeOfPacked = 0;
	if (MapOfShell != NULL)
	{
		VirtualFree(MapOfShell, 0, MEM_RELEASE);
		MapOfShell = NULL;
	}
	AddrOfShell = 0;
	SizeOfShell = 0;
	ShellInfo = NULL;

	PE = NULL;
	SH = NULL;
	bDLL = FALSE;
}

///////////////////////////////////////////////////////////////
void KByS()
{
	HANDLE		hFile;
	
	hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		if (bChinese)
			strcpy(szMessage, "打开文件失败");
		else
			strcpy(szMessage, "fail to open the file");
		return;
	}
	if (!IsPE(hFile))
	{
		if (bChinese)
			strcpy(szMessage, "无效PE");
		else
			strcpy(szMessage, "invalid PE file");
		CloseHandle(hFile);
		return;
	}
	MapFile(hFile);
	OverlayFile(hFile);
	CloseHandle(hFile);
	SizeOfIAT = GetSizeIAT();
	FuckIAT();
	GetIconRSRC();
	FuckRSRC();
	FuckTLS();
	FuckReloc();
	MakeReloc();
	FuckE8E9();
	FuckSection();
	PackSection();
	MakeShell();
	BackupSrcFile(szFileName);
	hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		if (bChinese)
			strcpy(szMessage, "写入文件失败");
		else
			strcpy(szMessage, "fail to write the file");
		jobdone();
		return;
	}
	OutputFile(hFile);
	CloseHandle(hFile);
	jobdone();
	if (bChinese)
		strcpy(szMessage, "压缩完成");
	else
		strcpy(szMessage, "job done");
	return;
}

⌨️ 快捷键说明

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