Пишу движок на C, все абсолютные смещения убрал. Ссылок на вшешние переменные и API нет. Абсолютных ссылок на строки и на любые данные тоже нет. В общем на первый взгляд все прекрасно. Но очень большим явилось мое удивление, когда про просмотре дизасм-кода я увидел абсолютные смещения, которые сгенерировал компилятор Visual C++ 6. А сделал он он их, когда компилировал секцию switch-case, создал таблицу переходов и ссылается на нее с помощью Hard-coded смещения, потом прыгает JMP [eax*ecx + offset JMP_TABLE]. В общем нужно от этих смещений избавиться. Думаю о смене компилятора. Знаю gcc -fpic. Но не пользовался никогда gcc. Ключи CL.EXE смотрел, там нет ничего подобного. Кто что может посоветовать для решения этой задачи? Юзали ли gcc? Что насчет других компиляторов(bcc)?
switch в режиме оптимизации генерируется через таблицу переходов. в bcc тоже самое. вариант отказаться от switch'a, так же как и от конструкций вида (case1 ? func1 : func2)(x, y); (превед, крис) add: В случае gcc -fpic адреса вычисляются относительно начала секции .got.plt.
censored Да, забыл сказать, что в Debug версии (без оптимизации) так же генериться код с дурацкими переходами. Ну, я думаю от switch отказываться не вариант. Потому как в теории можно без проблем нормальному компилятору сгенерировать код, который будет без абсолютных адресов где они не должны быть. Да и плясать от идиотизма конкретного компилятора не хочется. В общем буду пробовать сегодня юзать разные компиляторы(пока на думаю о bcc32 и gcc).
У Intel C++ есть опция: Код (Text): /Qopt-jump-tables:<arg> default - let the compiler decide when a jump table, a series of if-then-else constructs or a combination is generated never - do not generate jump tables and always use if-then-else constructs large - generate jump tables up to a certain pre- defined size (64K entries) Т.е. можно от генерации таблиц отказаться. PIC кроме gcc не знаю кто ещё генерирует.
Под Nix для *.so (shared objects) нужен - собственно потому gcc их делать и умеет. Под Windows кроме как для инжекта не знаю...
Asm-вставки в VB. Особенно если просто ну очень ломает делать интерфейс, а нужна функциональность/скорость чуть больше той, которую позволяет VB.
Пикод это универсальный код. Можно вставить в любое место кода, не заботясь о релоках. Просто скопипастить дамп. Хороший код в котором нет импортов должен быть базонезависимым. Например всякий код, который динамически распаковывается, тоесть можно скопировать код в любое место ап и исполнить его там.
ф принципе можно заюзать динамическую генерацию по таргетному адресу. вопрос только в относительной стоимости и приемлемости по объемам такого решения.
Clerk Вы бы со словом "пикод" по-осторожнее. Минуты две переваривал, перечитывая Ваш пост, пока понял, что речь не о p-code. BlackParrot Перед тем, как сменить компилятор... может попробовать написать небольшой корректор, который найдёт все инструкции вида табличных прыжков и позаменяет их? После компиляции останется только этим корректором по программе пройтись. P.S. Интересная, кстати, инструкция "JMP [eax*ecx + offset JMP_TABLE]". Core3Penta уже поддерживает?
l_inc Я раньше использовал термин "шелкод", но это вызывало не верные ассоциации у товарищей, поэтому лучше пикод(Position Independent).
l_inc В общем Clerk все хорошо описал. Лично я пишу дизасм, такой, чтобы можно быть вставить куда угодно в виде дампа байт. В итоге можно использовать и в вирусах, и в инжектах и не привязываться ни к каким форматам OBJ/LIB/etc. Еще одной важной причиной является то, что можно легко сжимать этот дамп, чтобы не тратить лишние байты. В итоге полноценный дизасм 0x86 с совершенно всеми инструкциями (например в CADT префиксных инструкций вообще нет), способный генерить мнемонику, получился весящим 12 килобайт. Хотя вес может вырости немного чуть позже, в финальной версии. Как оказалось задачка не очень простая, в коде было много строк, и пришлось немного подумать как это реализовать. В итоге я почти добился результата, осталась вот эта единственная проблема, которая по сути от меня, как от программиста не зависела, поэтому я удивился от того кода, который сгенерил мой компилятор. Кстати да, тут может быть путаница. Можно предложить называть это "бикод" (bi-code - base independent) чтобы как то различать понятия и быть кратким. Думаю нет, это дополнительный код, смысла нет писать чего-то подобное в моем случае, если есть возможность сделать все без дополнительного кода. В общем случае идея хорошая и она активно используется в разных загрузчиках. Да, тут опечатался. Хорошая наблюдательность! Что-то типо того Код (Text): FFA48100104000 JMP DWORD PTR [ECX+EAX*4+0401000h] cppasm Да, это то, что нужно. В общем думаю попробовать gcc, bcc, intel c++ compiler. О результатах отпишусь, интересно кто лучше сгенерит код.
В итоге Intel отлично справился с задачей, скачал варезный с торрентов. И все запахало, к тому же он неплохо оптимизирует, хотя конечно не без магии -обошлось. Не надо было плясать с бубном - он сам автоматически встраивается в VS2008 и можно его сразу использовать. Это очень большой плюс. GCC в комплекте DevC++ не прокатил т.к. он использует AT&T-асм-синтаксис, а у меня были асм-вставки. BCC вообще странный инлайн-ассемблер имеет, поддерживает только инструкции до 286 включительно. В общем это тоже не подошло. Считаю intel-компилятор наиболее адекватный на сегодяшний момент из всех опробованных. Опций оптимизации там море. И сделан для людей - хотя бы взять ту же опцию по созданию таблиц переходов.