![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
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, кстати ?