|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июл 1, 2004 22:51:29 Спасибо captain cobalt что подключился и избавил о необходимости сто надцатый раз рассказывать то что уже написано и в обучалках есть. или твой малой на память помнит, что для push (0xff) поле reg должно обязательно равняться шести? Вот само это письмо просто дополнительное доказательство, того о чём я писал про "мифы" и "стереотипы" в отношении опкода у сложившихся программистов. Ребёнку проще объяснять, ему нужно объяснить как есть, а то что как "вы думаете - заблуждение и забудьте пожалуйста про него". Ну миф это, что можно определить всегда по одному байту. Миф и то что определяя когда можно по байту то нужен всегда весь байт. 1. Что уже сказано десятки раз и в десятках обучалок написано. То о чём ты говоришь называется поле codr, а когда пишут поле reg имеют ввиду не поле codr в modrm. ёпрст - если только ленивый не пишет про структуры опкода, но после чтения всё одно читатель поле codr называет полем reg, то эти "неленивые" - ламеры в этом вопросе и можно только добавить, что также только не ленивые учат всех жить, но умеют жить единицы. Нету такого ID кода FF. В ряде опкодов биты ID распологаются в нескольких байтах (я уже с ума начинаю сходить - мне приходится говорить опять о байтах хотя правильно о битовых полях) Вот у тебя FFB418 FF00000>PUSH DWORD PTR DS:[EAX+EBX+FF] ID тут не FF вот посмотри бинарно на два первых байта 11111111 10110 00 Вот жирным выделены идентифицирующие код биты. Они при этом в разных байтах и не подряд идут. Форматы находятся в приложении B.2. (Appendix B) второго тома Intel. У меня в доке которая лежит на сайте, совершенно разжёвано и однозначно этот по крайней мере вопрос объясняется + к тому же есть обучалка в которой показана группа использующая codr как расширение блока ID кода. Всё развалено по полям, выделено цветом, разбито в рамочки есть возможность щёлкать генерируя подобные по формату опкоды. Чего ещё нужно то? Речь что-ли туда добавить или дополнительные мигания? Обучалка называется типа muldiv*.exe Конечно же он знает что формат push с использованием кодирования modrm будет 1111 1111 : mod 110 r/ m Он просто видел формат в доке. А если не помнит - смотрит, только не в описании инструкций а в приложении B где даются форматы. Ему объяснили порядок следования блоков, декодирование и назначение блоков и некоторые исключения. Дальше то сам уже смотрел форматы. Англичане тоже смотрят в словари английские иногда. А как иначе? Как написать "мама" не зная ни буквы а ни буквы эм? На другой вопрос "как определить по байту опкод" - отвечу риторическим вопросом: как определить какое число написано и делится ли оно на три если оно записано как 1x? Где х какая-то десятичная цифра. Вот так же можно определить какой опкод если первый байт FF а другого не знаем. Т.е. никак. Это просто пример что ребёнку проще - ему просто нужно объяснить как это. Взрослому же программисту объясняя как это приходится ещё объяснять, что это не так как он думал, почему это не так как он думал, и ещё слушать вопросы на которые вообще невозможно ответить типа почему какой-нить ляпкин-тяпкин объяснил это по другому. Я из-за этих объяснений прослыл "специалистом по опкоду" хотя я не больший в нём специалист чем специалист формате заголовка EXE или защищённом режиме. Просто изучил формат по мере мелких надобностей, никогда не хотел и не собирался писать ни компиляторов ни дизассемблеров. Однако части декодеров есть в обучалках. Без всяких "первых байтов" :) Весь декодер modrm около 100 байт занял. Поскольку самого меня в семье зовут Глупый Свин за то что я не так быстро всё схватываю, то когда кто-то удивился что и я и мой ребёнок умеют бинарно кодировать, я их пожалел и объяснил поскольку пожалел их как себя изучавшего эти форматы и рассказал языком каким хотел бы чтобы мне рассказали. С тех пор меня записали в специалисты по опкоду и я только этим почти и занимаюсь. Скоро кодировать разучусь. Вобщем никакой я не специалист. Ребята, имейте совесть, есть то что я не описывал типа tttn (хотя есть обучалка) и не написал обучалок по биту s и к примеру использованию эскейп кодов. Но что-то я написал и выложил на сайте, в частности объяснения про использование codr в качестве расширения ID кода - ну это хотя бы прочитайте, а то вопросы об одном и том же. В Hiew кстати упомянутую ошибку по моей просьбе Евгений исправил. Но я обнаружил ещё несколько ошибок, он обещает исправить в новой 7ой. Olly неправильно декодирует кое что из FPU инструкций, давно обещал исправить но всё никак не исправит. |
|
|
Дата: Июл 2, 2004 15:11:40 The Svin В ряде опкодов биты ID распологаются в нескольких байтах (я уже с ума начинаю сходить - мне приходится говорить опять о байтах хотя правильно о битовых полях) Кажется мы говорим об одном разными языками :) Всем тем, что я написал, я пытался сказать о том, о чем ты сказал намного более лаконично и понятно - "...Они при этом в разных байтах и не подряд идут" Мне непонятно только как все это реально закодировать в дизассемблер длин. Классический(табличный) подход - строим таблицы для первого байта, подгруппы 0xff и т.п (так например сделано в borg'e). В этом случае опкоды с полем reg... кхм... codr ;) храйне хреново, точнее вообще не ложатся в эту концепцию, т.к. для них нужен уже не байт, а больше (borg/ida/delphi/hiew на это "больше" забивают). Че делать? можно в таблице завести битовый флаг, указывающий на необходимость проверки поля codr и завести еще отдельную таблицу для codr... можно каждую команду кодировать типа так: - значение первого байта подгруппы (полного) для опкода - маска второго байта (т.е. маска поля codr) - значение второго байта (т.е. поля codr с маской) можно, но с офигенной избыточностью, т.к. команд с codr немного, и городить это только ради них - накладно можно сделать что-то типа арифметического кодирования (тут уже уходим от таблиц), но это геморойно писать вручную. можно сделать в виде таблиц, пускай и с избыточностью, а потом автоматом (отдельной программой) сгенерировать позиционно-независимый код типа арифметического кодирования. можно как-то еще... так как ты мыслишь в этих вопросах ширее меня, я и спрашиваю, как лучше делать? |
|
|
Дата: Июл 3, 2004 12:47:39 · Поправил: The Svin Max Дизассемблер длин, мало чем отличается от просто дизассемблера, по сути это и есть дизассемблер но невыполняющий (игнорирующий) некоторые функции (причём наиболее простые, типа символьных эквивалентов заполняния по одноранговым таблицам) Детально на алгоритмическом уровне объяснить это - это больше чем даже просто написать дизассемблер, это написать дизассемблер и прокомметировать каждую строчку. Я уже сказал в общем что делать - приложение B и самостоятельно сгруппируй по подобию формата. Я бы выбрал общую стратегию такую. Поскольку в разных форматах груп используются схожие блоки. То 1. Я написал бы процедуры которым можно подсовывать эти блоки для декодирования. Самый сложный блок modrm уже выкинут сюда исходником. 2. Для анализа, поскольку получение информации из кода линейно не совпадает всегда со временем когда эта информация понадобится, то я бы завёл внутреннюю структуру флагов. Куда до поры пока не понадобится записывал бы такую информацию типа наличия какого то префикса, значения w и s и т.п. 3. Первая стадия декодирования (можно делать проще с помощью проверки принадлежности по битовой строке) это - префиксы. Ты проверяешь принадлежит ли текущий байт префиксу, если да - увеличиваешь адрес и проверяешь следующий байт и ставишь флаг префикса. 4. Добравшись до байта блока кода ты должен определить к какой группе он относится. И делать это можно по разному. Я бы предложил для начала, поскольку ну противно мне делать такую ПРОСТУЮ работу, зашёл в приложение B и сгруппировал бы по форматам. Тут нет примитивного линейного подхода, если только не делать огромные и тормозные таблицы, которые уже доказано на таком говне как IDA просто глючат и работают страшно медленно и годятся только для анализа примитивных с точки зрения кода программ написанных на ЯВУ. При развале на группы я обратил бы внимание на уникальность бит. И построил бы методом отсечения групп ID. Т.е. если байт кода говорит о том, что это двухуровневая группа - сразу перенаправил бы на анализатор группы. Почему? Поскольку байт признака групп мало - можно быстро проверить по bt на принадлежность к групповому ID и ускорить ветвление по сравнению с примитивным сканированием. Об обработчике групп отдельный разговор, но сначала нужно определить тип формата, и началом определения типа служит определение групповой он (типа 1111111x или другое какое ID группы) Далее пошёл бы опять методом отсечения по старшим битовым полям. Например фомат mov reg,imm 1011wreg imm Проверив старшую тетраду на 1011 уже можно понять принадлежит ли этой группе код и если да -> перейти на процедуру декодирования этого формата. Это не единственная группа которую можно определить по четырём старшим битам. По пяти битам можно определить целую пачку опкодов, за исключением FF (а на неё не должно выйти если группы определяются вначале) идентифицируют 11111 в старших битах. Это формат пачки опкодов которые работают с флагами типа CLD, STD и т.п. Т.е. выделив пять бит можно определить целую пачку опкодов, включая формат не только флагов но и хххххreg таких как push reg, inc reg и т.д. А пять бит это всего лишь 32а значения значит можно опять проверить на принадлежность одной bt reg с битовой строкой множества, reg со сдвинутыми 5ю старшими битами. И т.д. - ясно будет когда сделаешь домашнюю работу по группировки форматов используя приложение B. После определения к какому формату это принадлежит - пересылается процедуре формата. Она вспомогательно вызывает другие процедуры типа декодера mod+memr. Сами такие процедурки (группы) будут очень короткими если все процедурки внутренних блоков будут написаны раздельно. Там очень простые управляющие блоки будут с вызовом подпроцедур декодирования. Почему я настаиваю на раздельных процедурах для каждого формата, у Интел не много но есть исключения и особенности которые трудно (а то и не возможно) обобщить и они связанны с определёнными группами. Например та же 1111111x группа для ряда опкодов трактует последний бит как w а для других он должен быть обязательно 1. Если декодер на такой формат раздельный в нём просто реализовать проверку на исключения. В общем потоке - это очень тяжело. Закончу как я на этом. Для того написать безглючный дизассемблер нужно знать формат опкода, не получится просто стыбрить примитивную схему и вставить. В Hiew один из лучших движков, но и там глюки находились, хотя движок по скорости работы очевидно что правильный. Я повторяю - нет тут возможности написать рассматривая как простое сканирование байт качественного дизассемблирования. Все кто говорил что есть - показать не смогли результат качественный, везде глюки и непонятки. Впрочем я дизассемблеров не писал. Можно конечно у спецов спрашивать. Кстати автор FASM очень быстро исправлял глюки которые я находил в ассемблировании, другие медленней, что скорее всего говорит что там грамотный движок, правильно структурно построенный. Наиболее качественный дизасм из того, что я видел - в SoftIce. |
|
|
Дата: Июл 4, 2004 12:33:30 Edmond Мои комплименты. Дотошно не разглядывал, но сам подход очень радует. А ты говорил, - сложно :) А у самого уже анализ ID детальней чем я тут пишу. Молоток! Ты наше светлое будущее :) О ляпах напишу в приват. |
|
|
Дата: Июл 12, 2004 11:24:32 А ты говорил, - сложно Да, ушла неделя работы. А у самого уже анализ ID детальней чем я тут пишу Это не моя заслуга - просто надо было найти (то над чем Володя смеёться). Вот и нашёл. О ляпах напишу в приват А ты думал я чистовик нахаляву брошу?! Прошло то времячКо. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.045 |