Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.10.23;
Скачать: CL | DM;

Вниз

Переполнение массива в длл   Найти похожие ветки 

 
yaJohn ©   (2003-10-09 11:19) [0]

Есть доволе странная ситуация: вызываю функцию из чуждой ДЛЛ с двумя параметрами: integer по значению и буфер по ссылке, тобишь указатель.
По возвращении из функции переменная содержавшая integer параметр (переданный по значению) меняет свое значение... Только не говорите мне что так не бывает. Я до вчерашнего вечера тоже так думал.
После долгих размышлений пришел к следующему:
обе переменные обьявленны в классе, нечто вроде
TMyClass = class
....
MyArray: array [0..1000] of byte;
MyVar: integer;
....
Видимо, длл-функция лезет за край массива (хотя не должна). Предположим, действительно криво написана длл. Теперь вопрос:
Как обьявить статический массив, чтобы при попытке выйти за диапазон генерились страшные экзепшены и акссес виолейшены.
Нет, при попытке сказать MyArray[1001] или иже с ним все нормально, экзепшн есть. Но длл, видимо не так щепетильна в проверке диапазонов.


 
Digitman ©   (2003-10-09 11:27) [1]

скорей всего ты просто нарушил соглашение о бызовах для данной DLL ... она ж "чужая", док-ции нет, и ты от балды проставил соглашение)


 
TUser ©   (2003-10-09 11:29) [2]

может так

var
firstArray[..], secondArray[..];
//2 массива одного размера
begin
Func(Int, FirstArray);
try
Second:=First;
except
end;


Хотя памяти много надо.


 
Digitman ©   (2003-10-09 11:35) [3]


> Как обьявить статический массив, чтобы при попытке выйти
> за диапазон генерились страшные экзепшены и акссес виолейшены.
>


никак.
вернее - как угодно.
для ОС совершенно индифферентно как ты его объявишь
AV генерируется при выходе не за пределы какого-то там массива, а при нарушении прав доступа к странице памяти в ВАП процесса


> Но длл, видимо не так щепетильна в проверке диапазонов


никаких "диапазонов" DLL не проверяла и проверять никогда не будет , если не используются соотв. спец.опции соответствующего компилятора (использованного при создании DLL) и декларация диапазонного типа не соответствует соглашениям данного компилятора по автоматически генерируемого кода проверок


 
yaJohn ©   (2003-10-09 11:41) [4]

2> Digitman
В этой длл юзается еще два десятка функций. Вполне успешно. Функция переполняющая массив в принципе тоже дает верные результаты.
Что такое stdcall я тоже в курсе. Соглашение о вызовах - это первое что я проверил. А потом перепроверил. Документацию по длл я читал.

2 TUser
Память не критична. Мне скорее надо однозначно идентефицировать проблему. Желательно с уликами и доказательствами. Дабы потом настучать по мозгам авторам длл.
Можно попробовать решить проблему в лоб, увеличением буфера, но кто скажет, при каких условиях н хватит "раздутого" буфера?

Для справки - длл из API к хитрому PCI девайсу (АЦП). Писана фирмой производящей девайсы.


 
HolACost! ©   (2003-10-09 11:45) [5]

Есть хороший и вполне хорошийе 2 выхода!!!!!
1 - перебором... автоматическим
2 - дезассемблировать и проверить сколько она юзает! Там тебе и доказательства будут налицо!!!!


 
Digitman ©   (2003-10-09 11:49) [6]


> Соглашение о вызовах - это первое что я проверил


каким образом ? ты дизассемблировал эту библиотеку или методм научного тыка искал соглашение ?


 
yaJohn ©   (2003-10-09 11:49) [7]

>для ОС совершенно индифферентно как ты его объявишь
Спорное утверждение. Но это не важно. Зададим вопрос по другому:
как получить буфер (от дельфи, системы, черта) чтобы любое обращение за его пределы вызывало однозначную ошибку.

>никаких "диапазонов" DLL не проверяла и проверять никогда не будет
То что длл не проверяет диапазоны я уже понял. Само по себе это не есть хороший стиль. Но еще не ошибка.


 
han_malign ©   (2003-10-09 11:54) [8]

>integer по значению и буфер по ссылке
- уверен, что по значению? Как функция объявлена?


 
yaJohn ©   (2003-10-09 11:58) [9]

2 Digitman
Сударь, Вы встали не с той ноги? Соглашение о вызовах я определил путем чтения документации. По описанным выше симптомам я тоже первым делом подумал о соглашениях. Поэтому не мудрствуя лукаво перебрал все возможные варианты. Со всей ответственностью могу заявить, что соглашения о вызовах здесь ни при чем.


 
Anatoly Podgoretsky ©   (2003-10-09 12:00) [10]

Метод научного втыка не очень эффективный


 
Anatoly Podgoretsky ©   (2003-10-09 12:01) [11]

yaJohn © (09.10.03 11:58) [9]
Вот и приведи его здесь, зачем же остальным заниматься телепатией, только точно из документации, а не из головы, с поисанием параметров.


 
Digitman ©   (2003-10-09 12:01) [12]


> yaJohn


> Спорное утверждение


да никакого спора ! именно так и не иначе !
в ран-тайм при выполнении маш.инструкции обращения к участку вирт.памяти никаких "массивов" уже не существует.

существуют страницы вирт.памяти в АП процесса, и каждая из этих страниц имеет соотв.атрибуты/привелегии доступа.

если инструкция, обращающаяся по адресу в такой-то странице, нарушает тем или иным образом права доступа к этой странице, происходит GPF, следствием которого является прерывание по нарушению доступа, и в конечном итоге, AV-исключение. Весьма упрощенно, конечно, это описано мной ...


