Может кто когда-нибудь пытался написать небольшой дизассемблер ? Есть описание форматов инструкций, опкодов и т.д. Хотелось бы узнать сам алгоритм (вопрос также относится к быстродействию и определению защиты от дизассемблировани). Может также у кого-нибудь есть готовые структуры данных для облегчения ? З.Ы. Если есть, то можно ссылочку на разбор алгоритма и т.п. Спасибо
z0mbie тебя просветит - это факт Если ты о быстродействии дизассемлирования инструкций, то это происходит почти мгновенно, другое дело анализ надизасембленного это достаточно долго притом что без использования эмулятор качество листинга очень низкое. Можешь глянуть сюда http://wasm.ru/forum/index.php?action=vthread&forum=5&topic=6618 это первые две версии моего кривого движка Сейчас замочу парочку багов и выложу третью версию с примером использования (бинарный дизассемлер 32бита)
Все дело в том, что у меня есть описание инструкций, опкодов и т.д. Но я не знаю с чего начинать. Я понимаю, что необходимо начинать проверку на префиксы. А если их не один ? Просто хочу Вас попросить привести сам алгоритм разбора. З.Ы А вообще кто-нибудь пытался создать совместный дизасм с обсуждением на форуме - может из этого вышло бы что - нибудь оригинальное (а то посмотрев многие исходники приходишь к выводу, что все пишут одно и тоже, изобретая велосипед) З.Ы.Ы. Кстати, а почему дизассемблирование ведется побайтово. Ведь процессор - это ведь в своем роде конечный автомат (или он тоже ведет разбор побайтово ?) Если нет, то можно попытаться смоделировать его работу - это будет намного быстрее.
Я это делал так: прописывал все инструкции по номерам потом тип адресации а потом регистры - это все уже побитно (в одном байте много чего закодировано). Для двухбайтных инструкций сначало распознается первый байт а потом сама инструкция - кобинация байтов всегда устойчива. Самое сложное это вызовы и переходы по регистрам (ер. сall [edx], jmp eax и.т.п). Да и обычные условные переходы тоже создают много неудобств. Т.к. я стараюсь дизасмить по ходу исполнения программы бо код может изменятся - ер. самомодифицирующиеся. Вот тебе куски моего самодельного дизасма для примера Код (Text): sub eax,eax lodsb mov edx,opcode[eax*4] call edx ret ....... modrm: sub ebx,ebx lodsb mov bl,al shr al,6 mov operand_size,putOpSize mov edx,addressing[eax*4] mov eax,offset _reg_ call edx ret modrmb: sub ebx,ebx lodsb mov bl,al shr al,6 mov operand_size,putOpSizeb mov edx,addressing[eax*4] mov eax,offset _regb_ call edx ret m_a: mov eax,moff32 mov [addr_type+20],eax mov [sib_base+20],eax call m_ call dword ptr [edx] mov byte ptr [edi],']' inc edi ret ............... ................ m_: sub edx,edx mov dl,bl shr dl,3 and dl,7 shl dl,2 call operand_size add edx,offset addr_typ ret m_a: mov eax,moff32 mov [addr_type+20],eax mov [sib_base+20],eax call m_ call dword ptr [edx] mov byte ptr [edi],']' inc edi ret mb_a: mov eax,ebp_a mov [addr_type+20],eax mov [sib_base+20],eax call m_ call dword ptr [edx] mov byte ptr [edi],'+' inc edi push [esi] call hex4outb mov byte ptr [edi],']' inc edi add esi,2 ret .......... add_rmb: mov dword ptr [edi],' dda' add edi,4 call _rmb ret add_rm: mov dword ptr [edi],' dda' add edi,4 call _rm ret add_rb: mov dword ptr [edi],' dda' add edi,4 call _rb ret add_r: mov dword ptr [edi],' dda' add edi,4 .......... _rmb: call modrmb mov edx,offset __regb call regb ret _rm: call modrm mov edx,offset __reg call reg ret _rb: mov edx,offset regb__ call regb call modrmb ret _r: mov edx,offset reg__ call reg call modrm ret ........ .data opcode dd add_rmb,add_rm,add_rb,add_r,add_accb,add_acc,push_es,pop_e........ addressing dd m_a,mb_a,md_a,reg_a .................... sib_base dd eax_a,ecx_a,edx_a,ebx_a,esp_a,0,esi_a,edi_a sib_index dd eax_p,ecx_p,edx_p,ebx_p,nema_,ebp_p,esi_p,edi_p Это начальная часть проги, а вообще дизасм это очень имхо сложная задача.
Эх, бездельники, Свина на вас нету. Он бы показал, что здесь вам не тут и как сапоги на пьяную голову одевать. zzzyab - ассемблер на принципе таблиц - это сакс. Мне лень искать, но где-то на форуме Свин высказал все, что думает по этому поводу. zss Ты не мучься - ты движок от OllyDbg возьми. На сайте автора лежит. В движке Свин копался - поэтому движок вроде ничего будет!
Я нашел тему svina про динну команд (в нее еще вникнуть надо), а также посмотрел _15056069__486dis_c.zip и дизасм с z0mbie.host.sk. Эти дизасмы на С да еще там куча case`ов и if-else`ов, и таблица присутствует - покажите мне без сase`овый код, - короче таких валом в сети были бы хорошие не брался бы за разработку своего. Я дизасмлю по ходу, пока полностью не расшифруюется инструкциюя и ее длинна включая и префмкс следующия не начинается, и условные переходы имхо это тормознуто. Читайте статью с таблицами по дизасму (имхо она отличная, я с помощью нее и начал разработку). Автор К. Касперский -ищите в сети.
Читайте статью с таблицами по дизасму (имхо она отличная, я с помощью нее и начал разработку). Автор К. Касперский -ищите в сети. Не Касперский, а Касперски. Касперский - это Евгений Далее, Крис в той таблице наделал туеву хучу ошибок. Свин ее очень жестоко распинал. Если я тебя правильно понял - то вот документ: http://www.wasm.ru/docs/1/DisassembingErrata.zip Edmond постил сюда таблицу с декодированными опкодами. Свин отнесся к таблице куда более благожелательно. Хотя, сказал, что ошибки есть и там. Еще раз предлагаю взять движок Olly.
Таблицы - это все конечно хорошо (удобнее). Но ведь у процессора нет никаких таблиц Он все делает на лету. Так вот хотелось бы такой же алгоритм придумать. Как вариант (я уже об этом говорил) создать некий конечный автомат и подавать ему на вход код. Мне кажется, что в этом случае будет выигрыш во многом (как минимум в производительности) Или я не прав ?
2 zss Боюсь, что да На самом деле для программной реализации конечных автоматов (КА) используется в основном два метода - таблицы состояний либо дикая мешанина if/switch-case/goto и т.п. Дизассемблер x86 можно моделировать КА (да это и есть КА в конце концов), но при реализации от вышеупомянутых методов никуда не денешься. А как процессор "в железе" декодирует инструкции - это уже другой вопрос
zss >Таблицы - это все конечно хорошо (удобнее). Но ведь у >процессора нет никаких таблиц Он все делает на лету. >Так вот хотелось бы такой же алгоритм придумать. Чем такой дизассемблер по твоему круче будет, быстрее? или это уже эмулятор? я непойму zzzyab >Эти дизасмы на С да еще там куча case`ов и if-else`ов, и >таблица присутствует - покажите мне без сase`овый код Без таблицы if`ов ваше немеренно станет >Я дизасмлю по ходу, пока полностью не расшифруюется >инструкциюя и ее длинна включая и префмкс следующия не >начинается А все остальные наугад длину определяют? Другое дело что весят нехило или использовать неудобно, а модифицировать тяжело
ни... не понимать по рюсски. Че ваше? "неменренно" - это "не измеренно" или "много" ? Я думаю регистровый сall\jmp лучше case\elseif. Мне не нравится что они дизасмят все подряд без перебора (особенно запакованые данные), а мне надо по ходу исполнения - если что всегда додизасмть можно. WinDasm отличная прога конечно, но она делает не АСМ файл а гониво своего стандарта.Вот я хочу сфарганить что-то типо,но с АСМ файлами. volodya http://www.wasm.ru/docs/1/DisassembingErrata.zip (дя и iczelion) в идиотскои стандарте сhm - обломно, я не знаю как его переделать. Пожалуйста, где оно есть в нормальном текстовом (или хтябы pdf) виде.
zzzyab Идёшь на сайт http://yarix.by.ru/ берешь прогу htm2chm декомпилишь chm и получаешь вместо chm кучу html
А что плохого в таблицах? (ведь речь идёт о таблицах инструкций или нет?) Такой вариант реализуется легко и красиво. И работает достаточно быстро: на моих 1533 MHz опредление длины инструкции - ~40 мс на Мб кода, декодирование - ~70 мс/Мб. Кому интересно, в аттаче выдержки из моего кода (самой таблицы инструкций там нет; поддержка только до PII, но это не суть важно). 1654135354__dasm.txt
>>„Без таблицы if`ов ваше немеренно станет“ ни... не понимать по рюсски. Че ваше? "неменренно" - это "не измеренно" или "много"? Много. Тоесть придется декодировать каждый опкод, или схожую группу опкодов, примерно так как это сделанно здесь http://z0mbie.host.sk/disasm.txt Только вот для дизассемблера, такой информации бутет явно недостаточно >>„А все остальные наугад длину определяют“ Мне не нравится что они дизасмят все подряд без перебора особенно запакованые данные), а мне надо по ходу исполнения - если что всегда додизасмть можно. Хм... нутак в чем проблема, распакуй данные, а потом их дизассемблируй >>WinDasm отличная прога конечно, но она делает не АСМ файл а гониво своего стандарта.Вот я хочу сфарганить что-то типо,но с АСМ файлами. Я думаю,если напишешь конвертор из WinDasm формата в нужный тебе формат, потратишь намного меньше нервных клеток и времени
Письма к Крису есть и просто текстом в разделе BOOKS. В разделе "Образовательные программы" есть обучалки и статьи. Не все вопросы там освящены но хоть что-то. На форуме есть декодер modrm с исходниками и тестовой программой. Там даже преобразование имён регистров из кодов регистров делается без прямого табличного метода. Дело не в том, чтобы полностью отказаться от табличного метода, а чтобы дешифратор декодировал хотя бы "общие поля". Вобщем так много уже сказано, что добавить в обычном режиме "болтовни" нечего, нужно дополнительные статьи писать, которые в конечно счёте должны вылится в некие обобщения - полные алгоритмы декодирования. Сейчас некогда, рецензирую книжку по прикладной логике. Здесь кстати есть ребята которые понимают в декодировании "общих полей" не хуже меня. Уступаю им слово