Имеется крохотная программка на MSVC 2015 без CRT. Полный код с проектом лежит на гитхабе (компиляется только релизная версия, для дебажной требуется всякие опции поотключать, чтоб линковалось). Всё делается под Windows 7 x64.
Компилирую программу под 64 бита, запускаю — работает. Какое-то время пользуюсь. В один прекрасный момент очередной запуск внезапно обваливается со знаменитым 0xC0000005. И тут начинается самое интересное: с этого момента все последующие запуски будут выдавать этот 0xC0000005. Не помогает даже перезагрузка системы. Стоит лишь переименовать файл, или как-то его модифицировать (вплоть до правки одного байта хекс-редактором, скажем, инкремент таймштампа в PE-заголовке), или даже просто сменить дату/время модификации, он магическим образом снова начинает запускаться и работать. Потом в какой-то момент ему надоедает, он выкидывает очередной 0xC0000005, после которого см. пункт 1.
Если же я пытаюсь отладить и понять, откуда вообще берётся исключение, отладчик швыряет меня в какие-то дебри системных библиотек, в которых я ни бум-бум. Насколько я смог понять, исключение возникает ещё ДО того, как управление передаётся хотя бы первому байту моего кода. Во всяком случае, моих адресов в стеке нет, а бряки, поставленные на начало wWinMainCRTStartup не срабатывают.
Вот как выглядит ошибка:
Unhandled exception at 0x000000013F4B1000 in hideconsole_hdls_nocrt.exe: 0xC0000005: Access violation executing location 0x000000013F4B1000
BaseThreadInitThunk:
0000000076E559C0 sub rsp,28h
0000000076E559C4 test ecx,ecx
0000000076E559C6 jne BaseThreadInitThunk+16h (076E559D6h)
0000000076E559C8 mov rcx,r8
0000000076E559CB call rdx
Падает, собственно, CALL. rdx тут равен вот этому самому 0x000000013F4B1000, а по этому адресу светятся одни вопросики. Видимо, несуществующая страница, отсюда и access denied. Но как он пришёл к такому состоянию, я не могу понять, не хватает опыта низкоуровневой отладки.
Когда я ради эксперимента переделал проект на CRT-шный, проблемы прекратились, то есть обходной путь найден. Но мне хочется разобраться:
1) Что это за падение? Чем оно может быть вызвано и как его избежать? И почему оно работает-работает, а потом вдруг решает, что с него хватит?
2) Каким-таким волшебным образом система запоминает падучесть программы? Я подозреваю сбой в каком-нибудь prefetch-е, но не знаю, как проверить. Возобновление работы после "обновления" файла явно намекает на какие-то технологии кэширования. Однако в каталоге c:\Windows\Prefetch\ нет ни одного файла с именем, начинающемся на имя моего исполняемого файла.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, CaptainFlint, Вы писали:
CF>Когда я ради эксперимента переделал проект на CRT-шный, проблемы прекратились, то есть обходной путь найден. Но мне хочется разобраться: CF>1) Что это за падение? Чем оно может быть вызвано и как его избежать? И почему оно работает-работает, а потом вдруг решает, что с него хватит? CF>2) Каким-таким волшебным образом система запоминает падучесть программы? Я подозреваю сбой в каком-нибудь prefetch-е, но не знаю, как проверить. Возобновление работы после "обновления" файла явно намекает на какие-то технологии кэширования. Однако в каталоге c:\Windows\Prefetch\ нет ни одного файла с именем, начинающемся на имя моего исполняемого файла.
Варианты:
1. Что то в TLS Callback. Посмотрите, есть ли колбеки в файле, если есть, удалите, чтобы исключить их влияние.
2. Если TLS Callback нет, или после их удаления все равно падает, возможно, кто-то инжектится в процесс (например, тот же Windows Defender или другой антивирус). Попробуйте антивирус отключить, полностью.
Здравствуйте, enigmas, Вы писали:
E>1. Что то в TLS Callback. Посмотрите, есть ли колбеки в файле, если есть, удалите, чтобы исключить их влияние.
Как это посмотреть? TLS Directory в PE-заголовке пустая, это оно?
Сам я точно никаких коллбеков не делал, весь проект — это тупой CreateProcess с ожиданием завершения. Код на полстранички. В проекте тоже ничего необычного не выставлял. По-моему, только entry point (иначе без CRT и не собрать).
E>2. Если TLS Callback нет, или после их удаления все равно падает, возможно, кто-то инжектится в процесс (например, тот же Windows Defender или другой антивирус). Попробуйте антивирус отключить, полностью.
Ок, попробую. Сейчас, после экспериментов оно пока работает, а принудительно вызывать этот сбой не получается.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re: Программа крэшится до точки входа, на стадии загрузки
Судя по содержимому kernel32!BaseThreadInitThunk в Windows 7, call rdx — это прыжок на
точку входа в стартовую функцию потока, т.е. это обычно или threadstartex, или main/WinMain.
Похоже, что или какой-то чужой поток вклинился в работу exe, или кто-то нечаянно подпортил
содержимое регистров при старте процесса (такое в теории может быть при установленных
антивирусах, фаерволах, DLP и т.п. программах).
Можно еще открыть крэш-дамп в WinDBG и выполнить такую команду:
dps @rsp L300
(просмотр "сырого" стека)
или
dps начало конец
(начало и конец стека вытаскиваются командой !teb, см. поля StackBase и StackLimit).
Ну а дальше в стеке попытаться найти "виновника" проблемы, т.е. какой-то
сторонний модуль или функцию.
Re[2]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, okman, Вы писали: O>Судя по содержимому kernel32!BaseThreadInitThunk в Windows 7, call rdx — это прыжок на O>точку входа в стартовую функцию потока, т.е. это обычно или threadstartex, или main/WinMain. O>Похоже, что или какой-то чужой поток вклинился в работу exe, или кто-то нечаянно подпортил O>содержимое регистров при старте процесса (такое в теории может быть при установленных O>антивирусах, фаерволах, DLP и т.п. программах).
Поймал падение, отключил антивирь, падение никуда не делось.
Загрузил файл в WinDbg, стартанул до крэша. В списке загруженных модулей перечислены только Майкрософтовские.
O>Можно еще открыть крэш-дамп в WinDBG и выполнить такую команду: O>dps @rsp L300 O>(просмотр "сырого" стека) O>или O>dps начало конец O>(начало и конец стека вытаскиваются командой !teb, см. поля StackBase и StackLimit). O>Ну а дальше в стеке попытаться найти "виновника" проблемы, т.е. какой-то O>сторонний модуль или функцию.
Увы, виновников не видать. Стек начиная с Base (00140000) забит нулями вверх вплоть до RtlUserThreadStart:
Немножко дополнительной инфы. Я скопировал фейлящийся файл под новым именем (чтобы он перестал фейлиться), тоже загнал в дебаггер и сравнил поведение. В самом начале, в ntdll:RtlUserThreadStart адрес моего кода должен храниться в RCX (потом копируется в RDX). Собственно, при нормальном запуске там правильный адрес (== адресу начала загруженного EXE-модуля + смещение 0x1000), при сбойном — неправильный. Но что любопытно, когда я инициализирую запуск (выставил в Иде останов на самой ранней стадии), RIP указывает на самую первую инструкцию RtlUserThreadStart, и RCX отображается такой, каким должен быть, а в списке загруженных модулей присутствует только мой одинокий EXE. Стоит мне сделать один шаг (инструкция — sub rsp, 48h), как список модулей дополняется стандартными DLL, а RCX неожиданно меняется на фигню (и подсвечивается как модифицированный). В нормальном сценарии запуска с модулями происходит то же самое, но RCX на первом шаге не меняется.
Не знаю, какие можно из этого сделать выводы, но на всякий случай решил написать. Может, конечно, это неточность отладчика (скажем, он уверен, что RCX обязан указывать на начало кода, так что вместо чтения реального значения подставляет туда нужный адрес, а потом опа, оказывается, там с самого начала было что-то другое).
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[3]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, CaptainFlint, Вы писали:
CF>Поймал падение, отключил антивирь, падение никуда не делось. CF>...
Можно попробовать копнуть глубже, если есть желание...
Случись у меня такая проблема, я бы попробовал запустить "сбойную" версию приложения из WinDBG и
поставить точку останова на ntdll!NtTestAlert. А затем, когда она сработает, поискал бы в стеке структуру
CONTEXT — она лежит обычно на самом дне стека и в ней хранятся значения регистров для прыжка на
точку входа, т.е. для RtlUserThreadStart и main/WinMain. Если на входе в NtTestAlert внутри структуры
CONTEXT значение RCX уже указывает не на main/WinMain, либо Rip указывает на что-то другое вместо
RtlUserThreadStart, значит, с вероятностью 99.9%, в запуск процесса вмешиваются "третьи силы".
Если RCX меняется уже после NtTestAlert, т.е. например между NtTestAlert и входом в RtlUserThreadStart, то
это значит, что значение меняется какой-то асинхронной процедурой (APC), т.к. они как раз и доставляются в
этот момент. И этим механизмом частенько пользуются антивирусы и тому подобный софт для внедрения в процессы
своего кода. Иногда и в "отключенном" состоянии тоже.
Re[4]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, okman, Вы писали: O>Можно попробовать копнуть глубже, если есть желание...
Желание есть, но пока не хватает понимания… O>Случись у меня такая проблема, я бы попробовал запустить "сбойную" версию приложения из WinDBG и O>поставить точку останова на ntdll!NtTestAlert. А затем, когда она сработает, поискал бы в стеке структуру O>CONTEXT — она лежит обычно на самом дне стека и в ней хранятся значения регистров для прыжка на O>точку входа, т.е. для RtlUserThreadStart и main/WinMain. <…>
Не могу сообразить, как найти начало структуры CONTEXT. "На самом дне стека" — это где? Прямо от Stack Base? На момент ntdll!NtTestAlert стек выглядит так:
Если верить winnt.h и команде "dt _CONTEXT", структура зело жирная из-за всяких XMM-регистров и занимает 0x4d0 байт. Такой шматок во всём стеке может поместиться лишь где-то в промежутке от StackBase (1b0000) до вызова ntdll!RtlUserThreadStart, но как видно из дампа, там практически одни только нули, лишь перед самым вызовом сидят два ненулевых значения, ни одно из которых на адрес точки входа и близко не походит (а в моём случае RCX всё-таки указывает куда-то поблизости от реальной точки, а не в открытый космос, не говоря уж о том, что RCX находится не у самого края структуры, а в серёдке).
Здравствуйте, CaptainFlint, Вы писали:
CF>Не могу сообразить, как найти начало структуры CONTEXT. "На самом дне стека" — это где? Прямо от Stack Base?
Да, не совсем точно выразился. Вот на примере notepad.exe:
Запускаю из WinDBG процесс C:\Windows\notepad.exe, отладчик останавливается в ntdll!LdrpDoDebuggerBreak,
ставлю точку останова:
bp ntdll!NtTestAlert
и возобновляю выполнение — g
отладчик останавливается:
Breakpoint 0 hit
ntdll!NtTestAlert:
00007ff8`97c33510 4c8bd1 mov r10,rcx
получаем полный стек текущего потока:
!teb
TEB at 000000b194fed000
ExceptionList: 0000000000000000
StackBase: 000000b194d20000
StackLimit: 000000b194d0f000
dp 000000b194d0f000 000000b194d20000
и далее, просматривая полученную "портянку" снизу-вверх, — а там пока одни нули, — ищем
значения 0010001b (ContextFlags), 33 и 2b (сегментные регистры в x64). В моем случае получилось вот что:
Далее проверяем, что это структура CONTEXT. От поля со значением 0010001b нужно отмотать некоторое
количество байт назад (т.к. поле ContextFlags в структуре CONTEXT лежит не в самом начале).
Замечу, что на x64 структура CONTEXT всегда лежит на границе 16 байт:
dt nt!_CONTEXT 000000b1`94d1f320
Надо, чтобы получилось вот так:
...
+0x030 ContextFlags : 0x10001b
...
Остальные поля, т.е. SegCs, SegSs, Rcx, Rsp, Rip и т.д., тоже
должны иметь "осмысленные" значения:
Здесь в SegCs и SegSs будут жестко прошитые константы — 33 и 2b,
в Rcx — адрес main/WinMain (проверить можно командой u адрес),
в Rip — адрес RtlUserThreadStart, а в Rdx — адрес PEB (проверить
можно командой !peb и сравнить).
Если там явный мусор — надо искать CONTEXT дальше (т.е. по тексту вверх).
Re: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, CaptainFlint, Вы писали:
CF>Если же я пытаюсь отладить и понять, откуда вообще берётся исключение, отладчик швыряет меня в какие-то дебри системных библиотек, в которых я ни бум-бум. Насколько я смог понять, исключение возникает ещё ДО того, как управление передаётся хотя бы первому байту моего кода. Во всяком случае, моих адресов в стеке нет, а бряки, поставленные на начало wWinMainCRTStartup не срабатывают.
CF>Вот как выглядит ошибка: CF>
CF>Unhandled exception at 0x000000013F4B1000 in hideconsole_hdls_nocrt.exe: 0xC0000005: Access violation executing location 0x000000013F4B1000
CF>BaseThreadInitThunk:
CF>0000000076E559C0 sub rsp,28h
CF>0000000076E559C4 test ecx,ecx
CF>0000000076E559C6 jne BaseThreadInitThunk+16h (076E559D6h)
CF>0000000076E559C8 mov rcx,r8
CF>0000000076E559CB call rdx
CF>
CF>Падает, собственно, CALL. rdx тут равен вот этому самому 0x000000013F4B1000, а по этому адресу светятся одни вопросики. Видимо, несуществующая страница, отсюда и access denied. Но как он пришёл к такому состоянию, я не могу понять, не хватает опыта низкоуровневой отладки.
На уровне предположения: внешний процесс создал нить с точкой входа в 0x000000013F4B1000, не рассчитав отсутствие в целевом процессе какой-то DLL. Надо при падении посмотреть является ли текущая нить главной нитью этого процесса, для WinDbg команда просмотра нитей с их стеками: ~*k
Если еще удастся поймать падение — сделайте полный дамп для анализа (из WinDbg: .dump /mfh /b dump.cab).
Re[6]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, EreTIk, Вы писали:
ETI>На уровне предположения: внешний процесс создал нить с точкой входа в 0x000000013F4B1000, не рассчитав отсутствие в целевом процессе какой-то DLL. Надо при падении посмотреть является ли текущая нить главной нитью этого процесса, для WinDbg команда просмотра нитей с их стеками: ~*k
Поток один-единственный. (Разве что до бряка успевает создасться, нагадить и завершиться.) Да и как-то странно было бы, что для некоторых запусков (и после модификации файла) эти потоки не создаются (иначе в "нормальных условиях" я бы всегда получал RCX, указывающий не на мою точку входа, а на что-то внешнее, и лишь потом — ещё раз останов уже с моей точкой).
ETI>Если еще удастся поймать падение — сделайте полный дамп для анализа (из WinDbg: .dump /mfh /b dump.cab).
Падение я зафиксировал, для основной работы просто скопировал файлы под другим именем, а "сбойный" оставил без модификаций для дальнейшего анализа.
Вот дамп: https://yadi.sk/d/Od9aQ5hD3SqNxd
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[3]: Программа крэшится до точки входа, на стадии загрузки
CF>Падение я зафиксировал, для основной работы просто скопировал файлы под другим именем, а "сбойный" оставил без модификаций для дальнейшего анализа.
Кто и как (какой функцией) запускает этот процесс?
Re[4]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, EreTIk, Вы писали:
CF>>Падение я зафиксировал, для основной работы просто скопировал файлы под другим именем, а "сбойный" оставил без модификаций для дальнейшего анализа. ETI>Кто и как (какой функцией) запускает этот процесс?
Как минимум, прямой вызов CreateProcess (фактически, я натравил рабочую копию этой же программулины на запуск "сломанной" копии, а там у меня применяется CreateProcess). Также попробовал запустить через альтернативный вариант этой же прожки, где CreateProcess дёргается с другими параметрами (без перезачи STD-хэндлов и с bInheritHandles==FALSE), результат аналогичный (если что, код второй прожки тут).
Среди других способов я не могу с уверенностью сказать, какой API применяется в них, но это: запуск из перлового скрипта (оператор "бэктик" для запуска с чтением вывода stdout), из Total Commander (double-click, Enter), из Проводника, из cmd.exe, из Task Scheduler'а (запуск с повышенными привилегиями при логине — не для этой конкретной программы, но для другой, тоже без CRT, с которой тоже иногда проявляется подобный крэш), из WinDbg (Open executable, Debug -> Go).
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[2]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, CaptainFlint, Вы писали:
CF>>Асмовый код в точке падения: CF>>
CF>>BaseThreadInitThunk:
CF>>0000000076E559C0 sub rsp,28h
CF>>0000000076E559C4 test ecx,ecx
CF>>0000000076E559C6 jne BaseThreadInitThunk+16h (076E559D6h)
CF>>0000000076E559C8 mov rcx,r8
CF>>0000000076E559CB call rdx
CF>>
CF>>Падает, собственно, CALL. rdx тут равен вот этому самому 0x000000013F4B1000, а по этому адресу светятся одни вопросики. Видимо, несуществующая страница, отсюда и access denied. Но как он пришёл к такому состоянию, я не могу понять, не хватает опыта низкоуровневой отладки.
Что-то код выглядит странновато. Вроде sub rsp,28h показывает, что при вызове будет 5 параметров. Но параметры передаются через RCX, RDX, R8, R9 и пятый через стек.
А здесь получается, что запускается подпрограмма как 2-ой параметр? Непонятно. А чуть ниже есть еще какие-нибудь вызовы?
Re[3]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, кт, Вы писали:
кт>Что-то код выглядит странновато. Вроде sub rsp,28h показывает, что при вызове будет 5 параметров. Но параметры передаются через RCX, RDX, R8, R9 и пятый через стек. кт>А здесь получается, что запускается подпрограмма как 2-ой параметр? Непонятно. А чуть ниже есть еще какие-нибудь вызовы?
Вот полный код функции:
BaseThreadInitThunk:
0000000076E559C0 sub rsp,28h
0000000076E559C4 test ecx,ecx
0000000076E559C6 jne BaseThreadInitThunk+16h (076E559D6h)
0000000076E559C8 mov rcx,r8
0000000076E559CB call rdx
0000000076E559CD mov ecx,eax
0000000076E559CF call qword ptr [__imp_RtlExitUserThread (076EDCE88h)]
0000000076E559D5 int 3
0000000076E559D6 test byte ptr [7FFE02D0h],10h
0000000076E559DE je BaseThreadInitThunk+4Fh (076E55A0Fh)
0000000076E559E0 mov rax,qword ptr gs:[30h]
0000000076E559E9 mov rcx,qword ptr [rax+60h]
0000000076E559ED mov rcx,qword ptr [rcx+10h]
0000000076E559F1 call qword ptr [__imp_RtlImageNtHeader (076EDC7C0h)]
0000000076E559F7 test rax,rax
0000000076E559FA je TlsGetValue+178FBh (076E78E9Bh)
0000000076E55A00 mov ecx,8000h
0000000076E55A05 test word ptr [rax+5Eh],cx
0000000076E55A09 je TlsGetValue+178FBh (076E78E9Bh)
0000000076E55A0F xor eax,eax
0000000076E55A11 add rsp,28h
0000000076E55A15 ret
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[4]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, CaptainFlint, Вы писали:
CF>Вот полный код функции: CF>
CF>BaseThreadInitThunk:
CF>0000000076E559C0 sub rsp,28h
CF>0000000076E559C4 test ecx,ecx
CF>0000000076E559C6 jne BaseThreadInitThunk+16h (076E559D6h)
CF>0000000076E559C8 mov rcx,r8
CF>0000000076E559CB call rdx
CF>0000000076E559CD mov ecx,eax
CF>0000000076E559CF call qword ptr [__imp_RtlExitUserThread (076EDCE88h)]
CF>0000000076E559D5 int 3
CF>0000000076E559D6 test byte ptr [7FFE02D0h],10h
CF>0000000076E559DE je BaseThreadInitThunk+4Fh (076E55A0Fh)
CF>0000000076E559E0 mov rax,qword ptr gs:[30h]
CF>0000000076E559E9 mov rcx,qword ptr [rax+60h]
CF>0000000076E559ED mov rcx,qword ptr [rcx+10h]
CF>0000000076E559F1 call qword ptr [__imp_RtlImageNtHeader (076EDC7C0h)]
CF>0000000076E559F7 test rax,rax
CF>0000000076E559FA je TlsGetValue+178FBh (076E78E9Bh)
CF>0000000076E55A00 mov ecx,8000h
CF>0000000076E55A05 test word ptr [rax+5Eh],cx
CF>0000000076E55A09 je TlsGetValue+178FBh (076E78E9Bh)
CF>0000000076E55A0F xor eax,eax
CF>0000000076E55A11 add rsp,28h
CF>0000000076E55A15 ret
CF>
Тогда понятно. Но это может не причина, а уже далекое следствие
По-моему эта функция делает две вещи, в зависимости от 1-ого параметра 0/1. Она или собственно запускает программу или проверяет можно ли ее запустить (т.е. у нее правильный ли заголовок).
Тогда call rdx — это и есть сам запуск программы. Т.е. это всего лишь вызов входной точки в заголовке EXE. А вот почему такой адрес при вызове — это вопрос.
Кстати, Entry Point в заголовке EXE, наверное, не такой?
Может запретить загружать EXE по любым адресам?
Re[5]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, кт, Вы писали:
кт>Тогда понятно. Но это может не причина, а уже далекое следствие
На момент создания темы я этого не знал, отписал то, до чего смог сам докопаться.
кт>По-моему эта функция делает две вещи, в зависимости от 1-ого параметра 0/1. Она или собственно запускает программу или проверяет можно ли ее запустить (т.е. у нее правильный ли заголовок).
кт>Тогда call rdx — это и есть сам запуск программы. Т.е. это всего лишь вызов входной точки в заголовке EXE. А вот почему такой адрес при вызове — это вопрос. кт>Кстати, Entry Point в заголовке EXE, наверное, не такой?
Тут в параллельной ветке уже добрались до того, что ещё до процитированной функции адрес точки входа должен лежать в RCX (в RDX он копируется уже потом), а по факту там лежит что-то другое (хотя и близкорасположенное), указывающее на несуществующую страницу. Причины пока неясны.
кт>Может запретить загружать EXE по любым адресам?
Да, у меня тоже такая мысль возникла. Я уже перекомпилял с соответствующей опцией и вставил этот вариант для постоянного использования, но надо ждать, пока воспроизведётся (если воспроизведётся). Но даже если это починит проблему, хочется понять, что происходит. Починить-то я смог и банальным возвратом CRT.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[6]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, CaptainFlint, Вы писали:
кт>>Тогда понятно. Но это может не причина, а уже далекое следствие
CF>На момент создания темы я этого не знал, отписал то, до чего смог сам докопаться.
кт>>По-моему эта функция делает две вещи, в зависимости от 1-ого параметра 0/1. Она или собственно запускает программу или проверяет можно ли ее запустить (т.е. у нее правильный ли заголовок).
кт>>Тогда call rdx — это и есть сам запуск программы. Т.е. это всего лишь вызов входной точки в заголовке EXE. А вот почему такой адрес при вызове — это вопрос. кт>>Кстати, Entry Point в заголовке EXE, наверное, не такой?
CF>Тут в параллельной ветке уже добрались до того, что ещё до процитированной функции адрес точки входа должен лежать в RCX (в RDX он копируется уже потом), а по факту там лежит что-то другое (хотя и близкорасположенное), указывающее на несуществующую страницу. Причины пока неясны.
кт>>Может запретить загружать EXE по любым адресам?
CF>Да, у меня тоже такая мысль возникла. Я уже перекомпилял с соответствующей опцией и вставил этот вариант для постоянного использования, но надо ждать, пока воспроизведётся (если воспроизведётся). Но даже если это починит проблему, хочется понять, что происходит. Починить-то я смог и банальным возвратом CRT.
Не считаю себя параноиком. Но здесь почему-то мерещится что-то вирусообразное.
Уж больно место нехорошее. Типа подмена вызова программы своим вызовом, но потом что-то идет не так.
Если бы я писал вирус понезаметнее, постарался бы исправить код как раз в этой точке.
Re[7]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, CaptainFlint, Вы писали:
CF>... CF>Эх, как бы эти "третьи силы" теперь ущучить… желательно без ядерного отладчика и без "раздевания" системы от всех установленных программ…
Кажется, я начинаю догадываться, в чем может быть дело.
У приложения нет секции .reloc (релоков), т.е. исполняемый модуль не поддерживает загрузку по произвольному адресу:
(все лишнее поскипано)
> !dh hideconsole_hdls
SECTION HEADER #1
.text name
0 file pointer to relocation table
0 number of relocations
SECTION HEADER #2
.rdata name
SECTION HEADER #3
.pdata name
SECTION HEADER #4
.rsrc name
Но при этом указаны флаги 'Dynamic base' и 'High entropy VA supported', работа которых основывается как раз
на релокациях исполняемого модуля в памяти по рандомным адресам:
OPTIONAL HEADER VALUES
8160 DLL characteristics
High entropy VA supported
Dynamic base
NX compatible
Terminal server aware
Также важно, что в заголовке не указан флаг 'Relocations stripped' (см. опцию /FIXED компоновщика), по которому
система могла бы точно понять, что приложение должно загружаться по строго фиксированному адресу:
FILE HEADER VALUES
22 characteristics
Executable
App can handle >2gb addresses
-> нету здесь больше ничего :)
Косвенно на проблему указывает это: "когда я ради эксперимента переделал проект на CRT-шный, проблемы прекратились".
Как я понимаю, CRT добавляет секцию .reloc.
И еще одно наблюдение (подсмотрено в дампе).
Команда !dh выдает 13f310000 image base, т.е. 13f310000 — предпочтительный адрес загрузки модуля в память.
Сам модуль был загружен (и релоцирован) по адресу 13f720000 (команда lmv m hideconsole_hdls).
А исключение возникло при попытке доступа к адресу 13fb31000 (см. !analyze -v).
Так вот, 13f720000 — 13f310000 = 410000.
Но что интересно, 13fb31000 — 13f720000 = 411000.
Т.е. разница между предпочтительным и реальным адресом загрузки модуля такая же, как между реальным адресом
загрузки и адресом, где произошло исключение. 1000 не в счет, это оффсет от начала загрузки модуля до точки входа.
Вот только я уж и не знаю, баг ли это в системе или в Visual Studio, которая позволяет
задавать "противоречивые" настройки компоновки...
Re[8]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, okman, Вы писали:
O>Кажется, я начинаю догадываться, в чем может быть дело. O>У приложения нет секции .reloc (релоков), т.е. исполняемый модуль не поддерживает загрузку по произвольному адресу:
Вот так находка!
Большущее спасибо, буду разбираться с опциями. Пока что только успел попробовать /FIXED:NO, но он релокаций не добавил (что ожидаемо, ибо это и так умолчальное значение для программ), а на большее времени пока не удалось выкроить. Плюс возникли непонятки, чем вообще отличаются опции /FIXED:NO и /DYNAMICBASE…
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[9]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, CaptainFlint, Вы писали:
CF>Пока что только успел попробовать /FIXED:NO, но он релокаций не добавил (что ожидаемо, ибо это и CF>так умолчальное значение для программ), а на большее времени пока не удалось выкроить.
Релокаций здесь не добавлено, потому что код очень компактный и без CRT.
Видимо, он получился полностью базонезависимым и секция релоков ему просто не нужна.
CF>...чем вообще отличаются опции /FIXED:NO и /DYNAMICBASE…
Когда указан флаг 'FIXED:NO', генерируется секция релоков, но система все равно в
первую очередь будет пытаться загружать модуль по предпочтительному адресу, и
только если это невозможно, например адрес уже занят другим модулем, будет
перемещать его.
Когда указан флаг 'DYNAMICBASE', система сразу пытается загружать модуль по
произвольному адресу (рандомному, см. технологию ASLR). HIGHENTROPYVA добавляет
еще больше рандомности в этот процесс.
Разница, насколько я понимаю, лишь в этом.
Кстати, на последних Виндах можно программно запретить запуск приложений, скомпиленных
без поддержки релоков + ASLR, см. SetProcessMitigationPolicy + ProcessASLRPolicy.
Re[10]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, okman, Вы писали:
CF>>Пока что только успел попробовать /FIXED:NO, но он релокаций не добавил (что ожидаемо, ибо это и CF>>так умолчальное значение для программ), а на большее времени пока не удалось выкроить.
O>Релокаций здесь не добавлено, потому что код очень компактный и без CRT. O>Видимо, он получился полностью базонезависимым и секция релоков ему просто не нужна.
Но ведь если бы он получился базонезависимым, то проблема бы не возникла? Раньше же говорилось: >У приложения нет секции .reloc (релоков), т.е. исполняемый модуль не поддерживает загрузку по произвольному адресу:
O>Когда указан флаг 'FIXED:NO', генерируется секция релоков, но система все равно в O>первую очередь будет пытаться загружать модуль по предпочтительному адресу, и O>только если это невозможно, например адрес уже занят другим модулем, будет O>перемещать его.
O>Когда указан флаг 'DYNAMICBASE', система сразу пытается загружать модуль по O>произвольному адресу (рандомному, см. технологию ASLR). HIGHENTROPYVA добавляет O>еще больше рандомности в этот процесс.
O>Разница, насколько я понимаю, лишь в этом.
Примерно так я и подумал, но потом задумался: а с точки зрения исполняемого файла-то какая разница? Либо он поддерживает загрузку по произвольному адресу, либо не поддерживает. А уж всегда система будет его пытаться перемещать или только иногда — это уже её, системы, дело.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[11]: Программа крэшится до точки входа, на стадии загрузк
Здравствуйте, CaptainFlint, Вы писали:
O>>Релокаций здесь не добавлено, потому что код очень компактный и без CRT. O>>Видимо, он получился полностью базонезависимым и секция релоков ему просто не нужна.
CF>Но ведь если бы он получился базонезависимым, то проблема бы не возникла? Раньше же говорилось: >>У приложения нет секции .reloc (релоков), т.е. исполняемый модуль не поддерживает загрузку по произвольному адресу:
Мне кажется, проблема возникает из-за того, что DYNAMICBASE и/или HIGHENTROPYVA не могут работать правильно,
если у модуля нет релоков. Даже если там полностью базонезависимый код и ему эти релоки не нужны.
Создание модуля без CRT — это сам по себе достаточно редкий сценарий и вряд ли Microsoft тестирует его
так тщательно, как требуется.
Возможно, это какой-то баг в системном загрузчике модулей. Больше пока добавить нечего
Возможно, я вообще заблуждаюсь и на самом деле проблема 0xC0000005 кроется где-то в совершенно другом месте.
Здравствуйте, CaptainFlint, Вы писали:
CF>Но ведь если бы он получился базонезависимым, то проблема бы не возникла? Раньше же говорилось:
Проблема возникает у запускающего процесса: родительскому процессу надо указать точку входа в первую нить процесса. У проблемного файла какой image base указан в заголовке файла на диске? Случайно не 000000013fb30000 == 000000013fb31000 (точка падения) — 1000 (entry point) ?
Re[8]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, okman, Вы писали:
CF>>Эх, как бы эти "третьи силы" теперь ущучить… желательно без ядерного отладчика и без "раздевания" системы от всех установленных программ…
O>Кажется, я начинаю догадываться, в чем может быть дело. O>У приложения нет секции .reloc (релоков), т.е. исполняемый модуль не поддерживает загрузку по произвольному адресу:
Релоки для вызова EntryPoint НЕ НУЖНЫ!
P.S. Дя и судя по всему процесс 64-х битный где с вероятностью 99.9% релоки не нужны и всему остальному (курить мануалы про RIP адресацию).
Здравствуйте, drVanо, Вы писали:
V>Релоки для вызова EntryPoint НЕ НУЖНЫ!
Теоретически, да, не должны быть нужны. Но, возможно, это какой-то баг в загрузчике, который не может корректно обработать смещение точки входа при отсутствии релоков. Во всяком случае, других гипотез, объясняющих накопленные факты, пока не нашлось.
V>P.S. Дя и судя по всему процесс 64-х битный где с вероятностью 99.9% релоки не нужны и всему остальному (курить мануалы про RIP адресацию).
Тем не менее, когда собираю с CRT, таблица релоков появляется.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[12]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, EreTIk, Вы писали:
CF>>Но ведь если бы он получился базонезависимым, то проблема бы не возникла? Раньше же говорилось:
ETI>Проблема возникает у запускающего процесса: родительскому процессу надо указать точку входа в первую нить процесса. У проблемного файла какой image base указан в заголовке файла на диске? Случайно не 000000013fb30000 == 000000013fb31000 (точка падения) — 1000 (entry point) ?
Image base: 0000000140000000
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[10]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, CaptainFlint, Вы писали:
CF>Теоретически, да, не должны быть нужны. Но, возможно, это какой-то баг в загрузчике, который не может корректно обработать смещение точки входа при отсутствии релоков. Во всяком случае, других гипотез, объясняющих накопленные факты, пока не нашлось.
Больше похоже на баг в каком-нить гавноантивирусе.
CF>Тем не менее, когда собираю с CRT, таблица релоков появляется.
Вы бы хоть скинули ссылку на сам бинарник без CRT.
Re[8]: Программа крэшится до точки входа, на стадии загрузки
O>OPTIONAL HEADER VALUES
O> 8160 DLL characteristics
O> High entropy VA supported
O> Dynamic base
O> NX compatible
O> Terminal server aware
O>
O>Также важно, что в заголовке не указан флаг 'Relocations stripped' (см. опцию /FIXED компоновщика), по которому O>система могла бы точно понять, что приложение должно загружаться по строго фиксированному адресу:
Насколько я знаю 'Relocations stripped' вообще никак не влияет на загрузку имейджа по разным адресам. Влияет только 'Dynamic base'
Re[11]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, drVanо, Вы писали:
CF>>Теоретически, да, не должны быть нужны. Но, возможно, это какой-то баг в загрузчике, который не может корректно обработать смещение точки входа при отсутствии релоков. Во всяком случае, других гипотез, объясняющих накопленные факты, пока не нашлось.
V>Больше похоже на баг в каком-нить гавноантивирусе.
Проявляется одинаково на двух машинах. На одной KAV, на другой только предустановленный Defender. Оба пробовал отключать, безрезультатно (хотя понимаю, что без деинсталляции это неполная проверка).
CF>>Тем не менее, когда собираю с CRT, таблица релоков появляется.
V>Вы бы хоть скинули ссылку на сам бинарник без CRT.
По заголовкам видно, что хоть релоков нет ни у одного из бес-CRT-шных вариантов, флаг IMAGE_FILE_RELOCS_STRIPPED имеется только у /FIXED. Именно этот вариант я сейчас использую как основной, и он пока ни разу не падал.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[12]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, CaptainFlint, Вы писали:
CF>На всякий случай, выкладываю прочие тестовые варианты: CF>с CRT: https://yadi.sk/d/g-PEPVaO3T3g55 CF>без CRT, /DYNAMICBASE:NO /FIXED:NO : https://yadi.sk/d/4rDSscRR3T3g5B CF>без CRT, /DYNAMICBASE:NO /FIXED : https://yadi.sk/d/ZGUM0H-f3T3g5D
CF>По заголовкам видно, что хоть релоков нет ни у одного из бес-CRT-шных вариантов, флаг IMAGE_FILE_RELOCS_STRIPPED имеется только у /FIXED. Именно этот вариант я сейчас использую как основной, и он пока ни разу не падал.
Конечно их нет при "/DYNAMICBASE:NO"
Re: Программа крэшится до точки входа, на стадии загрузки
Кажется, мелочь одну забыли глянуть. Когда падает — по указанному адресу память не выделена (в отладчике вопросительные знаки). Но в этом случае по заданному ENTRY POINT адресу все нормально?
Там действительно адрес первой команды?
Re[2]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, кт, Вы писали:
кт>Кажется, мелочь одну забыли глянуть. Когда падает — по указанному адресу память не выделена (в отладчике вопросительные знаки). Но в этом случае по заданному ENTRY POINT адресу все нормально? кт>Там действительно адрес первой команды?
Если взять адрес, по которому загружен модуль (с точки зрения отладчика), и перейти по этому адресу +1000, то да, там мой код.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[3]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, CaptainFlint, Вы писали:
CF>Если взять адрес, по которому загружен модуль (с точки зрения отладчика), и перейти по этому адресу +1000, то да, там мой код.
Ожидаемо, но и непонятно. Отладчик ведь не сам загружает файл, а выполняет стандартные действия операционной системы. При этом все нормально, файл загрузился на "свое" место. И вдруг вместо Entry Point только что загруженного файла вызов по непонятному адресу. Разгадка должна находиться где-то в предыдущей сотне выполненных команд.
Re: Программа крэшится до точки входа, на стадии загрузки
Когда не крэшится, запуститесь по windbg и выполните в нем команду:
sxe ld
..и проследите какие модули будут подгружаться в ваш процесс. Все очень похоже на крэш изза когото кто извне заинжектить чета пытается. Первое подозрение — на security сьюты
Как много веселых ребят, и все делают велосипед...
Re: Программа крэшится до точки входа, на стадии загрузки
Что-то вылетела у меня из головы эта темка… Поковырялся и забыл. Чтобы не висела совсем уж в воздухе, отпишусь тут о результатах.
В итоге я попробовал взять исходный проблемный файл, в котором и динамическая база, и релоков нет, и флага об отсутствии релоков нет, и просто воткнуть прямо в заголовок скомпилированного файла этот флаг (IMAGE_FILE_RELOCS_STRIPPED). Сделал это уже давно (не меньше месяца назад), и до сих пор оно больше ни разу не падало, а используется эта утилитка очень активно. Думаю, гипотезу о влиянии флага на загрузчик можно считать подтверждённой.
Разумеется, остаётся открытым вопрос, почему оно вообще идёт вразнос, когда флага нет, но, видимо, это можно списать на какой-то внутренний виндобаг, где разработчики просто не учли такой сценарий. На будущее буду иметь в виду такую особенность и либо править проект, чтоб после сборки флаг автоматом добавлялся, либо ручками выставлять его в хекс-редакторе.
Спасибо всем за помощь и участие!
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[2]: Программа крэшится до точки входа, на стадии загрузки
CF>В итоге я попробовал взять исходный проблемный файл, в котором и динамическая база, и релоков нет, и флага об отсутствии релоков нет, и просто воткнуть прямо в заголовок скомпилированного файла этот флаг (IMAGE_FILE_RELOCS_STRIPPED). Сделал это уже давно (не меньше месяца назад)
это отключает ASLR
а падало потому что винда в процессе работы может образ файла двигать в памяти
Re[3]: Программа крэшится до точки входа, на стадии загрузки
R>вы дебагером когда нибудь пользовались ? R>в нём это хорошо видно
Как-то не догадывался запоминать и сравнивать адреса модулей в процессе отладки. А пруфа в печатном виде нет, случаем?
Но всё равно не верится, что это возможно. К примеру, возьмём среднестатический бинарик со статическим, опять же, объектом. И ссылку на него (ака адрес).
Если система вдруг вздумает переместить модуль по другому адресу в памяти, то адрес объекта станет недействительным.
Re[3]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, reversecode, Вы писали:
CF>>В итоге я попробовал взять исходный проблемный файл, в котором и динамическая база, и релоков нет, и флага об отсутствии релоков нет, и просто воткнуть прямо в заголовок скомпилированного файла этот флаг (IMAGE_FILE_RELOCS_STRIPPED). Сделал это уже давно (не меньше месяца назад)
R>это отключает ASLR R>а падало потому что винда в процессе работы может образ файла двигать в памяти
А каким макаром ASLR к отсутствию релоков? Казалось бы, наоборот, ничего релоцировать не надо, хочешь — двигай. Собственно, оно и двигало, только забывало известить вторую свою же половину о собственных движениях.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[6]: Программа крэшится до точки входа, на стадии загрузки
F>Как-то не догадывался запоминать и сравнивать адреса модулей в процессе отладки. А пруфа в печатном виде нет, случаем?
какой пруф ? те кто пользуются к примеру IDA, могут видеть это как частый rebase модулей или самого приложения
на форуме новички которые любят чего то подламать в приложениях, приходят и плачут как у них ничего не выходит
и им часто раньше советовали отключать ASLR
F>Но всё равно не верится, что это возможно. К примеру, возьмём среднестатический бинарик со статическим, опять же, объектом. И ссылку на него (ака адрес). F>Если система вдруг вздумает переместить модуль по другому адресу в памяти, то адрес объекта станет недействительным.
я здесь не для того что бы тратить время на доказательства
Re[4]: Программа крэшится до точки входа, на стадии загрузки
CF>А каким макаром ASLR к отсутствию релоков? Казалось бы, наоборот, ничего релоцировать не надо, хочешь — двигай. Собственно, оно и двигало, только забывало известить вторую свою же половину о собственных движениях.
Изучил, ответа на вопрос не нашёл. Просто повторяется то же самое: нет ножек релоков — нет ASLR.
В моём представлении релокации в файле отсутствуют в двух случаях:
а) fixed base, код завязан на конкретный адрес и не умеет релоцироваться в принципе;
б) PIC (position-independent code), релоки не нужны, потому что везде используется только относительная адресация.
Я полагал, что флаг IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE как раз и служит для различения этих ситуаций. А получается, он тупо дублирует IMAGE_FILE_RELOCS_STRIPPED. Как вообще тогда объяснить системе, что вот в этом конкретном файле релоков нет, потому что они просто не нужны, и код можно спокойно перемещать?
Или винда в принципе не признаёт понятия PIC?
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[3]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, reversecode, Вы писали:
R>а падало потому что винда в процессе работы может образ файла двигать в памяти
R>частый rebase модулей или самого приложения
O>>Звучит как ересь O>>
R>или вам пора на переквалификацию
Может быть.
Но перемещение исполняемого модуля в а.п. пространстве процесса прямо во время его выполнения у меня не укладывается в голове и
за несколько лет я такого ни разу не видел. А что происходит тогда с указателями на функции, которые уже кто-нибудь успел вычислить
(GetProcAddress/static import)? А с базой модуля (HMODULE/HINSTANCE)? А с секцией (дисковая проекция исполняемого файла)? Она тоже
вдруг отмапливается и замапливается обратно по другому адресу? А потоки, которые выполняют код внутри exe/dll — они останавливаются и
их Rip/Eip двигаются на другие адреса? И в какой версии Windows это появилось? Ну дайте больше деталей (или ссылку на достаточно
авторитетный источник), где это было бы описано. А еще лучше — код, который подтверждает эту м-м... гипотезу. В источниках, которым я
доверяю (MSDN/TechNet, Windows Internals и т.д.) сказано, что ASLR для модулей работает во время загрузки, после этого адрес не меняется.
А для системных dll адрес сохраняется постоянным до следующей загрузки компьютера. Что я и наблюдаю в отладчике еще со времен Windows Vista.
Пока могу представить только один кейс: FreeLibrary/LoadLibrary модуля, скомпиленного с поддержкой reloc/ASLR.
Но это совсем другая ситуация, чем "двигание" модуля в памяти уже после его загрузки.
А то сначала порвать шаблон, а затем сразу давать задний ход в стиле "я здесь не для того что бы тратить время на
доказательства" — это как-то не очень...
Re[7]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, reversecode, Вы писали:
R>на форуме новички которые любят чего то подламать в приложениях, приходят и плачут как у них ничего не выходит R>и им часто раньше советовали отключать ASLR
ASLR — это перемещение модулей в процессе их загрузки в АП процесса, но не в процессе работы. Видимо, речь об этом, всё же.
Re[8]: Программа крэшится до точки входа, на стадии загрузки
Здравствуйте, flаt, Вы писали:
F>Здравствуйте, reversecode, Вы писали:
R>>на форуме новички которые любят чего то подламать в приложениях, приходят и плачут как у них ничего не выходит R>>и им часто раньше советовали отключать ASLR
F>ASLR — это перемещение модулей в процессе их загрузки в АП процесса, но не в процессе работы. Видимо, речь об этом, всё же.
советую по чаще пользоваться дебагером что бы знать не только теорию но и практику
в процессе работы винда может двигать модули
до введения ASLR этих движений не было по моим наблюдениям
Re[9]: Программа крэшится до точки входа, на стадии загрузки
R>советую по чаще пользоваться дебагером что бы знать не только теорию но и практику R>в процессе работы винда может двигать модули R>до введения ASLR этих движений не было по моим наблюдениям
Винда не может двигать уже загруженный модуль. ASLR влияет на базу загрузки модуля, после загрузки — все остается где было до выгрузки. Если у вас изза включения ASLR для дллки чтото начинает глючить, значит или у вас гдето есть чтото типа:
В этом случае на последней строчке с включенным ASLR вероятность крэша на много порядков выше чем с выключенным. Но, всеже, с выключенным она тоже будет ненулевая.
Или же у вас код который не умеет толком работать с void *, например
в этом случае тоже вероятность свалиься с ASLR сильно выше чем без оного. Потому что с ASLR вероятность того что модуль загрузится выше первых 4 гиг очень высока (оно вроде вообще только туда и грузит ASLR'ед дллки), а без оного — система попытается промапить модуль по его preferred base. Что обычно находится в нижних адресах.
А тайпкаст в 32х битную переменную (int) ломает поинтеры указываюшие выше 4 гиг.
Но в данном случае имеем дело не с длл, а с апликухой, в которой даже релоков нет. И вероятно это в самом деле баг загрузчика, т.к. такие минималистичные апликухи нынче редкость, а микрософт индусами полнится. Или же у ТС троянчик сидит, или антивирь. С глючным инжектором. Потому хотелось бы увидеть лог windbg о том какие длл в процесс и в каком порядке загружаются.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, ononim, Вы писали:
O> Или же у ТС троянчик сидит, или антивирь. С глючным инжектором. Потому хотелось бы увидеть лог windbg о том какие длл в процесс и в каком порядке загружаются.
К сожалению, у меня сейчас пошёл основательный загруз сразу по нескольким направлениям, так что времени на академические исследования в ближайшем будущем точно не найдётся. Если достаточно просто загрузить и выдать лог, это ещё могу сделать (только желательно с инструкциями, а то я в windbg не очень, а тратить время ещё и на поиск инфы не хочется). Если же надо конкретно в сценарии с воспроизведением падения — тогда вряд ли получится.
Но всё же, что касается трояна или антивиря, вероятность с моей точки зрения крайне невелика. Две разных машины, с разными антивирями от разных производителей, у обоих воспроизводится в отключённом без перезагрузки виде. То есть они оба должны одинаково ломать загрузчик, причём делая это именно теми компонентами, которые остаются загруженными в память при выключении проверочной функциональности. Не исключено, но всё же сомнительно.
Троян… Опять же, одинаковый на обеих системах, живущий на них незамеченным не менее двух лет, и ни разу не пойманный ни мной (а я несколько раз основательно шуршал по системе, заметив что-то, показавшееся подозрительным), ни теми же антивирями? Точно так же, не исключено, но как-то не верится.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[11]: Программа крэшится до точки входа, на стадии загрузк
Как вариант кстати баг возможно даже не лоадера, а линкера. Лоадер, к примеру, может ожидать, что раз нету флага IMAGE_FILE_RELOCS_STRIPPED — значит релоки есть. А линкер этот флаг не выставляет, несмотря на отсутствие релоков в имаже. Все зависит от того растусована ли както такая ситуация в спецификации.
А про глючные инжекторы секуритисьютов я неспроста писал. Я сам писал такие инжекторы, которые, бывало, глючили
Как много веселых ребят, и все делают велосипед...