> как получить буфер (от дельфи, системы, черта) чтобы любое
> обращение за его пределы вызывало однозначную ошибку.


просто передай в кач-ве адреса буфера nil
если в теле вызываемой ф-ции нет соотв.проверки на nil, AV тебе гарантировано !


> То что длл не проверяет диапазоны я уже понял. Само по себе
> это не есть хороший стиль


строго наоборот
если DLL отлажена, то нет никакого резона перед распространением ее окончательного релиза компилировать ее с опциями проверки диапазонов. Кому , спрашивается, нужно бестолковое снижение производительности библ-х ф-ций из-за избыточного кода проверок ?


 
Digitman ©   (2003-10-09 12:03) [13]

с той или не с той - неважно)

если ты действительно владеешь док-цией к DLL, приведи дословно ее фрагмент, где описывается декларация проблемного эксп.вызова


 
Digitman ©   (2003-10-09 12:07) [14]

и далее.
если это действительно stdcall, лишний раз не помешает убедиться в этом, при том что ты сомневаешься в корректности реализайии ф-ции

дизассемблируешь ф-цию, ищешь в ее листинге все возвраты из п/п и убеждаешься как минимум в том, что они выглядят как RET 8


 
yaJohn ©   (2003-10-09 12:14) [15]

BOOL ReadInfoBlock(
HANDLE hID,
LPVOID lpBuffer
);


 
Anatoly Podgoretsky ©   (2003-10-09 12:22) [16]

Оп, тогда с чего ты решил, что размер буфера для данной функции равен 1001. Приведи и этот кусок документации. Потом аналогично насчет hID, ты то что нужно передаешь. Про соглашение об вызове я молчу, здесь вообще нет этой информации.


 
Digitman ©   (2003-10-09 12:29) [17]

заодно приведи свой Паскаль-адаптированный вариант этой декларации и фрагмент вызова ф-ции


 
han_malign ©   (2003-10-09 12:33) [18]

Насколько я знаю такого стиля API, либо lpBuffer имеет фиксированную структуру и первое поле у него cbSize(стиль Microsof для совместимости версий, в TAPI, для всех структур переменного размера - три первых поля dwTotalSize, dwNeededSize, dwUsedSize) , либо существует дополнительная функция, типа GetInfoBlockSize, и ты должен гарантировано выделить требуемый размер...
А самонадеянно использовать, самолично придуманный, фиксированный размер - это криминал.


 
nikkie ©   (2003-10-09 12:37) [19]

>han_malign
либо в документации написано что-то вроде
This buffer must be at least MAX_PATH characters in size.

криминал, это точно.


 
yaJohn ©   (2003-10-09 14:01) [20]

Я могу привести примеры кода, цитаты из документации и пр. Но я не прошу найти у меня ошибки! Я и так знаю где они. В ДНК, в стиле программирования, в самонадеяной и кримональной любви к числу 1001, в том что я вообще решил занятся этим ремеслом, в английском (устном и письменном), в формулировках вопросов и т.д. Я не разумею ни альфы ни омеги вин-апи и с соглашениями (декларативными и психологическими) у меня трудности с детства. Мои программы работают только за счет взаимокомпенсации ошибок и фантастической стойкости масдая и борландов к бредовому коду. Я со всем этим согласен заранее и навсегда.

А теперь мне очень хотелось бы узнать, можно ли (и если да то как) создать буфер, такой чтобы при любом (с 3 кольца) обращении (через указатель на оный буфер) за его границы происходило нечто специфическое (например AV), позволяющее утверждать, что это была именно попытка переполнения буфера.

Заранее спасибо.


 
Digitman ©   (2003-10-09 14:49) [21]


> Я могу привести примеры кода, цитаты из документации и пр


тебя, видимо, на коленях надо упрашивать это сделать)


> можно ли


да можно, можно ! но не нужно)

ну зачем ты себе проблемы ищешь там где их нет ?
сильно смахивает все это на бородатый анекдот про мужика, изрядно поддавшего, который ищет потеряный кошелек не там где потерял, а возле фонарного столба, с безапелляционной и убивающей наповал мотивировкой - мол, здесь светлее)

ну зачем его создавать, этот буфер ?

вариант 1:

берешь на вооружение любой более-менее серьезный дебаггер (подойдет и старенький TD32), ставишь аппаратные брейкпойнты в сомнительные точки за пределами диапазона адресов массива (с условием останова при чтении/записи), ловишь брейкпойнты и смотришь адрес инструкции, пытавшейся получить доступ .. если твое предположение подтвердится, то адрес инструкции будет лежать в диапазоне адресов, занимаемых модулем DLL

вариант 2:

средствами обычного дельфийского встроенного дебаггера просто трассируешь в окне CPU инструкции, исполняемые в ходе вызова проблемной ф-ции

дебаггер же - первый друг программера ! неужто в 1-й раз слышишь !?)



Страницы: 1 вся ветка

Текущий архив: 2003.10.23;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.028 c
3-74022
valmont
2003-10-06 09:14
2003.10.23
FILTER


8-74326
oic
2003-06-21 22:08
2003.10.23
Как из делфи отсканировать или сфотографировать рисунок


1-74130
nevalex
2003-10-10 23:18
2003.10.23
Можно ли вытенуть инфу(например темпер.CPU из MainBoardMonitor)


3-74013
P0tia
2003-10-03 13:07
2003.10.23
Сумирование строк


14-74382
Knight
2003-10-02 18:49
2003.10.23
Как вы относитесь к журналу Хакер?