| Сейчас на форуме: bartolomeo, -Sanchez-, morgot, sashalogout (+4 невидимых) | 
| eXeL@B —› Софт, инструменты —› MUltimate Assembler | 
| << . 1 . 2 . 3 . 4 . 5 . 6 . 7 . >> | 
| Посл.ответ | Сообщение | 
| 
 | 
Создано: 14 сентября 2009 09:42 · Поправил: BoRoV  · Личное сообщение · #1 Плаг для ольки, позволяющий добавлять/заменять в дизасме и соответствено в проге асм код даже выходящий за пределы если он вставляется посреди имеющегося кода, при этом все адреса у call, jcc, и прочего пересчитыются с учетом этой новой вставки. // З.Ы. Было пять скринов пошаговой инструкции его использования, но автор почему-то их удалил // З.Ы.2. Автор с россии, а че прошел мимо нас... хз v.0.1 Первый релиз, в нем было несколько багов v0.2 - Supports data disassembling and assembling as a C-style string. - Suggests you to create a backup before disassembling, so that the modifications will be visible. - Help added. - Minor fixes. v.0.3 - Disassembles external jumps and calls. - Added an options dialog. - Fixes a couple of crashes. - A right click menu to make LCF-AT happy That's all, I've completed my ToDo list Кажется все он пофиксил, т.к. все говорили что те баги что были пофиксены rammichael.com/ ----- Лучше быть одиноким, но свободным © $me ![]()  | 
| 
 | 
Создано: 18 октября 2012 11:05  · Личное сообщение · #2  | 
| 
 | 
Создано: 20 октября 2012 00:42  · Личное сообщение · #3 RaMMicHaeL Огромное тебе спасибо за прекрасный инструмент. Я с ним очень много работаю при распаковке программ и восстановлении обфусцированного кода (EXECryptor, Themida, и некоторые самопальные обфускаторы). При работе с файлами EXE все идет прекрасно, а вот при работе с DLL - имеются трудности. Например, я столкнулся с одной DLL, в которой имеется одна подпрограмма, часть которой сильно обфусцирована с применением массы инструкций PUSH/RET. Все эти инструкции PUSH обработаны с помощью таблицы релоков, чтобы получить валидные адреса. Я деобфусцировал код, привел его в читабельный вид, а далее мне нужно было вставить этот код на место обфусцированного кода. Поскольку нужно было переделывать таблицу релоков к изменившемуся коду, я запустил специальный скрипт, и с помощью родной таблицы релоков убрал привязку адресов к имеющемуся ImageBase, чтобы сдампировать программу. Однако восстановленный код, с помощью твоего инструмента, был привязан к ImageBase загрузки DLL. И мне пришлось вручную править все адреса и константы в восстановленном коде, чтобы получить нормальный дамп программы. Было бы очень неплохо иметь возможность в твоем инструменте, при необходимости, указывать нужный адрес привязки, чтобы плагин сам записывал имеющиеся константы и адреса с указанной пользователем базой. Это бы намного облегчило работу, когда приходится править вручную большое количество адресов. ![]()  | 
| 
 | 
Создано: 20 октября 2012 01:54 · Поправил: Konstantin  · Личное сообщение · #4  | 
| 
 | 
Создано: 22 октября 2012 15:26  · Личное сообщение · #5 vnekrilov пишет: А можно ли сделать параллельно файл справки и на русском языке? Можно, разрешаю ![]() KingSise пишет: неплохо было бы добавить меню "хэлп" из главного окна, тем более хелп имеется. Ну или по ф1 Оно есть в меню Plugins. vnekrilov, Konstantin Я не совсем понял. То есть, хочется для RVA адресов самому задавать ImageBase? Почему не подходит использование имени модуля? ![]()  | 
| 
 | 
Создано: 22 октября 2012 16:25 · Поправил: Konstantin  · Личное сообщение · #6 RaMMicHaeL пишет: То есть, хочется для RVA адресов самому задавать ImageBase? Да. RaMMicHaeL пишет: Почему не подходит использование имени модуля? Потому что к нему привязана конкретное значение ImageBase. А хотелось бы другое в пределах этого же модуля. Вся эта суета нужна чтобы сделать новую таблицу релоков, а для этого требуется два дампа длл с разными ImageBase. Может быть это всё и лишнее. Уже достаточно наличия дизасма с RVA. (нужно только несколько раз перезагрузить длл в оле чтобы ImageBase был разный). Но иногда проще воспользоваться скриптом для пересчёта адресов(с использованием старой таблицы релоков) и вот в этом случае хотелось бы иметь возможность самому задать значение ImageBase для адресов правленного кода. Может сделать что-то типо команды, например, set_ImageBase.Name=1000000, а далее уже пользоввать - $Name.1234 и т. д. В таком случае можно использовать в качестве Name не только имя реального модуля, но и имя заданное в этой команде - Set. ![]()  | 
| 
 | 
