Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Exception внутри IsBadReadPtr (kernel32)


ZeroDivide ©   (2005-12-08 12:42:00) 

Бага проявляется на некоторых машинах с 2000, XP.
Это из за чего? И что делать?


ZeroDivide   (2005-12-08 16:44:00) [1]

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


ZeroDivide   (2005-12-08 16:35:00) [2]

Правельнее было бы, ИМХО
if ValidCodeAddr then
 if not IsBadReadPtr then

Если дело действительно в этом. В хелпе ни какого ограничения на
CONST VOID *lp, // address of memory block - нет.


Digitman   (2005-12-08 16:14:00) [3]


> IsBadReadPtr будет вызываться для любого CodeAddr


как видно из кода, как раз НЕ для любого - только для (CodeAddr > 8) + только для (ValidCodeAddr) = True ..

причем состояние опции Complete Boolean Eval  проекта JEDI-пакета при его сборке тоже будет играть в этой строчке немаловажную роль


ZeroDivide   (2005-12-08 15:53:00) [4]


> а в целом - не посмотреть ли тебе, как та же самая задача
> решается (с успехом) в JEDI ?


Из JCL

function TJclStackInfoList.ValidCallSite(CodeAddr: DWORD; var CallInstructionSize: Cardinal): Boolean;
var
 CodeDWORD4: DWORD;
 CodeDWORD8: DWORD;
 C4P, C8P: PDWORD;
begin
// First check that the address is within range of our code segment!
 C8P := PDWORD(CodeAddr - 8);
 C4P := PDWORD(CodeAddr - 4);
 Result := (CodeAddr > 8) and ValidCodeAddr(DWORD(C8P), FModuleInfoList) and not IsBadReadPtr(C8P, 8);
......


Как видно, IsBadReadPtr будет вызываться для любого CodeAddr, по идее проблема должна быть и здесь.

А вот еще интересная строчка из JCL
if not IsWinNT and not IsBadReadPtr(Pointer(ADR_BIOSCOPYRIGHT), 2) then


> Могу порекомендовать использовать IsBadCodePtr

Угу, и вызвать ее 5 раз :) В IsBadReadPtr указывается число байт (вторым параметром), если к части из них нет доступа, то она вернет True.

А тот комп, где AV происходит, часом не ADM64 и не XP SP2 там ?
На одном XP SP2, на другом w2k.... :(

Таким образом DEP срабатывать не может ?
Без понятия, может быть.


Игорь Шевченко   (2005-12-08 14:10:00) [5]


> К тому же, на своем компе ни разу не получал его.


А тот комп, где AV происходит, часом не ADM64 и не XP SP2 там ?
Таким образом DEP срабатывать не может ?

Могу порекомендовать использовать IsBadCodePtr


Digitman   (2005-12-08 14:03:00) [6]


> ZeroDivide ©   (08.12.05 13:40) [2]



> только (очевидно) при определенных аргументах


ну так заключи ф-цию в Try..Except да протоколируй (с целью последующего анализа) аргументы, при которых управление в рез-те искл-я передается в except-блок !

куда уж проще решение)..

а в целом - не посмотреть ли тебе, как та же самая задача решается (с успехом) в JEDI ?


ZeroDivide   (2005-12-08 13:40:00) [7]

IsBadReadPtr используется в функции трассировки стека для отображения истории вызовов процедур.


> а что за Exception, кстати ?

AV :)


> пройтись в отладчике пошагово по "потрохам" ф-ции
>

Сложно. Exception возникает не всегда, к сожалению, а только (очевидно) при определенных аргументах. К тому же, на своем компе ни разу не получал его.

Вот кусок кода

   SAddr := DWORD(Ptr(StackPtr)^);
   Dec(SAddr, 5);
   CallPtr := Ptr(SAddr);
   if IsBadReadPtr(CallPtr,5) = False then // AV здесь
   begin
     CallData := BYTE(CallPtr^);
     if CallData = $E8 then
     begin
       ComStr := 'Near Address Call';
       ...............
       Result := True;
     end;
   end;


Digitman   (2005-12-08 12:48:00) [8]


> Это из за чего?


сложно сказать ... возможно даже и из-за сервиспаков ...


> что делать?


пройтись в отладчике пошагово по "потрохам" ф-ции

а что за Exception, кстати ?


Наверх

Титульная страница Поиск, карта сайта Написать письмо