2015-11-24 5 views
-5

У меня возникли проблемы с запуском этого c-кода. Когда я делаю, я получаю ошибку сегментации и ошибку с возвратом return 0xdeadbeef;Ошибка сегментации при переполнении буфера

У кого-нибудь есть предложения?

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int lame(unsigned int size, unsigned int value){ 

unsigned int array1[4]; 
unsigned int array2[6]; 
array2[5] = value; 
memcpy(&array1, &array2, size * sizeof(unsigned int)); 

return 1; 
} 

void awesome(){ 
printf("awwwwwww yeaaahhhhh! All awesome, all the time!\n"); 
} 

main(unsigned int argc, char ** argv){ 
unsigned int size, value; 
size = strtoul(argv[1], 0, 10); 
value = strtoul(argv[2], 0, 16); 

if(!lame(size, value)){ 
    awesome(); 
} 
else{ 
    printf("I am soooo lame :(\n"); 
} 

return 0xdeadbeef; 
} 
+3

Не размещайте ссылку на код. В частности, не размещайте ссылку на IMAGE кода. Поместите здесь свой код – Joe

+1

. Прежде всего, не публикуйте ссылки на код, ссылки могут устаревать и сделать ваш вопрос бесполезным. Во-вторых, и, что более важно, не размещайте изображения текста! Это делает невозможным копирование и вставку, чтобы попробовать сами. Вместо этого вы должны скопировать и вставить текст и поместить в тело вопроса как текст. –

+1

Существует по крайней мере одна ошибка почти на каждой строке вашего кода. Вам нужен вводный курс программирования, а не сайт Q & A. – zwol

ответ

2

Я сказал, что была «по крайней мере одна ошибка почти на каждой строке вашего кода», и теперь я перечислил их. Если у меня нет комментариев по строке, в этой строке нет ошибок, но вам также нужно прочитать правильное форматирование и стиль кода.

int lame(unsigned int size, unsigned int value){ 
unsigned int array1[4]; 
unsigned int array2[6]; 
array2[5] = value; 
memcpy(&array1, &array2, size * sizeof(unsigned int)); 
return 1; 
} 

Неопределенное поведение на memcpy линии, если size больше, чем 4. Поскольку size берется из пользовательского ввода, эта программа содержит уязвимость переполнения буфера, хотя тот, который может быть трудно эксплуатировать. (Вам необходимо прочитать «Smashing the Stack for Fun and Profit.»)

Эта функция не имеет внешних видимых побочных эффектов. Компилятор может и, вероятно, удалит весь код, за исключением return 1.

Функции, которые всегда возвращают одинаковое постоянное значение, должны быть реорганизованы для возврата void. Функции, которые не используются вне текущего файла, должны быть объявлены static.

void awesome(){ 
printf("awwwwwww yeaaahhhhh! All awesome, all the time!\n"); 
} 

Это использование printf можно заменить puts. Функции, которые не используются вне текущего файла, должны быть объявлены static.

main(unsigned int argc, char ** argv){ 

Первый аргумент main должен иметь тип int, не unsigned int. Обратный тип (который должен быть int, а не void) отсутствует; многие компиляторы будут терпеть это (рассматривая его как неявное возвращение int) для обратной совместимости с кодом pre-C89, но он по-прежнему неверен.

unsigned int size, value; 
size = strtoul(argv[1], 0, 10); 
value = strtoul(argv[2], 0, 16); 

Оба size и value должны быть unsigned long для соответствия с какими strtoul возвращается.

Неопределенное поведение, если имеется менее двух аргументов командной строки.

Необходимо проверить оба звонка на strtoul для отказа. Это нетривиально; прочитайте EXAMPLES section of the OpenBSD manpage for strtoul, чтобы узнать, как это сделать правильно.

Однако реквизита для использования strtoul, а не atoi (которые вы не можете чек на отказ) или sscanf (который имеет неопределенное поведение на целочисленное переполнение).

if(!lame(size, value)){ 
    awesome(); 
} 
else{ 
    printf("I am soooo lame :(\n"); 
} 

Компилятор может и будет определять, что lame всегда возвращает 1, а также оптимизировать выход вызов awesome.(Фактически, он будет иметь право оптимизировать все, но выше printf, так как все пути управления потоком либо вызывают неопределенное поведение, либо достигают этого printf, и других внешних видимых эффектов нет. Составителей, с которыми я с готовностью не совсем, что умные, но они сделать удалить тогда еще, если-и весь код внутри lame.)

Это использование printf также может быть заменен puts.

Вы автоматически станете на 23% меньше, если перестанете называть себя хромым.

return 0xdeadbeef; 

Значение, возвращаемое main имеет смысл. 0 означает успех общей программы, любое другое значение означает какой-то отказ. Всегда возвращайте 0, если вы не намерены указывать отказ. Кроме того, только исходные значения в диапазоне [0, 127] могут быть надежно получены кросс-платформой родительского процесса; 0xdeadbeef Правильно.

На вашем скриншоте mainvoid вместо отсутствия возвращаемого типа; что плюс оператор return со значением должен был привести к ошибке компиляции. Однако ваш компилятор может переносить его в main.

+0

большое спасибо, но я все еще очень озадачен! Не могли бы вы привести мне пример возврата 1 раздела этой работы? –

+0

извините, t понять, что вам нужно. – zwol

+0

как в том, как исправить строку memcpy (функция ламе) –

Смежные вопросы