
31.08.2007, 17:59
|
|
Banned
Регистрация: 11.08.2006
Сообщений: 1,522
С нами:
10393869
Репутация:
2032
|
|
Всем спасибо, я разобрался.
Сообщение от groundhog
А вообще читай азы по сям...
Я читал, но, видимо, не очень хорошо 
|
|
|

31.08.2007, 17:02
|
|
Постоянный
Регистрация: 27.08.2006
Сообщений: 367
С нами:
10370602
Репутация:
472
|
|
Небольшое отступление к сообщению groundhog. Всегда определяйте указатели.
int *pint = 0;
Такие мелочи приводят к ошибкам в больших проектах, читайте книги.
|
|
|

31.08.2007, 19:05
|
|
Banned
Регистрация: 18.05.2005
Сообщений: 1,981
С нами:
11042306
Репутация:
2726
|
|
> а в чем различие на практике?
Различие принципиальное. У тебя есть переменная scratch. Ее значение - это какие-то байты по адресу определенному. Когда ты к ней обращаешься
char scratch = getColor( 0 );
компиллер генерирует такой код, например:
push 0
call getColor // вызов getColor
mov byte ptr [0x00401020], eax // положить результат в байт по адресу, тут ее адрес 00401020
А предположим она у тебя char *scratch.
Тогда она в 32-битной системе (проца) будет 4-байтным значением (DWORD, ULONG и тп), в ней будет хранится АДРЕС чего-то. Т.е. в принципе по*** пишешь ты char *scratch, void *scrach или int *scratch. Если указываешь звездочку - это значит там будет указатель 4-байтный. А тип - это значит на какой тип данных указывает переменная. Это надо чтоб компиллер тебе говорил об ошибках возможных. Впринципе можно взять указатель и рассматривать данные по нему как данные другого типа. Пример
void *ptr = (void*)0x00401020; // указатель на 0x00401020
((mystruct*)ptr)->field1 = 0; // рассматриваем как указатель на структуру mystruct
//или:
*((int*)ptr) = 0; // рассматриваем *ptr (данные по адресу ptr) как int и кладем туда int
тогда сначала берется значение по адресу какому-то (значение переменной), там лежит опять адрес, и значение по этому адресу уже будет *ptr.
Если тебе, скажем, надо дать возможность ф-ии модифицировать переменную переданую (а не только передать ее значение) - можно передать указатель на нее. По этому адресу будет значение и ф-ия туда сможет записать свою ***ню.
Или, скажем, у тебя какая-то структуру большая в памяти должна динамически выделяться, тогда делаем mystruct *s = (mystruct*)malloc( sizeof( mystruct ) );
и у тебя в s указатель на место в памяти где отделено sizeof( mystruct ) байт под структуру. s->field1 - поле структуры. а если s хранит структуру а не указатель то s.field1.
Такие мелочи приводят к ошибкам в больших проектах, читайте книги.
лол NiOx вроде умный чел а написал ***ню) нахер определять указатели ? че за правило неписаное такое?
нихера не надо определять если явно не нужно.
Последний раз редактировалось KEZ; 31.08.2007 в 19:08..
|
|
|

31.08.2007, 22:27
|
|
Постоянный
Регистрация: 27.08.2006
Сообщений: 367
С нами:
10370602
Репутация:
472
|
|
Кез, ты не прав.
Статическая память(секции .data, .bss) иницилизируется нулями при запуске программы. У переменных в стеке и куче гарантия такой инициализации отсутствует, поэтому нужно специально инициализировать такие переменные для нормальной работы приложения. Содержимое неинициализированной переменной неопределено, зато можно точно предсказать что будет содержаться в неинициализированной области памяти. Представь себе неинициализированною стековую переменную, в ней может оказаться куча всего, в том числе сохраненные регистры, переменные от предыдущих вызовов, и тд. Все зависит от нахождения такой переменной в стеке. Стоит лишь взять определенную область памяти под контроль и появится возможность эксплутации. Конечно программистам, которые пишут для себя калькуляторы и тд плевать на такие уязвимости, однако раньше в крупных opensource проектах можно было часто встретить такие баги, сейчас они почти не попадаются. Для наглядности приведу пример:
Код:
unsigned int func(char *s)
{
char *vuln;
if(s)
{
vuln = malloc(1024);
...
}
free(vuln);
return 0;
}
А теперь подумайте, если аргумент s будет равен нулю, то указатель vuln окажется неинициализированным до конца функции, где для него будет вызвана функция free. О результате подумайте сами.
Последний раз редактировалось Ni0x; 31.08.2007 в 22:30..
|
|
|

31.08.2007, 22:39
|
|
Banned
Регистрация: 11.08.2006
Сообщений: 1,522
С нами:
10393869
Репутация:
2032
|
|
То есть функция
unsigned int func(char s)
уязвимой тоже будет. так?
|
|
|

31.08.2007, 23:02
|
|
Постоянный
Регистрация: 27.08.2006
Сообщений: 367
С нами:
10370602
Репутация:
472
|
|
Piflit, не совсем понял тебя.
Если вызвать func(0), то функция free попытается освободить vuln, который будет содержать в себе "мусор", обычно программа просто аварийно завершится.
|
|
|

31.08.2007, 23:10
|
|
Banned
Регистрация: 11.08.2006
Сообщений: 1,522
С нами:
10393869
Репутация:
2032
|
|
Сообщение от Ni0x
Piflit, не совсем понял тебя.
я тоже чето не то написал.
Код:
unsigned int func(char *s)
{
char vuln;
if(s)
{
vuln = malloc(1024);
...
}
free(vuln);
return 0;
}
это уязвимым не будет. правильно?
|
|
|

31.08.2007, 23:21
|
|
Познающий
Регистрация: 27.03.2007
Сообщений: 36
С нами:
10065986
Репутация:
86
|
|
2Piflit если бы было так: char *vuln = NULL, то все номр. А в данном случае указатель не инициализированный. т.е это косяк в проге.
|
|
|

31.08.2007, 23:32
|
|
Постоянный
Регистрация: 27.08.2006
Сообщений: 367
С нами:
10370602
Репутация:
472
|
|
http://shellcode.ru/index.php?name=News&file=article&sid=14
Указатели вовсе не обязательно иниицализировать, но новички всеже должны представлять, что существует класс уязвимостей, связанных с неинициализацией.
Последний раз редактировалось Ni0x; 01.09.2007 в 12:41..
|
|
|

02.09.2007, 16:48
|
|
Постоянный
Регистрация: 05.01.2007
Сообщений: 508
С нами:
10182506
Репутация:
1393
|
|
У меня Borland C++ Builder 6.0
Я игрался в настройках, и теперь когда компилю прогу, то пашет она, только у меня (
Как это исправить?
|
|
|
|
 |
|
|
Здесь присутствуют: 4 (пользователей: 0 , гостей: 4)
|
|
|
|