3. Определяем расположение таблицы импорта, выводим информацию об используемых DLL.

mz_head = (IMAGE_DOS_HEADER *)fBeg;

(DWORD)pe_head = (DWORD)fBeg + peOffset + sizeof(DWORD);

(DWORD)pe_opt_head = (DWORD)pe_head + sizeof(IMAGE_FILE_HEADER);

//Определяем расположение таблицы импорта в секции импорта...

DWORD ImportRVA = pe_opt_head->

DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;

int sect_num = -1;

//Ищем секцию с таблицей импорта...

(DWORD)sect = (DWORD)pe_opt_head + sizeof(IMAGE_OPTIONAL_HEADER);

int i;

for ( i=0; iNumberOfSections; i++)

{

if ( ImportRVA < sect->VirtualAddress )

 {

sect--;

sect_num=i-1;

break;

}

sect++;

}

if (sect_num == -1)

{

Log->Lines->Add("Данная программа не использует динамические библиотеки!");

UnmapViewOfFile(fBeg);CloseHandle(fMap);

return;

}

sect++;

DWORD AfterImportSecBeg = (DWORD)fBeg + sect->PointerToRawData;

sect--;

//Получаем файловый указатель на раздел c таблицей импорта.

LPVOID ImportSecBeg;

(DWORD)ImportSecBeg = (DWORD)fBeg + sect->PointerToRawData;

//Вычисляем смещение таблицы импорта в секции

//импорта относительно ее начала (секции).

LPVOID ImportTable;

(DWORD)ImportTable = ImportRVA - sect->VirtualAddress;

(DWORD)ImportTable = (DWORD)ImportSecBeg

+ (DWORD)ImportTable;

IMAGE_IMPORT_DESCRIPTOR *DLLInfo = (IMAGE_IMPORT_DESCRIPTOR *)ImportTable;

LPVOID DLLName;

DWORD DLLCounter = 0;

//Выводим информацию об используемых DLL

while (DLLInfo->Name != NULL)

{

DLLCounter++;

(DWORD)DLLName = (DWORD)DLLInfo->Name - sect->VirtualAddress;

(DWORD)DLLName = (DWORD)ImportSecBeg + (DWORD)DLLName;

Log->Lines->Add(IntToStr(DLLCounter)+"->"+(LPSTR)DLLName);

Application->ProcessMessages();

DLLInfo++;

}

Log->Lines->Add("Всего используется "+IntToStr(DLLCounter) + " библиотек.");

4. Определяем, имеется ли в файле достаточно свободного места для размещения новой таблицы импорта.

//Вычисляем размер новой таблицы импорта:

//Суммируем количество уже используемых DLL + наша DLL + zero запись.

DWORD NewImportTableSize = sizeof(IMAGE_IMPORT_DESCRIPTOR)*(DLLCounter+2);

char dllName[] = "azx";

NewImportTableSize += strlen(dllName)+1;

//Получаем файловый указатель на конец секции импорта.

LPVOID pos;

(DWORD)pos = AfterImportSecBeg-1;

DWORD maxFree = 0;

DWORD prevPtr;

LPVOID FreePtr = NULL;

//Ищем максимальный кусок свободного места в секции...

while ( pos >= ImportSecBeg )

{

if ( *(BYTE *)pos == 0x00 )

{

prevPtr = (DWORD)pos;

while (*(BYTE *)pos == 0x00)

(DWORD)pos -= 1;

if ( ((DWORD)prevPtr - (DWORD)pos) > maxFree )

{

maxFree = ((DWORD)prevPtr - (DWORD)pos);

(DWORD)FreePtr = (DWORD)pos + 1;

}

}

(DWORD)pos -= 1;

}

//Модифицируем полученный указатель на свободный блок, т.к.

//он может указывать на завершающий нулевой DWORD

//какой-либо структуры

(LPDWORD)FreePtr +=1;

maxFree -=4;

//Проверяем объем свободного места

if ( maxFree < NewImportTableSize )

