eXeL@B —› Программирование —› Ревёрс шаблонов с++ |
Посл.ответ | Сообщение |
|
Создано: 24 апреля 2012 12:44 · Личное сообщение · #1 Добрый день. Я вот помаленьку копаю движок сталкера Xray 1.6.0.2 Меня в нём заинтересовала скриптовая машина, а именно добавление туда функций и классов(прикручен туда luabind). Всё было бы хорошо, но luabind видоизменён(операции с памятью все делаются через специальный класс(видимо разработчики столкнулись с утечкой памяти и решили проблему перегрузкой всех new и delete)) Так вот. Меня интересует ревёрс шаблонов в С++. Там заменён стандартный std::auto_ptr на ихний. Впринципе ничего нового в реализации самой машины я не заметил. Только операции с памятью там изменены(выделение/освобождение). Имел ли кто - нить опыт в ревёрсе шаблонов и знает ли кто-нить как глобально перегрузить оператор new(знаю можно чисто в классе перегрузить, но возможно ли совсем глобально это сделать?) Сразу прошу меня извинить за возможные грамматические ошибки и написание "не по-русски". |
|
Создано: 24 апреля 2012 13:14 · Личное сообщение · #2 |
|
Создано: 24 апреля 2012 13:56 · Личное сообщение · #3 |
|
Создано: 24 апреля 2012 14:11 · Личное сообщение · #4 Dart Sergius пишет: а структуру класса оно не сильно изменит? Может сильно. Подабавляется в потомках то, чего не было в предках. И не влияют ли "предки" на декодированное название функции потомка? Хз. ----- Stuck to the plan, always think that we would stand up, never ran. | Сообщение посчитали полезным: Dart Sergius |
|
Создано: 24 апреля 2012 14:41 · Поправил: Hexxx · Личное сообщение · #5 Dart Sergius пишет: знает ли кто-нить как глобально перегрузить оператор new Мы для драйверов делали так: Code:
и operator new[] аналогично Не вьехал как это связано с реверсингом шаблонов. С шаблонами проблема в том что у тебя в коде 100500 классов, некоторые из которых похожи друг на друга как 2 капли воды и отличаются лишь каким-нить одним параметром. Т.е. инстансы для кучи типов, а код - копипаста. ----- Реверсивная инженерия - написание кода идентичного натуральному | Сообщение посчитали полезным: Dart Sergius |
|
Создано: 24 апреля 2012 14:46 · Поправил: r_e · Личное сообщение · #6 Dart Sergius Если не ошибаюсь, new и delete можно переопределить глобально. Нужно просто объявить функции с определенным прототипом. Погугли. Собсно, что касается шаблонов, то нужно понимать что все они инстанцируются с заданными типами. В итоге мы получаем кучу кода с одинаковой логикой и различными типами данных. По идее, для auto_ptr это некритично, потому как будет ли поле указателем на int или на CObject не играет никакой роли. Структура от этого не поменяется ни на байт. Hexxx Обошел на повороте ----- старый пень | Сообщение посчитали полезным: Dart Sergius |
|
Создано: 24 апреля 2012 15:16 · Поправил: Dart Sergius · Личное сообщение · #7 |
|
Создано: 24 апреля 2012 16:42 · Личное сообщение · #8 Dart Sergius Шаблоны реверсятся в С++ так же, как и всё остальное, но если ты в результате хочешь получить один шаблон, а не кучу "полуодинакового" кода на все инстанции, то анализируй одноименные функции по всем инстанциям и оформляй в шаблон, при некоторой сноровке ничего в этом сложного нет... В принципе, по желанию, ты можешь в любом std шаблоне заменить реализацию шаблонных параметров на свою, будь она внешней или внутренней, как Allocator, Hash, Comparator и другие. ----- Everything is relative... |
|
Создано: 08 мая 2012 23:10 · Личное сообщение · #9 r_e <<Собсно, что касается шаблонов, то нужно понимать что все они инстанцируются с заданными типами. Забавную чушь Вы пишете О non-type параметрах не слышали видимо никогда? Вообще то у шаблонов С++ существует 3 разновидности параметров: type parameter, non-type parameter и template parameter. Non-type параметры типами не инстанцируются -> Ваше высказывание ошибочно. C++ Templates the Complete Guide by David Vandevoorde and Nicolai M. Josuttis. |
|
Создано: 08 мая 2012 23:32 · Личное сообщение · #10 Товарищи. Я тут недавно класец для себя маленький сваял. А так как для себя писал, то соответственно нет ревизии кода и тому подобных вещей. Вообщем хотелось бы, чтобы Вы его покритиковали и высказали свои замечания. В первую очередь интересует оптимальность кода - может Вы лучше варианты увидите. (язык: C++) Если хотите взглянуть на творчество, то отпишите - покажу... |
|
Создано: 09 мая 2012 01:17 · Личное сообщение · #11 TheNozza Вы чисто потролить или с целью померяться? В RE вы не встретите compile-time calculations / MPL в бинаре, потому как вкомпиленно будет именно предрасчитанное компилятором значение. В остальных случаях будет таки либо создан тип / объект, либо сгенерирован код. Что и следовало понимать под странным словом инстанцирование. Я даже близко не MVP в С++ и всегда открыт для плодотворной дискуссии. Вы можете просветить меня насчет non-type template parameters в реверсе и как они выражаются в скомпиленном коде. Открою для себя новый мир. ----- старый пень |
|
Создано: 09 мая 2012 01:34 · Личное сообщение · #12 |
|
Создано: 09 мая 2012 01:43 · Личное сообщение · #13 "В RE вы не встретите compile-time calculations / MPL в бинаре, потому как вкомпиленно будет именно предрасчитанное компилятором значение. В остальных случаях будет таки либо создан тип / объект, либо сгенерирован код. Что и следовало понимать под странным словом инстанцирование." Зачем рассказывать то, о чём и так известно? Зачем слэш добавили(тип/объект) - чтобы съехать? Читайте ещё раз внимательней свою первоначальную фразу, она была некорректной - вы её написали, а не я: <<Собсно, что касается шаблонов, то нужно понимать что все они инстанцируются с заданными типами. Про объекты(Instance of the class) там речи не было, только о типах. For example: template<int i> class C { public: int k; C() { k = i; } }; class C<100>; Пример, когда шаблон инстанцируется не типом, а конкретным значением 100. Это non-type параметр. Это не тип. Высказывание было некорректно. Но потом Вы поправились. |
|
Создано: 09 мая 2012 01:56 · Личное сообщение · #14 |
|
Создано: 09 мая 2012 02:35 · Личное сообщение · #15 Code:
Предлагаю обсудить недостатки и преимущества кода данного класса. В нем я реализовал функционал счётчика с целью перебора произвольного алфавита(задаётся в рантайме) на любую глубину(задаётся в рантайме). В последний момент STL-евый vector был заменен на обычный массив с целью увеличения производительности, соответственно клиент класса берёт на себя ответственность при вызове operator[], т.к. выход за пределы массива более не контролируется. Вопрос: имеются ли более оптимальные пути? Кому надо, те поймут, остальным не обязательно. |
|
Создано: 09 мая 2012 11:00 · Личное сообщение · #16 |
|
Создано: 09 мая 2012 11:46 · Личное сообщение · #17 хм, у меня проблема возникла ещё с ревёрсом самого оператора new. Кароче есть такой код: Code:
в с++ он выглядит так насколько я понял: void* hz(void*ptr,void*size){ return luabind::allocator(luabind::allocator_parameter, (const void*)ptr, size); }; на что компилер мой генерит Code:
Валится от того что void * (*luabind::allocator)(void *,void const *,uint) указывает на область памяти, которая недоступна для выполнения. Мб там указатели на функции, а я пытаюсь вызвать сами функции? Как мне лучше это написать? Или во время инициализации dll своей прописать типо luabind::allocator=(void __cdecl*(void*,void const*,uint))(*luabind::allocator) |
Ранг: 419.0 (мудрец), 647thx Активность: 0.46↗0.51 Статус: Участник "Тибериумный реверсинг" |
Создано: 09 мая 2012 12:10 · Личное сообщение · #18 |
|
Создано: 09 мая 2012 12:13 · Личное сообщение · #19 r_e <<и заканчивая UB UB возможно при вызове operator[]. Предположим идёт полный перебор 32-битного числа (Radix=2, Resolution=32). Если контролировать выход индекса за границы массива, то дополнительно будет сделано более, чем 2^32 степени ненужных сравнения, когда со стопроцентной вероятностью известно, что в клиентском коде индекс за границы не выходит. Тут выбирать приходится: либо безопасность, либо скорость. Ну и конечно раз вместо вектора теперь динамический массив, то деструктор добавить нужно, иначе memory leak. |
|
Создано: 09 мая 2012 12:14 · Личное сообщение · #20 ELF_7719116 символы как то надо нормально экспортнуть. luabind::allocator_parameter и luabind::allocator экспортированы из другой dll. есть вариант конечно попробовать посмотреть исходные значения в olly(ida тяжко перебазирует 7-ми метровый dll), и сравнить с значениями, которые получаются у меня в программе. |
|
Создано: 09 мая 2012 12:44 · Личное сообщение · #21 |
|
Создано: 09 мая 2012 13:22 · Личное сообщение · #22 хм, я кажется понял что у меня неверно было. у меня на extern он генерит странный код. Как я понимаю, загрузчик просто заполнит мою переменню, и всё. Но компилер делает по другому. Он досоздаёт переменную __imp_?allocator@luabind@@3P6APAXPAXPBXI@ZA_0 которую и заполняет как я понял загрузчик Windows. и в адрес моей переменной пихает указатель на jmp. Появляются 2 лишних байта(jmp). Как это бы обойти? |
|
Создано: 09 мая 2012 13:41 · Личное сообщение · #23 TheNozza hint: UB из-за этого if (++Index == _Resolution) Я user-case'ы даже не рассматривал. А также в студии: - Отсутствие деструкора - утечка памяти. Неиспользование smart pointers. - Непроверка критических участков с бросанием эксепшнов. - Неконстантные функции, возвращающие константы. - Неоптимальная упаковка данных. Чо уж тогда тип элемента счетчика не сделать параметром шаблона? - Постфиксные инкременты - Нестандартное поведение перегруженного инкремента - Дизайн нерасширяем - Для данного кода в конструкторе достаточно было вызвать Reset - Множественные perfomance issues, например: >> for (int i = 0; i < _Resolution; i++) _pCurrentValue[i]=0; memset() для линейного непрерывного пространства, for_each для итераторов >> std::string asString() Передача объекта через стек. Вывод: наколенная школьная поделка. ----- старый пень | Сообщение посчитали полезным: redlord |
|
Создано: 09 мая 2012 14:28 · Личное сообщение · #24 |
|
Создано: 09 мая 2012 15:08 · Личное сообщение · #25 r_e <<UB из-за этого if (++Index == _Resolution) При каком сценарии здесь возникнет UB? (последовательность вызова интерфейсных методов) <<Отсутствие деструкора - утечка памяти. Да, это косяк. <<Неконстантные функции, возвращающие константы. Не критично. Хотя можно поправить. <<Неоптимальная упаковка данных. А вот это непростой вопрос. Думал над ним. Упаковка данных действительно неоптимальная. Концепция была следующая: есть алфавит, например из трёх букв 'a','b','c'. Нужно перебрать все варианты слов из пяти букв данного алфавита. Задаём счётчику: Radix = 3; Resolution = 5; После каждого инкремента счётчика пока !Overflow() через operator[] запрашиваем все цифры и отображаем их на символы алфавита. То есть: 00000 -> aaaaa 00001 -> aaaab ......................... 22222 -> cccccc У Вас есть другие варианты? <<Чо уж тогда тип элемента счетчика не сделать параметром шаблона? С какой целью? Элементы счётчика всегда цифры. <<Постфиксные инкременты Его можно реализовать на базе префексного. Главное добиться оптимальности кода префексного оператора. << std::string asString() <<Передача объекта через стек. Так возвращается из метода временная переменная. Вообщем обсуждать надо... |
|
Создано: 09 мая 2012 15:21 · Личное сообщение · #26 TheNozza UB> DigitalCounter l(1, 1); for (int i = 0; i < 0xffffffff; ++i) ++l; > С какой целью? Элементы счётчика всегда цифры. Это могут быть ну очень большие цифры. И тогда вашего int просто не хватит. > Его можно реализовать на базе преф Не только можно, но так и реализуется. Это классика. Соответственно, постфиксный используется только там где неприменим префиксный. > Так возвращается из метода временная переменная. Чего уж тогда не перегрузить оператор вывода в поток? Было бы вполне в с++ стиле. Собсно, чо тут обсуждать? Поумерь ЧСВ и неси в мир доброе и светлое нормальным тоном. ----- старый пень |
|
Создано: 09 мая 2012 16:36 · Личное сообщение · #27 r_e Давайте взглянем на более глобальные вещи: а именно на применённый алгоритм. Возможно, такой счётчик (со свойственной ему рекурсией) для брутфорса вариант неподходящий. Вам знакомы другие алгоритмы? Может на базе дерева существует шанс выполнить тот же перебор в более короткий срок? А может и нет. Что думаете? |
|
Создано: 09 мая 2012 16:44 · Личное сообщение · #28 |
|
Создано: 09 мая 2012 17:19 · Поправил: Dart Sergius · Личное сообщение · #29 TheNozza, ща придёт Archer и скажет про кнопку "правка". где-то в сети пробегало решение вашей задачи, но где я уже не помню. И вы не знаете как решить мою проблему? Как мне импортировать нормально без jmp, который вставляет компилятор? Проблема решилась return allocator(&allocator_parameter, (const void*)ptr, size); тупо передал адрес нашего jmp =) |
eXeL@B —› Программирование —› Ревёрс шаблонов с++ |