May 182013
 

Автор: joaquimandrade

Библиотека это набор байтов. Миллионов байтов. Они могут представлять числа, функции (в машинном коде), массивы и строки. Эта статья попытается объяснить вам, как найти функции в библиотеках и как их использовать.

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

В библиотеках, откомпилированных GCC (Linux), оффсеты помечены символьными именами, с помощью которых Вы можете легко распознать, что находится по данному оффсету.

В библиотеках, откомпилированных VC++, оффсеты, в целом, не имеют никаких меток, так что приходиться обращаться к таким методам, как поиск строки в библиотеке. Это происходит потому, что Вы можете легко связать строки в события, например, если Вы видите надпись “Terrorists Win”, то Вы знаете, что имеете дело с функцией, связанной с концом раунда.

При поиске оффсетов, мы можем использовать следующие методы:

  1. Нахождение функции путем поиска строк.
  2. После нахождения функции, использовать ее для нахождения других функций, например, если Вы знаете, что ваша функция вызывает или вызывается другой функцией.
  3. Применять изложенные выше действия в обратном порядке (комбинированный)

Что облегчить данный процесс, вам следует делать его с помощью библиотеки Linux.
Таким образом, вам необходимо иметь библиотеки вашего мода для Linux и Windows, а также заполучить “IDA Pro Disassembler”.

В IDA
IDA Start
Нажмите New

Для библиотеки Linux:
IDA Linux

Для библиотеки Windows:
IDA Windows

Выберете библиотеку и откройте ее.

Нажмите CTRL+F5. Это откроет диалог, где Вы можете выбрать место сохранения файла. Этот файл – декомпилированная версия вашей библиотеки (особенность IDA, в отм что она конвертирует машинный код обратно в код С (не очень читабельный код и не точно повторяющий оригинал, однако более читаемый, чем машинный код)).

В декомпилированной версии библиотеки Linux, у вас будет примерно такой код:

Это функция InstallGameRules, где легко можно увидеть, что используется строка “exec game.cfg\n”.

Теперь взглянем на декомпилированную версию библиотеки для Windows:

После беглого осмотра легко заметить, что мы имеем дело с одной и той же функцией.

Это значит, что оффсет 88530 в файле Counter Strike для Windows будет давать нам функцию InstallGameRules. Вы можете увидеть это в псевдо-метке “sub_10088530” (не обращаем внимание на sub_10). Теперь это число представляется нам, как шестнадцатиричное. Обозначим его 0x88530.

Чтобы продемонстрировать другой метод, обратимся к декомпилированной Linux библиотеки для функции InstallGameRules, чтобы найти функцию, ее вызывающую.

В последней строке Вы можете увидеть, что функция InstallGameRules вызывается из CWorld__Precache (настоящее имя CWorld::Precache). Тепрь возвращаемся в декомпилированную Windows библиотеку.

Заменяем все значения sub_10088530 на InstallGameRules. Ищем InstallGameRules.

И мы находим CWorld__Precache (offset 0xDD350).

В основном это все. При применении этих знаний и маленькой толики вашего мозга, Вы можете найти, в принципе, любую функцию.

Теперь о типах, которые может использовать функция. Вы можете проверить их, просмотрев список функций в Linux-версии библиотеки в окне IDA под именем Names. Я не знаю, существует ли простой путь для типа Return, однако вы всегда можете предположить его или проверить Half Life SDK, если это, конечно, имеет смысл.

Для данного случая:

Это должно находиться в файле InstallGameRules в папке configs/orpheu/functions. Помните, что если бы функция принадлежала классу, то вам бы пришлось создать папку с именем класса.

Следует знать еще кое-что. Оффсет гарантированно будет всегда одинаков каждый раз, когда библиотека загружается, однако он может с легкостью измениться, если библиотека обновилась. Однако эта проблема решается созданием сигнатур функции.

В общем, сканирование сигнатур означает следующее: вместо того, чтобы определять оффсет, определяется набор байтов, который можно найти в этом оффсете (те, что представляют функцию). Этот набор байтов может легко изменить свое местоположение, однако до тех пор, пока он существует в виде блока, вы можете легко найти его.

Перевод: Dani Minch
Источник: http://forums.alliedmods.net/showthread.php?t=118934

Статьи по теме:
Модуль Orpheu (v2.5.1)
Сигнатуры функций.

Dani Minch

Тот парень. Что-то пишу, когда не лень.

Оставить комментарий

Пожалуйста, авторизуйтесь чтобы добавить комментарий.
  Подписаться  
Уведомление о