С виду простой вопрос, но что-то ничего не нашёл по этому поводу нигде. Вот кусок кода Код (Text): invoke IsBadReadPtr, edi, sizeof DWORD xor esi, esi test eax, eax cmovz esi, dword ptr [edi] ; <- здесь access violation Регистры и флаги Код (Text): EAX = 00000001 OV = 0 UP = 0 EI = 1 PL = 0 ZR = 0 AC = 0 PE = 0 CY = 0 то есть получается, что указатель разыменовывается в любом случае, выполняется присвоение или нет. И если это так, то можно ли как-то обойти, не используя ветвление
Код (Text): dwNull dd 0 invoke IsBadReadPtr, edi, sizeof DWORD test eax, eax cmovnz edi, offset dwNull mov esi, [edi]
Нужно смотреть псевдокод в манах, вот для CMOVcc(x64 я опустил): Код (Text): temp <- SRC IF condition TRUE THEN DEST <- temp; FI; Тоесть вначале во временный регистр читается переменная, затем она в зависимости от условия переносится в RGP. Поэтому независимо от условия будет выполнен доступ к переменной, тоесть все проверки безопасности. Разумеется при этом генерится #AV, если проверки не прошли. Стоит заметить что если в IsBadReadPtr() передаётся нулевой указатель, то функция возвратит ноль, тоесть какбы успешно выполнится(аналогично как и в ядре ProbeForRead()). Можно использовать префикс rep: Код (Text): invoke IsBadReadPtr, Esi, sizeof DWORD test eax,eax setz cl movzx ecx,cl rep lodsd
Я просто не знал, что псевдокод описывает ситуацию и в случаях с исключениями а так не менее производительно?
sergegers Вы наверно шутите ? Какая оптимизация может быть, если вы в юзермоде, да есчо и винапи юзаете