Здрасти. Необходимо определить начала всех процедур, тоесть всего кода, после компиляции. Каким образом это можно сделать, откуда извлечь инфу(.map, obj etc). Причём константы в секции кода это не код. mapfile сомнительно. Такое вообще возможно ? obj.IMAGE_SYM_DTYPE_FUNCTION видимо нужное, но формат не прост.
Фантазию включать разрешается? - можно прочесать весь дамп в поисках начал процедур, характерных для ЯП (ЯВУ) - можно прочесать дамп, собирая все CALL'ы, и потом смотреть куда они "смотрят" - это либо п.1, либо место после POP'ов + RET, и возможно это начало новой процедуры , вроде такими путями обычный дизассемблер при составлении листинга поступает.
Отпишусь здесь. Нашел такую вещь http://www.jakstab.org/ вот презентация http://seminaire-dga.gforge.inria.fr/2012/20130419_JohannesKinder.pdf Как говорится, для тех, для кого это может представлять интерес.
TermoSINteZ Студия например. В общем для обработки апликухи(чтобы запротектить, но не суть важно) нужно выделить её код, тоесть начала всех процедур. Для этого нужно использовать инфу компилера. Вот оказывается в map содержится не только код на сколько помню, а экспорт в целом. Поэтому если туда попадёт переменная, а она не есть код, то всё сломается. Лучший способ это скомпилить с CFG картой, хотя туда тоже не всё включается. Хотелось бы найти метод общий, который можно применить к бинарю, но видимо это невозможно.
есть например так называемые AST в llvm (+ clang) . наверно это то что вы ищите. Он может генерировать нужные графы и вы сами можете что либо с ними делать . llvm это считайте некоторый frontend . вы подаете ему на вход сишечку (а ваще можно че угодно подавать по факту, если создать свои словари и проч) и он вам этот сорец парсит и строит дерево. посмотрите тут
TermoSINteZ, Мне не нужны графы. А простой и надёжный способ. И сурец исходный может не именно на сишке быть.
Как вариант распарсить OBJ файл, добраться до таблицы символов, извлечь элементы с типом IMAGE_SYM_DTYPE_FUNCTION. Правда не знаю всегда ли оно корректно заполняется.
Какое то противоречие. Я не думаю, что у вас в модуле имеются константы и переменные в секции кода. Для этих целей студия создает доп. секции. Большиству протекторов (vmprot и иные) вполне достаточно map файла. Да я и сам написал протектор с ВМ. И мне тоже вполне хватает информации из map файла.
Согласен map файла вполне должно быть достаточно, функции помечаются обычно символом f, так что можно со стопроцентной уверенностью покрыть каждую ф-ю (см. пример) Код (Text): 0000:00000000 ___ImageBase 00400000 <linker-defined> 0001:00000000 __enc$textbss$begin 00401000 <linker-defined> 0001:00010000 __enc$textbss$end 00411000 <linker-defined> 0002:000013a0 ??0List@@QAE@XZ 004123a0 f List.obj 0002:00001410 ??0ListEntry@@QAE@XZ 00412410 f List.obj 0002:00001490 ??1List@@QAE@XZ 00412490 f List.obj 0002:00001570 ??1ListEntry@@QAE@XZ 00412570 f List.obj 0002:00001610 ??_GListEntry@@QAEPAXI@Z 00412610 f i List.obj 0002:00001680 ?AppendTail@List@@QAEXPAVListEntry@@@Z 00412680 f List.obj 0002:00001700 ?Attach@ListEntry@@QAEXKPAE@Z 00412700 f List.obj 0002:00001760 ?CopyTo@ListEntry@@QAEXPAEKPAK@Z 00412760 f List.obj 0002:00001820 ?DataLeft@ListEntry@@QBEKXZ 00412820 f List.obj
Cмотрите, вы писали Далее в топике вы упоминали map и cfg карту, следовательно под компиляцией вы имеете ввиду именно компиляцию + линковку. Отсюда логический вывод что вы хотите обрабатываеть бинарь, а не obj файлы. Далее вы пишите Но это не так, все функции бинаря(приват, экспорт), данные и прочие регионы бинарного файла описываются map файлом, мало того каждая функция помечается флагом f, следовательно если вам данные не нужны, то пропускайте при парсинге все строки без флага f, смотрите пример выше. Правда линкер может вставлять код который не описывается в map, например таблица jump'ов incremental linking table <c>, но обычно это юзается только в дебаг сборке и все эти jmp лежат в начале кодовой секции, это не проблема вычеслить. Далее map даёт больше инфы чем CFG карта, разве нет?
Посмотрел несколько OBJ файлов сгенерированных C++, VB6, несколько файлов из WDK. Все функции имеют тип IMAGE_SYM_DTYPE_FUNCTION, константы и переменные не имеют этого атрибута. Если требуется только считывать данные из файла, то парсер довольно-таки простой получается, оффсет то символьной таблице хранится в заголовке.
Для более-менее сносного покрытия нужно комбинировать. Список адресов функций дает опорные точки, от которых уже строится CFG.
JKornev, > map даёт больше инфы чем CFG карта, разве нет? Нет, могу вам привести реал пример, когда весь код нэйтива выделяется через CFG и ребилдится в буфер.
Вот нашёл вам немного инфы: Видос и семпл, как выполняется ребилд всего кода в модуле через CFG: https://yadi.sk/i/5kaYg6STw9drt На счёт семпла не уверен(на ядиске их сотни по этой теме) https://yadi.sk/d/plsdUoIHw6ery Тут моя тема тоже с семплами https://exelab.ru/f/index.php?action=vthread&forum=6&topic=24488&page=0#17 Но вы что то из подобного провернуть не сможите - у вас нет конструктора