Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.10.2012, 20:59   #1
KellyDink
Пользователь
 
Регистрация: 14.10.2012
Сообщений: 13
По умолчанию дизассемблирование

Доброго времени суток. Пытаюсь дизассемблировать программу:

Код:
void lame (void) { char small[30]; gets (small); printf("%s\n", small); }
int main() { lame (); getch(); return 0; }
собираю ее с помощью команды gcc –ggdb qwa.c –o qwa,
дальше запускаю gdb qwa
и при дизассемблировании функции main я получаю
Код:
   0x00401316 <+0>:	push   %ebp
   0x00401317 <+1>:	mov    %esp,%ebp
   0x00401319 <+3>:	sub    $0x8,%esp
   0x0040131c <+6>:	and    $0xfffffff0,%esp
   0x0040131f <+9>:	mov    $0x0,%eax
   0x00401324 <+14>:	add    $0xf,%eax
   0x00401327 <+17>:	add    $0xf,%eax
   0x0040132a <+20>:	shr    $0x4,%eax
   0x0040132d <+23>:	shl    $0x4,%eax
   0x00401330 <+26>:	mov    %eax,-0x4(%ebp)
   0x00401333 <+29>:	mov    -0x4(%ebp),%eax
   0x00401336 <+32>:	call   0x401870 <_alloca>
   0x0040133b <+37>:	call   0x4013f0 <__main>
   0x00401340 <+42>:	call   0x4012f0 <lame>
   0x00401345 <+47>:	call   0x4018a0 <getch>
   0x0040134a <+52>:	mov    $0x0,%eax
   0x0040134f <+57>:	leave  
   0x00401350 <+58>:	ret
вот дамп функции lame
Код:
   0x004012f0 <+0>:	push   %ebp
   0x004012f1 <+1>:	mov    %esp,%ebp
   0x004012f3 <+3>:	sub    $0x38,%esp
   0x004012f6 <+6>:	lea    -0x28 (%ebp),%eax
   0x004012f9 <+9>:	mov    %eax,(%esp)
   0x004012fc <+12>:	call   0x401930 <gets>
   0x00401301 <+17>:	lea    -0x28(%ebp),%eax
   0x00401304 <+20>:	mov    %eax,0x4(%esp)
   0x00401308 <+24>:	movl   $0x403000,(%esp)
   0x0040130f <+31>:	call   0x401920 <printf>
   0x00401314 <+36>:	leave  
   0x00401315 <+37>:	ret
Внимание вопрос: почему он здесь (0x004012f3 <+3>: sub $0x38,%esp) смещает стек на 40 байт, если в функции указано 30? по моей логике он должен это делать на 32 байта?

И как мне записать в ebp - чего-нибудь свое (пытаюсь воспроизвести ошибку переполнения буфера)
пробовала
вот так вот:
Код:
main()
{ 
int i=0; char buf[44];
for (i=0;i<=40;i+=4)
*(long *) &buf[i] = 0x00401340;(адрес вызова функции lame)
puts(buf);
}
но выдает кроказябры =(

Последний раз редактировалось Stilet; 14.10.2012 в 21:30.
KellyDink вне форума Ответить с цитированием
Старый 14.10.2012, 21:40   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
смещает стек на 40 байт, если в функции указано 30?
Наверное в надежде на то, что в тех дополнительных 10-ти байтах будет что-то работающее с функциями gets и printf.
Вот если отладчиком пройтись по дизасму, как стек будет меняться после отработки этих двух функций?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 14.10.2012, 22:06   #3
Son Of Pain
Участник клуба
 
Регистрация: 23.12.2010
Сообщений: 1,129
По умолчанию

Неисповедимы пути gcc )
32 байта нужно для твоего буфера; 8 для передачи параметров в функции (gcc не пушит их, как большинство остальных компиляторов, а резервирует место в стеке сразу); ну и 16 оставляет на всякий случай (или для выравнивания, как в 0x0040131c).

