Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.01.2012, 22:23   #1
Dimarik
Форумчанин
 
Аватар для Dimarik
 
Регистрация: 18.04.2009
Сообщений: 688
Сообщение изменить dll (добавить запись)

Необходимо в таблицу импорта dll добавить новую запись об импортируемой функции. Я прочитал статью как это сделать (кому интересно вот она http://zalil.ru/32543884)
Но по ней нормально получилось сделать только до момента: получение виртуального адреса (преобразованного виртуального адреса!) таблицы импорта. Это я получил на строке 262. Вопросов по этому нет.
Но далее. Необходимо осуществить запись о новой импортируемой функции из новой dll.
Я осуществил проверку, достаточно ли места в секции чтобы вставить еще 2 массива IMAGE_IMPORT_DESCRIPTOR.
Если места недостаточно то программа идет к метке об ошибке и вызвывает ExitProc.
Но тут встал вопрос. Как грамотно надо добавить данные в таблицу импорта. Я нашел статью в Интернете:
http://bugtraq.ru/library/programming/harddll.html
Посмотрел код, там оказалось очень много непонятного на данном моменте, например:
Код:
//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) );
особенно с этой структурой hackRec patch
а начиная с
Код:
   memcpy(zeroPtr, &patch, sizeof(patch)); (DWORD)zeroPtr += sizeof(patch);
вообще непонятка. Как я понял, в zeroPtr находится адрес нулевых элементов в таблице импорта. Это как бы адрес последнего элемента. И если мы хотим добавить еще одну запись, то на место этого нулевого элемента надо поместить элемент с информацией и дальше опять после него ячейку запомнить структурой с нулями.
Но зачем для этого кучу левых структур создавать?
Да и к тому же, там совершенно разные поля:
Код:
typedef struct {
      DWORD ZeroDword;
      DWORD IAT;
      DWORD IATEnd;
      } hackRec;
Немножко не похоже на состав структуры IMAGE_IMPORT_DESCRIPTOR. Как-то непонятно.
Можете на пальцах пояснить, как дальше осуществить запись в таблицу импорта по шагам?
Я уже эти мануалы по PE-формату проштудировал не один раз, так что можно ссылку на описание не кидать)))
Пописал маленькие программки из туториалов по ассемблеру на эту тему и из цикла статей "от зеленого к красному тоже".
P.S. Вот код который я настрочил, правда он недоработанный и с этой 262 строки конкретная недоделка идет.
http://zalil.ru/32543970
И еще хотел спросить. В статье, которую я в архиве выслал написано, что нужно добавить будет не только структуру IMAGE_IMPORT_DESCRIPTOR, но еще "нужно создать и заполнить массивы по адресам OriginalFirstThunk и FirstThunk". И что самое простое решение - перенести в конец какой-нибудь секции".
То есть, например, мы находимся в секции .text, нужно найти начало следующей секции и конец важных данных в .text, кстати КАК ЭТО ПРАВИЛЬНО СДЕЛАТЬ? Последней структурой в .text будет IMAGE_IMPORT_BY_NAME? и нужно посмотреть сколько после нее свободного пространства? Так? А если не хватит для добавления еще одной записи? Ведь такое же тоже может случиться? Тогда кусками в разные секции пихать что ли?
Поясните, пожалуйста, поподробней. Заранее спасибо за помощь. Подскажите кто чем может, пожалуйста.
Dimarik вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Добавить (изменить) данные в БД arthur1 БД в Delphi 13 25.10.2011 23:04
Есть ли способ добавить/удалить элемент в дереве DBGridEh и соответственно изменить запись в базе данных? xorornot Общие вопросы Delphi 0 13.07.2011 11:22
Форма с кнлпками Добавить/Изменить/Удалить запись P.A.S.C.A.L. Microsoft Office Access 1 26.06.2011 21:11
Добавить запись в DBGrid adil БД в Delphi 7 27.07.2010 12:50
C#: Добавить, Изменить и удалить строку в бд Veiron Общие вопросы .NET 1 10.06.2009 09:25