![]() |
eXeL@B —› Вопросы новичков —› Поиск вызова библиотечной функции в двоичном коде |
Посл.ответ | Сообщение |
|
Создано: 07 мая 2013 17:23 · Личное сообщение · #1 Здравствуйте. Имеется задача прочитать ЕХЕ-шник и начти в нем вызовы библиотечных функций (например, scrcopy). Дизассемблеры типа IDA спокойно разпознают вызовы бибилиотечных функций, но я так и не понял, как они это делают. С помощью гугла отрыл, что IDA использует технологию FLIRT (http://www.idapro.ru/description/flirt/). Но как искать в файле по сигнатуре, если самого кода функции там не нету, не понял.. Похоже, нужно использовать таблицу импорта, искать импортируемые dll-ки и их функции и использовать примерно такой алгоритм: 1. Смотрим в таблицу импорта и сопоставляем адрес вызова с функцией 2. Ищем в ЕХЕ-шнике в разделе кода call <адрес нужной функции> Но вот вопрос, существует ли возможность определить адреса вызова футкций до загрузки программы в память? Напримет, в случае непривязанного импорта, если я все правильно понял, адреса импортируемых функций записывваются в время загрузки программы.. но тогда как можно заранее определить, какие инструкции искать? Вот, например, как выглядит код вызова функции strcpy в дизассемблере: Code:
Получается, что все вызовы strcpy перенаправляются на метку "@ILT+475(_strcpy)", а оттуда уже на метку "strcpy". По идее, получается, что в программе мне нужно искать все команды "call @ILT+475(_strcpy)". Но как узнать, что я должен искать именно такую команду, ведь в таблице импорта нет никакой информации об этой метке. Я там нашел только RVA строк, которые хранят названия функций. Скрин с таблицей приаттачил.. ![]() ![]() |
|
Создано: 07 мая 2013 18:11 · Личное сообщение · #2 |
|
Создано: 07 мая 2013 18:52 · Личное сообщение · #3 Спасибо за ответ! Но ведь после вызова GetProcAddress(LoadLibrary(..),..), я получу виртуальный адрес функции в адресном пространстве программы, которая сканирует ЕХЕ-шник. Этот адрес, по идее, никак не связан с теми адресами, что зашиты в самом ЕХЕ файле. Если так, то как можно будет сравнивать эти адреса? ![]() |
|
Создано: 07 мая 2013 19:16 · Личное сообщение · #4 |
|
Создано: 07 мая 2013 19:46 · Личное сообщение · #5 Извините, наверно, не очень понятно пишу... Задача такая: программа на вход получает ЕХЕ-шник и должна определить, в каких местах вызввалась определенная библиотченая функция (например, scrcopy). Я подумал, что мне поможет анализ таблицы импорта ехе файла для того, чтобы получить адрес нужной функции и потом в коде ехе-шника найти инструкцию вроде call <адрес> или jmp <адрес>, чтобы определить, что из этого места была вызвана нужная мне функция. ![]() |
|
Создано: 07 мая 2013 19:46 · Личное сообщение · #6 |
|
Создано: 07 мая 2013 20:07 · Личное сообщение · #7 |
|
Создано: 07 мая 2013 20:28 · Поправил: Veliant · Личное сообщение · #8 без дизассемблера плохо будет. совсем топорный способ - искать байты FF25 или FF15 в секции кода, и сравнивать следующий dword указывает на адрес из IAT(а не на саму api) или нет. ![]() |
|
Создано: 07 мая 2013 20:39 · Поправил: Alex071 · Личное сообщение · #9 Я, честно говоря, как раз вынашивал этот топорный метод )) Но ведь пока программа не загружена в память, IAT не заполнена, там находятся только имена импортируемых функций (это я из ![]() ![]() |
|
Создано: 07 мая 2013 20:56 · Личное сообщение · #10 Alex071 пишет: там находятся только имена импортируемых функций По именам и вести. Только что-то мне подсказывает, это это очередной велосипед и ваши 'реальные' задачи решаются иными, гораздо легчеми путями. ----- Следуй за белым кроликом ![]() |
|
Создано: 07 мая 2013 21:19 · Поправил: -=AkaBOSS=- · Личное сообщение · #11 Alex071 пишет: Но ведь пока программа не загружена в память, IAT не заполнена, там находятся только имена импортируемых функций а каким образом пользовательский код вдруг получит управление в тот момент, когда IAT не заполнена? если цель - чисто статический анализ, тогда либо читаем/анализируем модули, прописанные в таблице импорта, либо просто запоминаем диапазон адресов, где находится IAT и, при обращении к ним, подставляем соответствующее имя функции. ![]() |
|
Создано: 07 мая 2013 21:44 · Поправил: Alex071 · Личное сообщение · #12 Получается, код Code:
уже заранее есть в ЕХЕ-файле? Попробовал поискать "FF 25 DC 82 3B 00" в Hex-редакторе, но без успеха.. Или же в ЕХЕ-шнике есть код типа "дальний переход на адрес, что записан в IDT", но в "FF 25 DC 82 3B 00" он превращается уже после загрузки программы в память? Например, если строка в IAT имеет такой вид: pFile | Data | Value 000060DC | 0001873E | 063B strcpy То какой должна быть строка поиска? FF 25... Извините за глупые вопросы, мне очень стыдно )) ![]() |
|
Создано: 07 мая 2013 21:52 · Поправил: -=AkaBOSS=- · Личное сообщение · #13 Alex071 пишет: Получается, код Code: 1. FF 25 DC 82 3B 00 jmp dword ptr [__imp__strcpy (3B82DCh)] уже заранее есть в ЕХЕ-файле? советую перечитать доку по секции импорта PE-файла если функция принадлежит к секции импорта, то там есть только где-то: Code:
переходники_сгенеренные_компилятором: Code:
и, наконец, в директории импорта: Code:
rva _strcpy - относительное смещение на имя импортируемой функции загрузчик, при загрузке модуля, заменяет его на реальный адрес функции в адресном пространстве процесса /ADD: но! переходников может и не быть: Code:
или, например: Code:
поэтому, если нужно найти вызов функции статически, лучше следить за всякими константами, такими как адрес или рва функции в таблице импорта ![]() |
|
Создано: 07 мая 2013 22:09 · Поправил: Alex071 · Личное сообщение · #14 |
|
Создано: 07 мая 2013 22:20 · Личное сообщение · #15 |
|
Создано: 07 мая 2013 22:31 · Поправил: Alex071 · Личное сообщение · #16 черт) Вот мое понимание, поправьте пожалуйста, что не так: 1.В IAT до загрузки программы хранятся RVA строк, содержащих имена импортируемых функций. 2.Далее загрузчик подменяет эти RVA на адреса точек входа в функции. 3.В ЕХЕ-шнике уже есть код, который берет адрес, записанный в IAT и делает jmp на этот адрес (если есть переходник) Поэтому задача в простейшем случае сводится к нахождению кода из пункта 3 ![]() |
|
Создано: 07 мая 2013 22:44 · Личное сообщение · #17 Alex071 пишет: 3.В ЕХЕ-шнике уже есть код, который берет адрес, записанный в IAT и делает jmp на этот адрес (если есть переходник) обращения к записи в IAT будут по-любому, иначе в ней бы не было смысла но! опять подчёркиваю - адрес записи в таблице импорта может помещаться в регистр или переменную перед использованием, поэтому искать нужно константу (ImageBase+rva ImportedFunc) ТС, перед поиском решения, не помешало бы изложить суть задачи - возможно, метод решения окажется проще... ![]() ![]() |
|
Создано: 08 мая 2013 14:22 · Поправил: Alex071 · Личное сообщение · #18 |
![]() |
eXeL@B —› Вопросы новичков —› Поиск вызова библиотечной функции в двоичном коде |
Эта тема закрыта. Ответы больше не принимаются. |