![]() |
|
Модераторы: bsa |
![]()
|
|
| wvlg |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 2.6.2008 Репутация: нет Всего: нет |
Проблема в следующем. Пользователь вводит машинный код (то, что видно в дизассемблере в виде байт, а он их дизасемблирует отображает команды). Неважно как (из файла или просто вводом строки или по сети (у меня по сети этот код приходит). Но я просто никак не погу придумать как это реализовать, скажем в Borland Builder C++ (6.0)? На ассемблере нет проблем. Делаем область памяти с доступом RWE пишем туда код и нет проблем. Но на ЯВУ как(Конкрестно на С)? Сделать там ассемблеревскую вставку? Для меня проблематично. Хотя бы в плане адресации памяти. Не знаю как с этим быть. Да еще и доступ нужно открыть соответствующий.
(К стати, как альтернатива, интересует и возможность написания интерпритатора машинного кода, если можно так сказать З.Ы. Я тут новичек, так что прошу прощения, если что не так. Это сообщение отредактировал(а) wvlg - 3.6.2008, 09:19 |
|||
|
||||
| ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: нет Всего: 17 |
так:
точки с запятой после ассемблерных команд ставить не нужно. Интерпретатор машинного языка и дизассемблер - это кажется разные вещи, почти обратные. что это? -------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
| wvlg |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 2.6.2008 Репутация: нет Всего: нет |
Это опечатка. МАНЫ- мануалы... Доступные, готовые руководства к написанию дизассемблера. Пример с пояснением, в моем понимании.
Поэтому я и сказал:"интерпритатора машинного кода, если можно так сказать" А насчет ассемблеровской вставки как Вы себе представляет, что я там должен написать!!?? По-любому существующему адресу вставить то, что я хочу и выполнить? Для начала память надо выделить. Дать ей доступ R\W\E. Потом записать туда то, что нужно и выполнить. Это сообщение отредактировал(а) wvlg - 3.6.2008, 09:52 |
|||
|
||||
| ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: нет Всего: 17 |
Так вы объясните нормально, что вам нужно. на www.wasm.ru -------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
| wvlg |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 2.6.2008 Репутация: нет Всего: нет |
Да, пожалуй, самое главное я не сказал. Извиняюсь. Задумался слишком, наверное.
Итак. Пользователь вводит машинный код. В этом коде используются 4 регистра процессора. (два задают адреса строки символов(на оба одинаковый адрес), третий счетчик, в 4й происходит запись символа и операции над ним). Необходимо подать на эти регистры нужные нам значения. У нас в программе есть строка, адрес, по которому она лежит и нужно "положить" в регистры. А затем необходимо запустить этот самый пользовательский код на исполнение и вернуться в основную часть программы. Вот. Это сообщение отредактировал(а) wvlg - 3.6.2008, 10:40 |
|||
|
||||
| ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: нет Всего: 17 |
Допустим юзер вводит команду в Edit1, регистры соответственно в Edit2, Edit3 и Edit4.
Тогда можно сделать примерно так (в Borland Builder C++ 6.0):
Но могут быть проблемы из-за использования регистров. Поэтому лучше в начале вставки делайте PUSHA, а в конце POPA Это сообщение отредактировал(а) ksili - 3.6.2008, 10:43 -------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 2 Всего: 121 |
Я так и не понял, что конкретно надо. Интерпретатор, дизассемблер, свой ассемблер или что вообще? Давайте определимся, ненужно сумбурности и длинных описаний, приведите какой-нибудь обощённые пример и опишите последовательно, что должно происходить.
-------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| wvlg |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 2.6.2008 Репутация: нет Всего: нет |
Входные данные:
Пользовательская строка с машинным кодом. И ВСЕ. К ней требования: максимальный размер 500 байт В коде для адресации могут использоваться только 2 регистра: EBX, EAX. Для работы с данными Регистр AL - 1 байт Необходимо подать на регистры EAX,EBX адрес переменной с которой код пользователя будет работать. (по поводу размера отдельная тема, решаема...) Далее необходимо ЗАПУСТИТЬ строку которую ввел пользователь на исполнение. Т.е. пример: У нас есть адрес 0x018855aah. Записываем его в регистр EBX и его же в EAX. (Т.к. заранее мы не знаем какой из них будет выбран пользователем, но точно знаем, что один из них) Пользователь ввел: 8a03 Это - mov AL, Byte PTR DS:[EBX]-это в дизассемблере мы это увидим. А пользователь ввел всего лишь 8a03 Мы должны отправить 8a03 в память на исполнение, перед этим заполнив регистры адресами. Это сообщение отредактировал(а) wvlg - 3.6.2008, 11:19 |
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 6 Всего: 118 |
если ты знаешь как это реализовать на ASM, то зачем тебе билдер? ты можешь это реализовать на асме, и обернуть все это в библиотку, которую можно использовать уже в билдере.
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| wvlg |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 2.6.2008 Репутация: нет Всего: нет |
М... Думал я над этим. Просто на асме придется "попотеть". Библиотека ведь будет под WIn. Могу ошибок понаделать миллион, хотя... Там все те же вопросы по поводу выделения секций памяти и т.п. На асме я себе это еще хотя бы представляю (но не знаю на сколько это будет сложно). А вот в билдере... Да и просто интересно... Ведь если задачу усложнить и видоизменить, то что каждый раз писать на ассемблере? Добавлено @ 11:36
это команды ассемблера... А пользователь вводит команды процессора... Это сообщение отредактировал(а) wvlg - 3.6.2008, 11:37 |
|||
|
||||
| ksili |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: нет Всего: 17 |
Ну так поправить можно:
-------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
||||
|
|||||
| W4FhLF |
|
||||||||||||||||||||||||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 2 Всего: 121 |
Теперь всё ясно.
Код команды mov eax,X0...X3:
mov ebx,X0...X3:
Xn - n-ый байт в числе. т.е. X0...X4 - обычный DWORD. например 018855AAh. Создаёшь два массива в С++:
Пользователь ввёл какой-то адрес, ты переводишь строку в DWORD(unsigned int32) и пишешь по адресам mov_eax[1], mov_ebx[1]. Т.о. ты формируешь две машинные инструкции:
Выделяешь массив под шеллкод:
Далее пользователь вводит любой машинный код, например, как ты сказал:
Разделяешь всю введённую строку на байты, т.е. обрабатываешь по два символа, каждые два символа - один байт, т.е. в результате ты должен будешь получить массив:
Получил ты этот массив. В самое начало shellcode надо поместить команду pushfd, только если тебе надо сохранить среду исполнения перед выполнением пользовательского кода, команда сохранит все регистры и флаги в стеке, после исполнения твоего кода мы восстановим их. Код инструкции:
Далее, за pushfd в массив shellcode надо поместить две команды mov eax, an_address и mov ebx,an_address. Это осуществляется простым копированием из массивов mov_eax и mov_ebx в начало массива shellcode. Теперь копируй в shellcode[10] массив, который получил чуть раньше из введённых пользователем данных. За ними вставляй(в случае, если был pushfd):
Далее, после выполнения пользовательского кода и восстановления среды необходимо вернуться на то место в программе, откуда был вызван шеллкод, для этого надо узнать адрес возврата. Делается это примерно так:
Соответственно в конец массива shellcode пишешь
Только предварительно поищи в интернете или почитай в манах от Intel'a как формируется код адреса для относительных переходов. Всё, теперь можешь исполнять shellcode в памяти. Возможно понадобится выставить аттрибут EXECUTE для массива shellcode, это можно сделать с помощью api VirtualProtect в Windows. Ещё, массив shellcode лучше не делать локальным, ибо может быть включен DEP и тогда на стеке ничего не исполнится. Добавлено через 5 минут и 16 секунд Что касается адресации в памяти. Вводимы пользователь код должен быть базонезависимым, иначе тебе придётся прикручивать полноценный дизассемблер и делать анализатор кода, который будет заниматься rebasing'ом. Это сообщение отредактировал(а) W4FhLF - 3.6.2008, 12:12 -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
||||||||||||||||||||||||
|
|||||||||||||||||||||||||
| wvlg |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 2.6.2008 Репутация: нет Всего: нет |
ОБАЛДЕТЬ!!!
Как раз то, что я искал. Огромное спасибо! Надо попрбовать. Единственное, как я понял, чтобы вызвать shellcode должно быть что-то типа
И далее где-нибудь а затем asm вставка, где будет что-то типа Call ShellCode_addr ? И, главное, чтобы не возникло проблем с VirtualProtect... Вернее с тем что у памяти доступ будет еще и execute Добавлено через 9 минут и 47 секунд Честно говоря, когда сам над этим думал придумалась только одна мысль. Создать указатель на функцию. Выделить память. Скопировать туда то, что нам нужно. Указателю присвоить значение адреса этой памяти. Вызвать функцию.... Мне казалось, что такое не пройдет. ? Это сообщение отредактировал(а) wvlg - 3.6.2008, 12:51 |
|||
|
||||
| W4FhLF |
|
||||||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 2 Всего: 121 |
если со вставкой, то так:
Просто на С++ будет так:
Какие проблемы? Простой вызов:
Можешь даже делать этот вызов всегда, чтобы оградить себя от лишних проблем. Есть особенность, права доступа назначаются целым страницам памяти, они не могут быть назначены какой-то части страницы. Стандартный размер страницы в windows == 0x1000. Т.е. можешь массив shellcode делать размером 0x1000 и не париться. -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
||||||
|
|||||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |