Компилятор С способный генерить PI(position independent)-код

Тема в разделе "LANGS.C", создана пользователем BlackParrot, 2 апр 2009.

  1. BlackParrot

    BlackParrot New Member

    Публикаций:
    0
    Регистрация:
    19 фев 2009
    Сообщения:
    163
    Пишу движок на C, все абсолютные смещения убрал. Ссылок на вшешние переменные и API нет. Абсолютных ссылок на строки и на любые данные тоже нет. В общем на первый взгляд все прекрасно. Но очень большим явилось мое удивление, когда про просмотре дизасм-кода я увидел абсолютные смещения, которые сгенерировал компилятор Visual C++ 6. А сделал он он их, когда компилировал секцию switch-case, создал таблицу переходов и ссылается на нее с помощью Hard-coded смещения, потом прыгает JMP [eax*ecx + offset JMP_TABLE]. В общем нужно от этих смещений избавиться. Думаю о смене компилятора. Знаю gcc -fpic. Но не пользовался никогда gcc. Ключи CL.EXE смотрел, там нет ничего подобного. Кто что может посоветовать для решения этой задачи? Юзали ли gcc? Что насчет других компиляторов(bcc)?
     
  2. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    switch в режиме оптимизации генерируется через таблицу переходов. в bcc тоже самое.
    вариант отказаться от switch'a, так же как и от конструкций вида (case1 ? func1 : func2)(x, y); (превед, крис)

    add:
    В случае gcc -fpic адреса вычисляются относительно начала секции .got.plt.
     
  3. BlackParrot

    BlackParrot New Member

    Публикаций:
    0
    Регистрация:
    19 фев 2009
    Сообщения:
    163
    censored
    Да, забыл сказать, что в Debug версии (без оптимизации) так же генериться код с дурацкими переходами.

    Ну, я думаю от switch отказываться не вариант. Потому как в теории можно без проблем нормальному компилятору сгенерировать код, который будет без абсолютных адресов где они не должны быть. Да и плясать от идиотизма конкретного компилятора не хочется. В общем буду пробовать сегодня юзать разные компиляторы(пока на думаю о bcc32 и gcc).
     
  4. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    На Debug версию в этом случае вообще смотреть нельзя. Лучше уж тогда собирать релиз с pdb'шником
     
  5. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    У Intel C++ есть опция:

    Код (Text):
    1. /Qopt-jump-tables:<arg>
    2.                        default - let the compiler decide when a jump table, a
    3.                                  series of if-then-else constructs or a
    4.                                  combination is generated
    5.                        never   - do not generate jump tables and always use
    6.                                  if-then-else constructs
    7.                        large   - generate jump tables up to a certain pre-
    8.                                  defined size (64K entries)
    Т.е. можно от генерации таблиц отказаться.
    PIC кроме gcc не знаю кто ещё генерирует.
     
  6. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    оффтоп:

    Поясните пожалуйста, зачем нужен position-independent code? Для инжектов чтоли?
     
  7. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Под Nix для *.so (shared objects) нужен - собственно потому gcc их делать и умеет.
    Под Windows кроме как для инжекта не знаю...
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Asm-вставки в VB. :) Особенно если просто ну очень ломает делать интерфейс, а нужна функциональность/скорость чуть больше той, которую позволяет VB.
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Пикод это универсальный код. Можно вставить в любое место кода, не заботясь о релоках. Просто скопипастить дамп.
    Хороший код в котором нет импортов должен быть базонезависимым. Например всякий код, который динамически распаковывается, тоесть можно скопировать код в любое место ап и исполнить его там.
     
  10. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    ф принципе можно заюзать динамическую генерацию по таргетному адресу. вопрос только в относительной стоимости и приемлемости по объемам такого решения.
     
  11. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Clerk
    Вы бы со словом "пикод" по-осторожнее. :) Минуты две переваривал, перечитывая Ваш пост, пока понял, что речь не о p-code. :)
    BlackParrot
    Перед тем, как сменить компилятор... может попробовать написать небольшой корректор, который найдёт все инструкции вида табличных прыжков и позаменяет их? После компиляции останется только этим корректором по программе пройтись.
    P.S. Интересная, кстати, инструкция "JMP [eax*ecx + offset JMP_TABLE]". :derisive: Core3Penta уже поддерживает?
     
  12. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    l_inc
    Я раньше использовал термин "шелкод", но это вызывало не верные ассоциации у товарищей, поэтому лучше пикод(Position Independent).
     
  13. BlackParrot

    BlackParrot New Member

    Публикаций:
    0
    Регистрация:
    19 фев 2009
    Сообщения:
    163
    l_inc
    В общем Clerk все хорошо описал. Лично я пишу дизасм, такой, чтобы можно быть вставить куда угодно в виде дампа байт. В итоге можно использовать и в вирусах, и в инжектах и не привязываться ни к каким форматам OBJ/LIB/etc. Еще одной важной причиной является то, что можно легко сжимать этот дамп, чтобы не тратить лишние байты. В итоге полноценный дизасм 0x86 с совершенно всеми инструкциями (например в CADT префиксных инструкций вообще нет), способный генерить мнемонику, получился весящим 12 килобайт. Хотя вес может вырости немного чуть позже, в финальной версии. Как оказалось задачка не очень простая, в коде было много строк, и пришлось немного подумать как это реализовать. В итоге я почти добился результата, осталась вот эта единственная проблема, которая по сути от меня, как от программиста не зависела, поэтому я удивился от того кода, который сгенерил мой компилятор.

    Кстати да, тут может быть путаница. Можно предложить называть это "бикод" (bi-code - base independent) чтобы как то различать понятия и быть кратким.

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

    Да, тут опечатался. Хорошая наблюдательность! Что-то типо того
    Код (Text):
    1. FFA48100104000           JMP DWORD PTR [ECX+EAX*4+0401000h]
    cppasm
    Да, это то, что нужно. В общем думаю попробовать gcc, bcc, intel c++ compiler. О результатах отпишусь, интересно кто лучше сгенерит код.
     
  14. BlackParrot

    BlackParrot New Member

    Публикаций:
    0
    Регистрация:
    19 фев 2009
    Сообщения:
    163
    В итоге Intel отлично справился с задачей, скачал варезный с торрентов. И все запахало, к тому же он неплохо оптимизирует, хотя конечно не без магии -обошлось. Не надо было плясать с бубном - он сам автоматически встраивается в VS2008 и можно его сразу использовать. Это очень большой плюс. GCC в комплекте DevC++ не прокатил т.к. он использует AT&T-асм-синтаксис, а у меня были асм-вставки. BCC вообще странный инлайн-ассемблер имеет, поддерживает только инструкции до 286 включительно. В общем это тоже не подошло. Считаю intel-компилятор наиболее адекватный на сегодяшний момент из всех опробованных. Опций оптимизации там море. И сделан для людей - хотя бы взять ту же опцию по созданию таблиц переходов.