{

Log->Lines->Add("Недостаточно свободного места в таблице импорта \

для занесения информации об дополнительной библиотеке.");

UnmapViewOfFile(fBeg);

CloseHandle(fMap);

return;

}

else

Log->Lines->Add("Достаточно свободного \

места для занесения дополнительной информации.");

Application->ProcessMessages();

5. Финальная часть: Создаем в файле новую таблицу импорта и структуру IMAGE_IMPORT_BY_NAME. Записываем в файл строки с именем нашей библиотеки и импортируемой функции. Вычисляем все необходимые адреса, заносим их в структуры IMAGE_IMPORT_DESCRIPTOR, IMAGE_IMPORT_BY_NAME. Заносим в заголовок новый адрес таблицы импорта.

//1. Копируем старую таблицу импорта в новое место

memcpy(FreePtr, ImportTable, sizeof(IMAGE_IMPORT_DESCRIPTOR)*DLLCounter);

//2.1 Сохраняем строку с именем нашей DLL в старой таблице импорта

//(для экономии места)

memcpy(ImportTable, OUR_DLL_NAME, strlen(OUR_DLL_NAME));

LPDWORD zeroPtr;

(DWORD)zeroPtr = (DWORD)ImportTable + strlen(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 + strlen(OUR_DLL_NAME) + sizeof(hackRec);

patch.IATEnd = NULL;

DWORD IIBN_Table;

memcpy(zeroPtr, &patch, sizeof(patch)); (DWORD)zeroPtr += sizeof(patch);

memcpy(zeroPtr, &Hint, sizeof(WORD)); (DWORD)zeroPtr += sizeof(WORD);

memcpy(zeroPtr, myFuncName, strlen(myFuncName)+1 );

(DWORD)zeroPtr += strlen(myFuncName)+1;

memcpy(zeroPtr, &myName, sizeof(IMAGE_IMPORT_BY_NAME) );

//2.3. Заполняем структуру IMAGE_IMPORT_DESCRIPTOR данными об нашей DLL

IMAGE_IMPORT_DESCRIPTOR myDLL;

//Вычисляем указатель на нашу структуру IMAGE_IMPORT_BY_NAME:

//это адрес начала старой таблицы импорта + длинна строки с именем

//нашей DLL + нулевой DWORD

IIBN_Table = ImportRVA + strlen( 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

LPVOID OldFreePtr = FreePtr;

(DWORD)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;

//И записываем её в конец новой таблицы импорта.

(DWORD)FreePtr +=sizeof(IMAGE_IMPORT_DESCRIPTOR)*DLLCounter;

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

UnmapViewOfFile(fBeg);

CloseHandle(fMap);

Вывод

Данная методика позволяет внедрять свою DLL библиотеку в программы, имеющие достаточно свободного места в секции с таблицей импорта. Приведенная программа может быть доработана в следующих направлениях:

Создание таблицы импорта в другой секции (если в секции с оригинальной таблицей не хватает места)

Создание новой секции и хранение новой таблицы импорта в ней.

 Отдельное слово стоит сказать об .exe файлах, входящих в стандартную поставку Windows(таких как calc.exe, paint.exe, wordpad.exe, etc.). У них таблица импорта продублирована в начале файла, между MZ- и PE- заголовками, поэтому при модификации таких файлов необходимо в соответсвующих записях в DataDirectory обнулить адреса на эти таблицы (подробнее см. файл winnt.h, раздел Directory Entries).

Список литературы

Для подготовки данной работы были использованы материалы с сайта http://www.bugtraq.ru/


Информация о работе «Жесткое внедрение DLL в Windows-программы»
Раздел: Информатика, программирование
Количество знаков с пробелами: 22271
Количество таблиц: 0
Количество изображений: 2

Похожие работы

Скачать
135709
1
0

... ) ФАКУЛЬТЕТ ЭЛЕКТРОНИКИ И ПРИБОРОСТРОЕНИЯ КАФЕДРА КЭС группа Э-92 ДАТА ЗАЩИТЫ  апреля 1997 г. Отзыв на дипломную работу студента гр.Э-92 Сорокина Ю.В. “Разработка программы контроллера автоматически связываемых объектов для управления конструкторской документацией в среде Windows 95/NT”. Широкое использование вычислительной техники в народном хозяйстве требует увеличения производства и ...

Скачать
28445
0
0

... всего пароля. Кроме того, в каждом случае используется свой запрос сервера. Поэтому на определение паролей по Sniff-файлу потребуется значительно больше времени. Первой программой, выполняющей восстановление паролей Windows NT, была L0phtCrack (сегодняшнее название - LC5). Авторами L0phtCrack являются Peiter Mudge Zatko и Chris Wysopal из фирмы L0pht Heavy Industries, Inc. (сейчас @stake, Inc.). ...

Скачать
130194
3
17

... технология Single Worldwide Binary) — можно вводить текст на любом языке и запускать версию приложений Win32 для любого языка, используя соответствующую версию операционной системы Windows XP. + + Многоязычный пользовательский интерфейс — можно менять язык пользовательского интерфейса, чтобы работать с локализованными диалоговыми окнами, меню, файлами справки, словарями, средствами проверки ...

Скачать
139808
40
0

... от традиционных локальных сетей к сочетанию сетей интранет и экстранет с Интернетом, в результате чего особенно актуальной стала задача повышения безопасности систем. Для обеспечения безопасности вычислительной среды операционная система Windows Server 2003 предоставляет множество новых средств, а также совершенствует средства, впервые появившиеся в операционной системе Windows 2000 Server. ...

0 комментариев


Наверх