Создано: 22 октября 2012 16:45 · Поправил: vnekrilov  · Личное сообщение · #7 RaMMicHaeL пишет: Почему не подходит использование имени модуля? Попробую объяснить на примере. Имеется DLL, скомпилированная по ImageBase - 400000. При загрузке DLL в отладчик используется файл LOADDLL.EXE, который сам грузится по ImageBase - 400000, и поэтому загружает DLL по ImageBase - 00870000 (на моем компе). Часть этой DLL имеет сильно обусцированный код, который я деобфусцировал, и собрал в одном месте. Вот фрагмент этого кода: Code: 
 Этот код с помощью Multiline Ultimate Assembler я вставляю по адресу 0088EE30, и он приобретает такой вид: Code: 
 Теперь мне надо сохранить изменения в файле, но адреса во вставленном фрагменте кода мне нужно привязать к ImageBase DLL, т.е. к 00400000. Поэтому мне приходится вручную править все эти адреса, чтобы получить следующий вид этого фрагмента кода: Code: 
 Когда таких корректировок немного, то это можно сделать и вручную. А когда корректировок набегает до сотни, то это становится утомительным. Если бы я смог в Multiline Ultimate Assembler указать ImageBase вставляемого кода как 00400000, то мне не пришлось бы вручную корректировать вставляемый код. Именно это я и имел ввиду в своем посте. PS: Пока я писал это сообщение, Konstantin уже написал свой пост. Но я хотел бы кое-что уточнить в посте Konstantin. Когда я работаю с DLL, то я запускаю два отладчика с разными файлами LOADDLL.EXE, что позволяет мне загружать DLL по разным базовым адресам. Multiline Ultimate Assembler прекрасно привязывает адреса к разным базам, поэтому тут вопросов нет. Вопрос появляется, когда нужно сохранить изменения в файле, но с привязкой адресов к ImageBase DLL, указанной в PE-заголовке файла. ![]()  | 
| 
 | 
Создано: 22 октября 2012 17:07 · Поправил: Konstantin  · Личное сообщение · #8  | 
| 
 | 
Создано: 22 октября 2012 20:17  · Личное сообщение · #9 Konstantin пишет: Может в оле (modules window (Alt+E))) посмотреть имя модуля с ImageBase=400000. И привязать первую команду (как в вашем примере) к модулю с ImageBase=400000, как то так:PUSH $loaddll.359A8ЗЫ. Не получится так, будут ошибки. Можно. Все работает: http://i.imgur.com/m4mTe.png Какой код выдает ошибку? Другой вопрос, если на этом адресе нету модуля. Я хочу добавить возможность использовать RVA адрес без модуля, например: PUSH $(00400000).1000 ![]()  | 
| 
 | 
Создано: 22 октября 2012 21:19  · Личное сообщение · #10 При вставке кода в DLL, Multiline Ultimate Assembler пересчитывает адреса применительно к ImageBase загрузки DLL, причем этот адрес утилита берет автоматически. Для большинства DLL, которые мне приходилось распаковывать, используется стандартное значение ImageBase - 10000000. Родной лоадер LOADDLL.EXE, входящий в комплект поставки OllyDbg, загружает DLL по адресу, указанному в ее PE-заголовке, за исключением того случая, когда совпадают ImageBase обоих файлов - LOADDLL.EXE и DLL. В этом случае, DLL загружается по свободному адресу. И, если DLL загружается по адресу, указанному в PE-заголовке, то все получается хорошо - не нужно пересчитывать значения адресов. А вот во втором случае их приходится пересчитывать, что я и показал в своем предыдущем посте. ![]()  | 
| 
 | 
