Print This Post Вызов функции без импорта

Суббота, 5. Ноябрь 2011
Раздел: Assembler, Windows, Сниппеты, автор:

Сегодня посмотрел очередную свежую серию MLP:FiM и понял, что мне нечем себя занять. В связи с этим решил включить трек моей любимой группы (как вы, наверное, догадались - это Ранетки :D) и написать что-нибудь эдакое на ассемблере.
По совету друзей, которые маются всякой фигней, вместо того, чтобы заняться чем-нибудь полезным и написать нормальную статью в блог, выбор пал на написание нескольких макросов, которые позволяют вызывать библиотечные функции без использования таблицы импорта.
Минусы: макросы базозависимые.
Плюсы: макросы потокобезопасные.
Anyway: на базе этих макросов можно достаточно быстро построить новые, удобные вам.

Пример использования получившихся макросов:


Сами макросы:

Надеюсь, кому-нибудь пригодится.
Исходные коды одним архивом: скачать.

Обновлено: 14.11.11

 Обсудить на форуме


Получать обновления на почту:     

Комментариев: 21 к “Вызов функции без импорта”


  1. flisk :

    Спасибо, весьма интересно! Единственное, что значит базозависимые?
    "Минусы: макросы базозависимые."

    [Ответить]

    dx:

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

    [Ответить]


  2. User :

    А если один из параметров макроса "xinvoke" будет "addr localvar" адресом локальной переменной, то такой макрос должен не сработать. Как быть?

    [Ответить]

    dx:

    Явно использовать инструкцию lea.

    [Ответить]


  3. User :

    Это само собой, вопрос, непонятно как отличить локальную от глобальной, ведь нужно будет во время генераии push сделать lea reg, push reg.

    [Ответить]

    dx:

    Что значит "как отличить", если ты сам код пишешь и видишь, где локальные, где глобальные :)
    Я предлагаю в макросы не толкать addr, а перед вызовом макроса делать lea, а в макрос уже регистр передавать.
    Хотя если немного поколупать макросы, возможно, получится и универсально сделать.

    [Ответить]


  4. User :

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

    [Ответить]

    dx:

    Кстати, если в invoke ты используешь и регистр eax, и addr что_то, он ругнется. А чтобы эти макросы заставить работать как invoke, надо над ними поработать еще)

    [Ответить]

    dx:

    Только что сделал полную эмуляцию invoke, даже предупреждение выдает, если попытаться использовать в одном вызове оператор addr и регистр eax. Завтра выложу.

    [Ответить]

    dx:

    Обновление добавлено.

    [Ответить]


  5. User :

    Спасибо за обновление, полезный макрос. Предлагаю использовать предупреждение только в том случае, если регистр eax используется левее, чем addr, т.к. только в таком случае регистр eax будет реинициализироваться. Такую проверку можно сделать сохранением индекса параметров, а перед варнингом сделать проверку IF index_eax LT index_addr.
    Правильно ли я понимаю, различия между адресом глобальной и локальной переменной нету? Будут идеи как отличить адрес глобальной от локальной переменной?

    [Ответить]

    dx:

    Адрес никак не отличишь. Разве что, существуют какие-то виндовые функции, позволяющие отличить адрес стека от адреса кучи. Локальные переменные всегда в стеке лежат, глобальные - в куче. Может быть, такое и вручную реализуемо, не задумывался. По идее, где-то должны лежать указатели на начальные адреса стека и кучи процесса...

    [Ответить]


  6. Викинг :

    DX, ты бы не мог сделать не базозависимую версию (для крипторов/пакеров/протекторов)? Я пишу криптор.

    [Ответить]

    Kaimi:

    Расскажи-ка, что там базозависимого сейчас?

    [Ответить]

    Викинг:

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

    [Ответить]

    dx:

    Ну так возьми и напиши базонезависимые макросы, what's the problem? Человек, пишущий криптор сам, должен в таком разбираться.


  7. glukftp :

    Здесь можно взять более удобную реализацию такой идеи!
    http://www.wasm.ru/srclist.php?list=9#358

    [Ответить]


  8. аркад :

    А можнобрать функции из адрессного пространства библиотеки без подгрузки самой библиотеки

    [Ответить]

    Kaimi:

    ГРЕШНОВАТО

    [Ответить]

    dx:

    Верно толкуешь, Каимий! Какие ж адресные пространства, когда модуль не подгружен?

    [Ответить]


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