А для переполнения буфера тебе нужно просто ввести длинную строчку (больше 44 байт) в ответ на gets, адрес возврата в стеке перезапишется и ты скорее всего увидишь сегфолт
Чтобы вместо сегфолта вызвать какое-то осмысленное действие - в те 4 байта, которые перезапишут адрес возврата, нужно записать адрес кода, который должен выполниться.
И принтф там не нужен.
Son Of Pain вне форума Ответить с цитированием
Старый 14.10.2012, 22:25   #4
KellyDink
Пользователь
 
Регистрация: 14.10.2012
Сообщений: 13
По умолчанию

спасибо за разъяснения.

я хочу туда что-то дельное пихнуть. пока я хочу туда записать адрес 0x00401340 - вызов моей функции lame. при переводе в в символы, что означает @!!@

по идее, моя программа
main()
{
int i=0; char buf[44];
for (i=0;i<=40;i+=4)
*(long *) &buf[i] = 0x00401340;(адрес вызова функции lame)
puts(buf);
}

должна сгенерировать 11 раз 0x00401340 и вывести это в консоль, но во-первых, выводит она 1 раз, а во-вторых, не понимаю, как мне это в виде параметра донести первой программе?

я конечно осознаю всю тяжесть моего психического состояния, что использую все это под Windows, но подскажите пожалуйста, как это возможно сделать ? я пытаюсь это сделать с помощью команды (ret;cat)| qwa
но он упорно выдает мне @!!@

Последний раз редактировалось KellyDink; 14.10.2012 в 22:35.
KellyDink вне форума Ответить с цитированием
Старый 14.10.2012, 22:50   #5
Son Of Pain
Участник клуба
 
Регистрация: 23.12.2010
Сообщений: 1,129
По умолчанию

Окей, давай разбираться.

На архитектуре X86 числа хранятся в памяти, начиная с младшего байта (little-endian). т. е. твой адрес 0x00401340 будет выглядеть как 0x40 0x13 0x40 0x00.
И когда ты несколько раз подряд запишешь его в buf, там будет
Код:
0x40 0x13 0x40 0x00 0x40 0x13 0x40 0x00
, и так далее.
Потом ты передаешь этот буфер в puts. Она воспринимает его как строчку, и выводит на экран. А строчки в C всегда заканчиваются нулевым байтом. Следовательно, puts выведет только три байта (до первого нулевого). Потому ты и видишь это в консоли только один раз )

Ну и в этом коде переполнения буфера нету - ты выделяешь под него 44 байта и заполняешь 44 байта. Сделай буфер меньше или цикл дольше
И следи за тем, чтобы после перекомпиляции нужный адрес не поменялся.
Son Of Pain вне форума Ответить с цитированием
Старый 14.10.2012, 23:22   #6
KellyDink
Пользователь
 
Регистрация: 14.10.2012
Сообщений: 13
По умолчанию