Создано: 22 октября 2012 22:28 · Поправил: Konstantin  · Личное сообщение · #11 RaMMicHaeL пишет: Я хочу добавить возможность использовать RVA адрес без модуля, например:PUSH $(00400000).1000 Отлично! В принципе больше ничего и не нужно. RaMMicHaeL пишет: Можно. Все работает: http://i.imgur.com/m4mTe.pngКакой код выдает ошибку? Попробуйте в вашем примере - push $loaddll.1000 взять RVA не 1000, а больше размера модуля loaddll, например 70000. vnekrilov пишет: При вставке кода в DLL, Multiline Ultimate Assembler пересчитывает адреса применительно к ImageBase загрузки DLL, причем этот адрес утилита берет автоматически. Это не совсем так. Так будет если принудительно не указан никакой т.е. все RVA начинаются с $$, если в первом адресе с RVA явно указать модуль , например, PUSH $loaddll.359A8 (а не PUSH $$359A8) то все последующие адреса, начинающиеся с $$ будут вычисляться пользуя ImageBase модуля loaddll. ![]()  | 
| 
 | 
Создано: 22 октября 2012 22:51  · Личное сообщение · #12 vnekrilov пишет: При вставке кода в DLL, Multiline Ultimate Assembler пересчитывает адреса применительно к ImageBase загрузки DLL, причем этот адрес утилита берет автоматически. При использовании адресов вида $$1000, утилита берет ImageBase с модуля адреса блока. А заменить все "$$" на "$LOADDLL." - чем не решение? Konstantin пишет: все RVA начинаются с $$, если в первом адресе с RVA явно указать модуль - например - PUSH $loaddll.359A8 (а не PUSH $$359A8) то все последующие адреса, начинающиеся с $$ будут вычисляться пользуя ImageBase модуля loaddll. Не правильно. Адреса вида $$1000 берут модуль с адреса блока. Например: Code: 
 Konstantin пишет: Попробуйте в вашем примере - push $loaddll.1000 взять RAV не 1000, а больше размера модуля loaddll, например 70000. Выдает ошибку "The RVA address exceeds the module size", то есть - RVA адрес выходит за пределы модуля. Все правильно. ![]()  | 
| 
 | 
Создано: 22 октября 2012 23:08 · Поправил: Konstantin  · Личное сообщение · #13 RaMMicHaeL пишет: Не правильно. У вас в справке пример можно понять двояко, я просто не проверил. ![]() RaMMicHaeL пишет: Все правильно. RaMMicHaeL пишет: А заменить все "$$" на "$LOADDLL." - чем не решение? НЕ совсем совместимые вещи. ![]() Вот если бы была возможность отключать такие ошибки было бы ещё правильнее. Для наших целей иногда не нужно проверять конечный адрес на наличие и предел. ![]()  | 
| 
 | 
Создано: 22 октября 2012 23:35  · Личное сообщение · #14 Konstantin пишет: У вас в справке пример можно понять двояко, я просто не проверил. Исправлю. Хотя кроме примера есть и объяснение, как оно работает. Konstantin пишет: Вот если бы была возможность отключать такие ошибки было бы ещё правильнее. Для наших целей иногда не нужно проверять конечный адрес на наличие и предел. Я думаю предложенный выше синтаксис ($(00400000).1000) решит эту проблему. ![]()  | 
| 
 | 
Создано: 23 октября 2012 11:37 · Поправил: vnekrilov  · Личное сообщение · #15 Konstantin пишет: если в первом адресе с RVA явно указать модуль , например, PUSH $loaddll.359A8 (а не PUSH $$359A8) то все последующие адреса, начинающиеся с $$ будут вычисляться пользуя ImageBase модуля loaddll. На подопытной DLL я попытался применить предложенный подход, и вот что я получил: ![]() RaMMicHaeL пишет: Я думаю предложенный выше синтаксис ($(00400000).1000) решит эту проблему. А вот что я получил при попытке применить этот синтаксис: ![]() Неужели так трудно сделать загрузку кода по указанной пользователем базе? ![]()  | 
| 
 | 
Создано: 23 октября 2012 11:56  · Личное сообщение · #16  | 
| 
 | 
Создано: 23 октября 2012 14:41  · Личное сообщение · #17 vnekrilov пишет: На подопытной DLL я попытался применить предложенный подход, и вот что я получил: Имена модулей чувствительны к регистру. (Я поправлю это в следующей версии) Попробуй $LOADDLL.359A8 vnekrilov пишет: А вот что я получил при попытке применить этот синтаксис: Этот синтаксис - план на следующую версию. Пока его нету. vnekrilov пишет: Если тебе интересно поэкспериментировать с этой DLL, я могу выложить тебе ее на обменник вместе с листингом кода. Я не думаю, что нужно. Я понял суть проблемы, предложил нормальное решение. Осталось только воплотить его в реальность. ![]()  | 
| 
 | 
