Здесь читаем: "Компанией Microsoft была создана утилита, которая называется BIND. Ей на вход подается PE-файл, а она записывает в массив OriginalFirstThunk, таблицы импорта данного файла, адреса функций которые данный PE-файл использует." Я ничё не могу понять. А что даёт наличие в этом массиве адресов импортируемых функций? ...Честно говоря, я вообще не понимаю, зачем два массива OriginalFirstThunk и FirstThunk. Какова их практическая цель? Но я пока не ставлю этот вопрос, ибо так для себя ответил (ошибочно, но хоть как-то)- всегда можно просмотреть массив OriginalFirstThunk (он содержит RVA массива элементов типа IMAGE_THUNK_DATA32, адрес второго поля которого- адрес строки с именем функции) и FirstThunk (а этот содержит RVA адресов этих функций, да ещё и правится при загрузке) Причём два массив строго друг другу соотвествуют. Выводится один и другой и всё видно. Можно сделать так: для каждой импортируемой функции вывод имени и RVA адреса. Только для того, по-моему, чтобы я или кто другой мог получше ознакомиться с тем, какие функции PE-файл импортирует. И всё! Но зачем, извините, какие-то ещё дополнительные движения? Зачем биндингом (А потом ещё и Bound какой-то идёт) заполнять OriginalFirstThunk? Я понимаю, что адреса (или RVA, оно вычисляется из другого) нужны для корректировки ОДНОГО МЕСТА в коде, не знаю, как оно называется. Типа таблицы какой-то. При вызове всех api-функций совершается прыжок на жёлтую строчку (в OllyDbg она жёлтая) а потом ещё НА ОДНУ. ВОТ ЭТУ ПОСЛЕДНЮЮ И НАДО ПРАВИТЬ, ибо именно с неё идут прыжки НЕПОСРЕДСТВЕНО на адреса API-функций. А они разны, как я понимаю, в разных версиях Windows и всякий раз вычисляются системой (загрузчиком) и правятся. Но на фига эти танцы с бубном вокруг OriginalFirstThunk и FirstThunk, хоть убей, не пойму. Извините, если задел чьи-то чувства. Я учусь сам и вот. Спасибо.
amvoz Надо успокоится =) Если получится, попытаться все-таки добить начатый абзац: "Компанией Microsoft была создана утилита, которая называется BIND. Ей на вход подается PE-файл, а она записывает в массив OriginalFirstThunk, таблицы импорта данного файла, адреса функций которые данный PE-файл использует. Такая операция называется биндингом (binding) и служит в целях оптимизации процесса загрузки исполняемого файла." Системный лоадер сравнит TimeDateStamp из дескриптора с соответствующим значением для DLL. Если совпадает, то ... ... используются уже заранее прописанные адреса и загрузчик не тратит драгоценное время на резолвинг, а спокойно отхлебывает крепкого Ирландского Red Biddy. Вот затем и биндится. Видимо не понимаешь. В коде ничего НЕ корректируется, вызовы производятся относительно таблицы, которая и должна быть пропатчена на стадии загрузки.
Я всё изучу и подумаю. Но сейчас одна деталь не вызывает у меня сомнений (хотя я ошибаюсь, как всегда). И я хотел бы её обсудить. Как так? Вот код. Минимальное корректное приложение. Код (Text): .386 .model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib .data .code start: invoke ExitProcess, 0 end start Или, что то же самое, но в отладчике 00401000 6A 00 PUSH 0 00401002 E8 01000000 CALL <JMP.&kernel32.ExitProcess> 00401007 CC INT3 00401008 FF25 00204000 JMP DWORD PTR DS:[<&kernel32.ExitProcess>] C адреса 401002h прежде, чем прыгнуть на точку входа ExitProcess, идёт прыжок на 401008h По адресу 401008h находится код. И он правится при загрузке файла. Не может не правиться. А иначе что произойдёт: "FF25 00204000" означает, прыжок на начало ExitProcess (7c81caa2) в УСТАНОВЛЕНОЙ У МЕНЯ ОС. Запусти я этот код на другой оси, где другой адрес ExitProcess (не 7c81caa2. ExitProcess взята для примера только), эта функция уже не вызовется, ибо у неё другой адрес. Поэтому необходимо править этот участок кода. И это не таблица импорта. Так ведь?
[<&kernel32.ExitProcess>] - означает что читаем адрес из памяти. Там лежит IAT, которая содержит адрес импортируемых функций, и которая заполняется загрузчикам когда он обрабатывает импорт.
Я щас изучаю всё это, дайте пожалуйста минимальный корректный код, где используется API функция, которая импортируется по ординалу. Я не представляю ни одной. Мне необходимо посмотреть бинарник, в частности поле Ordinal.IMAGE_THUNK_DATA32 Щас пытаюсь вывести массив FirstThunk. Если функция импортируется по имени, то я разобрался, как выводить имя, а если по ординалу- то нет. ...То ли я не представляю, что такое "старший бит двойного слова", то ли опять автор "От зелёногок красному" что-то напутал. Спасибо.
Ну, то есть понятно, что если функция выводится по ординалу, я её имя выводить не буду, а выведу, допустим printf ("Only ordinal %x", (int) ordinal); Как-то так.
Из 792 файлов в папке с виндой - у 792 заполнен массив Original First Thunk. Это потому что там дельфе нету) то ли опять автор "От зелёногок красному" что-то напутал. сильно сомневаюсь) Почитай Мэтта Питрека лучше.
Дело Ваше А вот это ложь: "Компанией Microsoft была создана утилита, которая называется BIND. Ей на вход подается PE-файл, а она записывает в массив OriginalFirstThunk" Отсюда http://www.wasm.ru/article.php?article=green2red02#_Toc100906478 ...Специально нашёл утилиту EDITBIN.EXE и прошёлся ей по mesagebox.exe Адреса записываются в FirstThun. deLight, между прочим.
Кстати, шутки шутками, а, может тема-то и была создана от непонимания того, что правится биндингом не OriginalFirstThunk, а FirstThunk. Так-то, может и темы такой не создал. Пишу "может" потому, что уж забыл я, что думал,когда тему создавал- столько всего напереваривал в голове тех пор.