Показать сообщение отдельно

  #4  
Старый 22.03.2008, 12:45
desTiny
Reservists Of Antichat - Level 6
Регистрация: 04.02.2007
Сообщений: 1,152
Провел на форуме:
3008839

Репутация: 1502


По умолчанию

Казалось бы всё, основная идея ясна, дальше всё просто… Но, увы, нет. Попробуйте запустить файл на другом компьютере – и у вас, скорее всего, ничего не получится. Всё дело в том, что, если вы теперь нажмёте пробел на «call функция из библиотеки», то вы увидите что-то типа “CALL 7C801A24”, то есть абсолютный адрес в библиотеке. А если у нас другая версия kernel32.dll, к примеру? Тогда произойдёт ошибка, и программа работать не будет. Поэтому нам надо грамотно импортировать все используемые нами функции. Для этого существует мехонизм под названием Import Address Table (IAT). Как она работает, я подробно рассказывать не буду, а ограничусь лишь тем, что скажу, что, используя данный механизм, программа (вернее, не совсем программа, ну да ладно) при загрузке в память вычисляет адреса импортируемых функций по их символьным именам. Итак, нам надо описать должным образом нужные нам функции. Конечно, некоторые из них уже описаны, но легче описать их заново, чем искать в других секциях… А если программа ещё и запакована, что, кстати, в случае отсутствия проверки CRC никоим образом не отражается на нашей работе, то там эта оригинальная IAT ещё и спрятана.
Для нашей цели необходимы следующие функции: CreateFileA, WriteFile, CloseHandle из библиотеки kernel32.dll и WSAStartup, connect, send, recv и WSACleanup из WS2_32.dll. Поэтому закрываем Олю и открываем нашу программу в LordPE (PETools тоже умеет редактировать IAT, но у неё с этим иногда, почему-то, возникают недоразумения в виде обрезания имён функций – так WSAStartup может стать WSAStartu и т.п.):


Directories -> ImportTable -> … -> правая кнопка -> add import
В появившемся окне добавляем вначале функции из kernel32.dll (вводим название библиотеки, а потом по очереди добавляем нужные функции кнопкой «+»):


Закрываем диалог, а теперь вызываем его ещё раз, чтобы добавить функции WinSock’а:


Закрываем диалог, закрываем LordPE, стараясь нажимать Save везде, где можно. Попробуем запустить программу… Она работает. А если бы мы что-нибудь напутали, то появилась бы ошибка вида: «Точка входа в функцию xxx не найдена в библиотеке yyy».
Запускаем программу в Olly, после этого снова загружаем её в LordPE и идём в ту же самую таблицу импорта. «Зачем мы его закрывали?»,- спросите вы. А затем, чтобы лорд дал нам возможность работать с файлом. Теперь в его заголовке видим слова “Read only”, то есть теперь мы можем только смотреть на заголовок, но не можем его модифицировать. Смотрим на добавленные нами импорты:


Нам нужен ThunkRVA – по этому адресу будет находиться адрес функции в памяти после загрузки программы (разумеется, +ImageBase). И в данном свете вместо “call CreateFileA" надо писать “call xxxxxxxx”, где по адресу xxxxxxxx находится команда “jmp dword ptr [464035]”, или просто “jmp [464035]”, так как 464035 = ImageBase + ThunkRVA фунуции CreateFileA. Да, действительно, это правда – надо делать call на jmp – это не ошибка и не бред, а на самом деле очень логичная операция, так как, во-первых, к одной функции программа может стучаться несколько раз, а, во-вторых, хочется, чтобы к функциям обращение шло через обычный call. Итак, нам надо записать эти самые прыжки. Запишем их начиная с адреса 460500 (они должны попадать внутрь файла, то есть до 461000). Переключаемся в Олю, переходим на этот адрес (быстрый переход – Ctrl+G), нажимаем пробел и пишем по очереди jmp [464035], jmp [464039], jmp [46403D] – импорт из kernel32.dll, и также с WS2_32.dll – jmp [64082], jmp [64086] и т.д. Кстати, компиляторы часто зачем-то разделяют эти прыжки командой “mov eax, eax"


Теперь идём в начало секции, и изменяем “call CreateFileA” на “call 460500”, аналогично – CloseHandle. (Для этого выделяем команду, жмём пробел и пишем новый код):


Заметим, что Olly заменил наши call’ы на логичные названия. Если нажать Ctrl+A, то он точно так же выводит список параметров функции. Можно убедиться, что всё действительно работает, можно сохранить уже имеющиеся изменения уже описанным способом, но я не буду этим заниматься, а постараюсь быстренько доделать всё до победного конца.
__________________
Bedankt euch dafür bei euch selbst.

H_2(S^3/((z1, z2)~(exp(2pi*i/p)z1, exp(2pi*q*i/p)z2)))=Z/pZ