Сейчас на форуме: rmn, Magister Yoda, vasilevradislav, tyns777, zombi-vadim (+6 невидимых) |
![]() |
eXeL@B —› Программирование —› Как программно узнать размер функции написанной на си ? |
Посл.ответ | Сообщение |
|
Создано: 24 августа 2008 22:04 · Поправил: theCollision · Личное сообщение · #1 Я написал ф-цию: Code:
вопрос, как можно узнать размер этой ф-ции для того, чтобы записать ее в файл и юзать уже в коде, который базово-независим ? фишку вроде вроде кода после последнего оператора в ф-ции: Code:
P.S.: Круто выглядит код в теге "код", когда прикрутили ? вроде небыло же ! ;) ----- My love is very cool girl. ![]() |
|
Создано: 24 августа 2008 22:23 · Поправил: Flint · Личное сообщение · #2 что мешает это сделать так: вначале функции вызываешь call $+5 потом pop eax и затем sub eax, 5 получишь адрес начала своей функции, потом jmp на такую же конструкцию, которая будет стоять перед ret получишь адрес конца функции потом джамп в основое тело, там получаешь разницу=размер функции в байтах. Примерно так Code:
----- Nulla aetas ad discendum sera ![]() |
|
Создано: 24 августа 2008 23:02 · Поправил: Azur1d · Личное сообщение · #3 |
|
Создано: 25 августа 2008 00:05 · Личное сообщение · #4 |
|
Создано: 25 августа 2008 04:26 · Личное сообщение · #5 |
|
Создано: 25 августа 2008 09:23 · Поправил: flamer · Личное сообщение · #6 Доброго здоровья! Бр, а в чем беда-то? Ну, кроме оффтопа -- кучи асма? Правила работы с указателями в зубы и задачка решается на ура. Без ухищрений оптимизации компиляторы не меняют порядок следования переменных и функций. Да, они могут выравнивать их на свой вкус, но порядок определяется программистом. Вывод. Определяем функцию ... my_func(...) {} Ее адрес определить - элементарно - один оператор & Определяем следующую функцию ( в примере это - main ) Вычитаем из большего адреса меньший - получаем длинну блока, который компилятор выделил под функцию. Да, в нем может быть хлам за концом функции, но это не страшно. Зная адрес и длинну блока памяти можешь делать с ним, что хочешь. Code:
Ну, и небольшой оффтоп, хотя, вопрос может возникнуть. Внутри "проблемной" функции другие функции лучше вызывать через указатели. Т.е. вначале целевой функции создать указатели на испольуземые функции и использовать их. В чем суть? В упрощенности отвязки кода от месторасположения. В случае, если используемые функции будут в другом месте (например системные вызовы) достаточно (на 32-битках) поменять один дворд, а не перекомпилить функцию. ![]() |
|
Создано: 25 августа 2008 10:03 · Личное сообщение · #7 flamer не согласен =) писал на VC++ 6.0: 1) во первых когда получаешь адресс функции (если на Debug ) то получишь адресс jmp на свою функцию, а не адресс ее начала. 2) почти никогда функции не располагаются друг за другом, это уже причуды компилера. в итоге это сработает только на Release когда код будет малость оптимизирован + можно добавить атрибут static функции. ![]() |
|
Создано: 25 августа 2008 10:04 · Поправил: PE_Kill · Личное сообщение · #8 |
|
Создано: 25 августа 2008 10:09 · Поправил: flamer · Личное сообщение · #9 RSI пишет: не согласен =) PE_Kill пишет: А что мешает вырубить оптимизацию для этой функции? +1 Всё равно, раз функция должна быть переносимой, то ее использование уже не стандартно. Ну отладь ее, да выкуси. (++ пост №6 обновил) Flint пишет: вначале функции вызываешь call $+5 потом pop eax и затем sub eax, 5 получишь адрес начала своей функции, потом jmp на такую же конструкцию, которая будет стоять перед ret получишь адрес конца функции потом джамп в основое тело, там получаешь разницу=размер функции в байтах И если уж идти по пути асма, то кто мешает не геморроиться, а элементарно ипользовать лэблы? ![]() |
|
Создано: 25 августа 2008 11:30 · Личное сообщение · #10 |
|
Создано: 26 августа 2008 03:22 · Личное сообщение · #11 |
|
Создано: 26 августа 2008 11:47 · Личное сообщение · #12 |
|
Создано: 26 августа 2008 13:05 · Личное сообщение · #13 |
|
Создано: 26 августа 2008 14:01 · Поправил: alexey_k · Личное сообщение · #14 пример на борландовском компилере (робит только в Release-билде, на дебаге не прокатит ![]() Code:
далее просто получаем указатель на эту функу (это будед начало), затем ищем строку "whatermark", вычитаем её длинну и получаем адрес конца функи. из иды: Code:
зы ногами не пинать, т.к. имхо PEKill прав, такие вещи на асме пишутся очень просто, зачем себе жизнь усложнять.. но мы не ищем лёгких путей ![]() ![]() |
|
Создано: 26 августа 2008 14:14 · Личное сообщение · #15 alexey_k пишет: правда это .text:00401193 retn ; и это тоже непонятно зачем тут =( стандартная хрень на дельфи ![]() return(0x90909090) компилится, как нистранно в mov EAX,90909090, после сигны ищем первый 0xC3 дизасмом длин это и есть последний retn. В функцию передаем указатель на выходной буфер и все. Я бы так и сделал и не одной строчки на асме, как ты и хотел) ----- invoke OpenFire ![]() |
|
Создано: 27 августа 2008 09:38 · Личное сообщение · #16 |
|
Создано: 27 августа 2008 10:10 · Личное сообщение · #17 |
|
Создано: 27 августа 2008 20:26 · Поправил: theCollision · Личное сообщение · #18 Ice-T Логично ! ;) Думаю даже дизасм-длин не нужен, просто поиск 0xC3 ) Тогда теперь ситуация такая, в конце ф-ции я же могу возвращать нетолько хреновый результат а-ля return(-1) но и зашибись типа return(0) или другой какой важный проге! Если поставлю после последнего ретурна : Code:
Code:
} я бы задал это в макросе и в конце нужных мне ф-ций его вставлял бы! А потом бы написал ф-цию поиска 0x90909090 и потом 0xC3 и копировал бы в файлом без учета B8 90 90 90 90 , а вставлял бы 0xC3 Вот примерно то что я хочу, осталось заставить компиллер MS Visual Studio 2005(8) Team Stuidio это захавать )) Code:
пока пришел к: Code:
----- My love is very cool girl. ![]() |
|
Создано: 27 августа 2008 22:26 · Личное сообщение · #19 На данном этапе у меня: Code:
и получаю: Code:
Но вставляется тело ф-ции без оптимизации! А мне бы хотелось убрать только и только эти самые 0x90... ----- My love is very cool girl. ![]() |
|
Создано: 28 августа 2008 06:34 · Личное сообщение · #20 |
|
Создано: 28 августа 2008 11:09 · Личное сообщение · #21 |
|
Создано: 28 августа 2008 14:07 · Личное сообщение · #22 какая-то странная затея это все. столько уже всего предложили, а что еще нужно? "программно узнать размер функции на си" - мы говорим о функции, в которой нет ни одного CALL или JMP вне функции? Если функция своя-самописаная, к чему это все? Можно перевести в опкод и не морочиться. Если хочется все так оптимизировать, тогда искать по RETN или по сигнатуре. Ведь проект компилится одним компилем, так под него и подгонять! Странная тема вообще ![]() ----- MicroSoft? Is it some kind of a toilet paper? ![]() |
|
Создано: 28 августа 2008 14:40 · Личное сообщение · #23 Tim А подумать ? Для чего еще нужно писать ф-цию написанную на си и в файл ? Да и спрашивать не где нить на форуме по базам данных, а на реверсинге, где большинство тем это крипторы, пакеры, проты и всякая подобная лабудень !!! Видно же что пишется криптор или пакер! Совсем народ думать разучился! >>столько уже всего предложили, а что еще нужно? А чего конкертно-то предложили ? ты вот возьми напиши xGetProcAddress положи ее в peimage.cpp и ни где в проекте ее не используй!!! Т.е. не пиши строк вида: xGetProcAddress(hDll, DllFunc); У меня лично компиллер при построении проекта в exe-шник не ложит то что не используется!!! Т.е. он оптимизирует и думает, раз не юзается,значит нафиг не надо!!! Почему мне это должно нравится ? Вот и возникает вопрос как сделать так чтобы и сохранить оптимизацию ф-ции и чтобы размер можно было получить! Пока пришел к методу, что написал в посте #19. Но тут отключается оптимизация вообще, было бы идеально заставить компиллер не выкидывать ф-цию и оптимизировать, при этом вставляя в конец 0x90909090, но как это сделать ? ----- My love is very cool girl. ![]() |
|
Создано: 28 августа 2008 19:31 · Личное сообщение · #24 theCollision да это понятно, что пишется прот или пакер ![]() просто мне интересно, почему нельзя перевести функу в опкоды и юзать так ![]() ведь эта функция же будет писаться в защищаемый файл и там использоваться?! ![]() ведь как-то писались и пишутся сотни протов и пакеров... ----- MicroSoft? Is it some kind of a toilet paper? ![]() |
|
Создано: 28 августа 2008 20:46 · Личное сообщение · #25 Tim А если я багу в ф-ции допущу ? Поправлю и че опять перекомпилять, опять в бин вид, а потом в виде си ! Это не есть автоматизация процесса, куда правильней задать порядок ф-ций, что я ща и делаю ;))) Есть опция в MS Visual Studio 2005 Team Suite, с названием "/ODER" ему надо дать на вход файлик порядка ф-ций, токо пока не пойму че и как делать ! Если порядок ф-ций будет таким каким я укажу, то логично что можно получить размер по Func2 - Func1 ----- My love is very cool girl. ![]() |
|
Создано: 28 августа 2008 21:03 · Поправил: theCollision · Личное сообщение · #26 Все, вроде как победил ))) Опишу действия, которые касаются MS Visual Studio 2005 Team Suite: 0. Делаем пробную компиляцию и ищем obj main.obj файл и юзая dumpbin /symbols получаем имена ф-ций, которые записываем в файл func_order.cfg в том порядке каком хотим! 1. В опциях проекта, для обеих версий и дебаг и релиз ищем Linker->Optimization->Funcion Order в него прописываем наш файл @func_order.cfg, также не удаляем COMDATs тамже ключик по выше! >>COMDAT record запись в формате COFF , содержащая инициализируемый общий блок данных и делающая упакованные функции видимыми для компоновщика 3. В хидере cryptor.h к примеру пишем макрос: Code:
4. Пишем еще одну ф-цию: Code:
5. Дожидаемся полнолуния 6. Компилем, результат храним в надежной от затирания файла ! ----- My love is very cool girl. ![]() |
![]() |
eXeL@B —› Программирование —› Как программно узнать размер функции написанной на си ? |