Спасибо большое за ответ =( мне очень стыдно, но у меня все-равно ничего не выходит.

увеличение цикла не помогло. он упорно выводит мне @!!@.

правильно ли я поняла, что нужно изменить запись в массив?
у меня же массив из 44 (уже из 48) однобайтовых элементов. то есть возможно он выводит не в той последовательности?

Эксперементальным путем выяснила, что падает она только при 75 знаках О_О
опять когнетивный диссонанс - почему не при 30-ти?

как мне правильно вывести на входные данные первой программы мой массив buf из другой? интуиция мне подсказывает, что моё: "(ret;cat)| qwa" неверно
в интернетах пишут
./buff `perl -e 'print "A" x 11'`
You entered: AAAAAAAAAAA

а у меня даже входную строку как параметр указать не удается, она ее игнорирует =(
KellyDink вне форума Ответить с цитированием
Старый 14.10.2012, 23:32   #7
KellyDink
Пользователь
 
Регистрация: 14.10.2012
Сообщений: 13
По умолчанию

для того, чтобы разложить для себя по полочкам сказанное - исправила написанное на:
main()
{
int i=0; char buf[80];
for (i=0;i<=84;i+=4)
buf[i] = 0x40;
buf[i+1]=0x13;
buf[i+2]=0x40;
buf[i+3]=0x00;
puts(buf);
}

выводит @ "

оно и понятно, видимо потом идет 0x00.

если поставить в обратном порядке, то ничего не выводит (ибо первым идет 0x00)

что-то мне подсказывает, что моя проблема в прямоте рук (ее отсутствии ) и команде для передачи на входные данные программе моего массива.

Последний раз редактировалось KellyDink; 14.10.2012 в 23:39.
KellyDink вне форума Ответить с цитированием
Старый 14.10.2012, 23:50   #8
Son Of Pain
Участник клуба
 
Регистрация: 23.12.2010
Сообщений: 1,129
По умолчанию

Так ты определись, что конкретно хочешь получить )

На экран ты никак эту длинную строчку не выведешь из-за нулевых байтов. Но для переполнения это и не нужно.
А в последнем твоем коде ошибка - тело цикла нужно брать в скобки {}.

В интернетах правильно пишут про perl только их пример рассчитан на случай, когда программа принимает ввод из командной строки. В твоем случае нужно наоборот -
Код:
perl -e 'print строчка с эксплоитом' | ./имятвоейпрограммы
И, опять же, напрямую передать так, как ты хочешь, не получится из-за нулевых байтов - gets остановит чтение на них. Потому нужно передавать любой другой байт, и только в конце буфера нужный тебе адрес. И рассчитать размер передаваемой строчки так, чтобы последние байты попали точно на адрес возврата.

Напиши итоговый код программы с листингом, и тогда посчитаем, что конкретно ей нужно передать )
Son Of Pain вне форума Ответить с цитированием
Старый 15.10.2012, 00:34   #9
KellyDink
Пользователь
 
Регистрация: 14.10.2012
Сообщений: 13
По умолчанию

хочу развернуть свою программу на 180 градусов и вернуть ее на выполнение функции lame.

сама программа выглядит так:
void lame (void) { char small[30]; gets (small); printf("%s\n", small); }
int main() { lame (); return 0; }

экспериментальным путем я вычислила, что если вставлять строчку
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxa из 81 x и 1 a, то программа падает на 0x78787878 (то есть x), а если 80-ый символ поставить a, то программа падает на адресе 0x61787878
правильно ли я понимаю, что мне нужно записать 76 x и потом записать желаемый адрес?

main()
{
int i=0; char buf[81];
for (i=0;i<=75;i+=1)
buf[i] = 0x78;
buf[76]=0x00;
buf[77]=0x40;
buf[78]=0x13;
buf[79]=0x40;
puts(buf);
}

тока она все-равно не работает =) при вызове команды (ret;cat) | qwa
она падает , но второй раз на функцию lame не идет =(

и вот еще вопрос: http://www.wasm.ru/article.php?article=buf_over4noob вот тут работало с нулевыми байтами =( пыталась повторить, но увы безуспешно =(

с перлом у меня не вышло.
при попытке записи
perl -e 'print "A"*3' / qwa
пишет
Can't find string terminator " ' " anywhere before EOF as -e line 1.


** адрес вызова функции lame еще раз проверила, он остался прежним.

Последний раз редактировалось KellyDink; 15.10.2012 в 01:06.
KellyDink вне форума Ответить с цитированием
Старый 15.10.2012, 01:19   #10
Son Of Pain
Участник клуба
 
Регистрация: 23.12.2010
Сообщений: 1,129
По умолчанию

На каком адресе падает? )
Вообще, стукни лучше в icq, там удобнее.
Son Of Pain вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Дизассемблирование exe Garmon Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 10.12.2011 15:48
Дизассемблирование\Снятие защиты ORiEN Goblenus Помощь студентам 0 05.10.2011 23:10
дизассемблирование команд [MI_nor] Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 23.05.2011 02:19
Дизассемблирование Slavic111 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 15 19.07.2010 16:46
Исследование программ (дизассемблирование) Вавел из ГМТУ Свободное общение 11 12.11.2009 23:37