Создано: 23 октября 2012 16:43  · Личное сообщение · #18 RaMMicHaeL пишет: Имена модулей чувствительны к регистру. Да, верно. В листинге, в блокноте, я заменил все символы "$$" на "$LOADDLL.", и все нормально получилось. Правда, были также откорректированы и несколько прыжков, но которые было легко вернуть назад (прыжков оказалось намного меньше), чем корректируемых адресов. Спасибо  
![]()  | 
| 
 | 
Создано: 24 октября 2012 20:33  · Личное сообщение · #19 Готов v2.1, с расширенным синтаксисом RVA адресов: * Возможность вручную задавать базовый адрес, например: PUSH $(00400000).1000 * Возможность использовать короткий синтаксис для адреса блока, например: <$$1000> Общий пример использования RVA адресов с последними нововведениями: Code: 
   | Сообщение посчитали полезным: Konstantin, vnekrilov, Bronco, NikolayD, plutos, Simargl, KingSise, Valemox, mak, stas_02 | 
| 
 | 
Создано: 04 ноября 2012 01:04 · Поправил: vnekrilov  · Личное сообщение · #20 RaMMicHaeL Столкнулся еще с одной проблемой при использовании твоего прекрасного инструмента. При вставке кода типа: Code: 
 MUltimate Assembler ассемблирует эти инструкции в таком виде: Code: 
 Т.е., в опкод инструкций, работающих с BYTE, он добавляет впереди опкода байт <36:>. При работе с большим числом инструкций, эти байты увеличивают код инструкций до такой степени, что они не помещаются на свое родное место. Приходится вручную удалять эти байты <36:>, чтобы вложиться в заданный размер подпрограммы. Следует отметить, что и при ручной вставке кода в отладчике через окно ассемблирования инструкций, происходит тоже самое, но весьма хаотично - то вставляется символ <36:>, то не вставляется. Может можно что-то сделать в MUltimate Assembler, чтобы устранить эту проблему? ![]()  | 
| 
 | 
Создано: 04 ноября 2012 23:44  · Личное сообщение · #21 vnekrilov Code: 
 Аналогично ассемблирует? (убран SS ) ----- EnJoy!   | Сообщение посчитали полезным: SVLab | 
| 
 | 
Создано: 05 ноября 2012 10:28  · Личное сообщение · #22 Jupiter Попробовал твой метод. Действительно, если сделать все строки в прописных буквах (а не в заглавных), и в настройках отладчика убрать отображение сегментов SS, то все ассемблируется нормально. Большое спасибо за совет. Я думаю, что твой совет может быть полезным и для других юзеров, которые занимаются восстановлением обфусцированного кода. ![]()  | 
| 
 | 
Создано: 05 ноября 2012 23:22  · Личное сообщение · #23 vnekrilov пишет: Действительно, если сделать все строки в прописных буквах (а не в заглавных) Капитан очевидность подсказывает, что регистр тут значения не имеет. А ман интела подсказывает, что дело исключительно в префиксе 36H—SS segment override prefix   | Сообщение посчитали полезным: vnekrilov | 
| 
 | 
Создано: 30 ноября 2012 10:58  · Личное сообщение · #24  | 
| 
 | 
Создано: 05 января 2013 15:50  · Личное сообщение · #25 RaMMicHaeL Если не сложно - добавьте в список "Disasm hex number as:" вариант "$FFFE"   | Сообщение посчитали полезным: DimitarSerg | 
| 
 | 
Создано: 05 января 2013 19:42  · Личное сообщение · #26  | 
| 
 | 
Создано: 07 января 2013 19:02  · Личное сообщение · #27  | 
| 
 | 
Создано: 07 января 2013 20:20  · Личное сообщение · #28  | 
| 
 | 
Создано: 08 января 2013 17:28  · Личное сообщение · #29  | 
| 
 | 
Создано: 13 января 2013 18:44  · Личное сообщение · #30  | 
| 
 | 
Создано: 13 января 2013 19:14  · Личное сообщение · #31  | 
| << . 1 . 2 . 3 . 4 . 5 . 6 . 7 . >> | 
| eXeL@B —› Софт, инструменты —› MUltimate Assembler | 



















 
 Для печати