Экспорт функций
От: thisisme  
Дата: 31.07.06 21:59
Оценка:
По какому принципу компиляторы (в частности VC6, VC7) назначают RVA экспортируемым функциям?
Пробовал различные варианты с именами и расположением функций, закономерности не нашел.
Re: Экспорт функций
От: gear nuke  
Дата: 01.08.06 13:48
Оценка: +1
Здравствуйте, thisisme, Вы писали:

T>По какому принципу компиляторы (в частности VC6, VC7) назначают RVA экспортируемым функциям?

T>Пробовал различные варианты с именами и расположением функций, закономерности не нашел.

А закономерности нет. Компилятор помещает функции в объектник в порядке, как они в сорцах, а вот линкер дальше может и перетасовать их, особенно если Link time code generation включена.

Лучше скажите, зачем это надо — может какие решения и найдутся.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: Экспорт функций
От: thisisme  
Дата: 02.08.06 09:02
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Лучше скажите, зачем это надо — может какие решения и найдутся.


Звучит глупо, конечно, но хотел засунуть тело функции в массив. Это нужно, например, для выполнения
кода в стеке. Адрес точки входа определить несложно, но вот длину функции...
Сделать это как у Криса Касперски — значит, отказаться от оптимизации, а в режиме отладки вообще невозможно (asm я не знаю),
так как компилятор вставляет переходники вместо самих функций. Поэтому был придуман сумасшедший алгоритм
Я экспортировал прямо из экзешника две функции: целевую и функцию-заглушку (ее код неважен) и затем просматривал
раздел экспорта. Оттуда добывался адрес точки входа, а длина тела — это разность RVA заглушки и целевой.
Вот только нужно, чтобы они шли именно в таком порядке. Вот мы и вернулись к вопросу.
Если есть готовые решения — буду признателен!
Re[3]: Экспорт функций
От: gear nuke  
Дата: 02.08.06 16:05
Оценка:
Здравствуйте, thisisme, Вы писали:

[]

T>Я экспортировал прямо из экзешника две функции: целевую и функцию-заглушку (ее код неважен) и затем просматривал

T>раздел экспорта. Оттуда добывался адрес точки входа

Необязательно экспортировать функцию. Единственное условие — она не должна заинлайнится. Но компилятор не будет инлайнить функции, адрес которых присваивается указателю — то есть как раз Ваш случай. Или для надежности:
#pragma auto_inline(off)

T>а длина тела — это разность RVA заглушки и целевой.

Универсального решения для определения длины функции нет — компилятор (хотя VC6 маловероятно, но поздние так делают) может разделить функцию на куски или даже расположить её конец перед началом. Необходимо быть осторожным с ветвлениями и смотреть результат компиляции. Может помочь пустая команда в конце:
__asm nop

T>Вот только нужно, чтобы они шли именно в таком порядке. Вот мы и вернулись к вопросу.

Попробуйте следующую функцию объявить как __declspec(neked) или тоже nop написать. Тут нужно дать оптимизатору хинт поменьше думать. Не факт, конечно, что он сохранит порядок, но для конкретного случая может помочь. Обычно компилятор не меняет функции без причин.

T>Если есть готовые решения — буду признателен!


Пусть компилятор сгенерирует asm листинг для функции. Вы его вырежите и вставите в __asm {}

ЗЫ Как Касперски рекомендовал делать — не знаю.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.