Вот тут http://files.virustech.org/indy/Code/NtMapViewOfImage/ находятся сорсы одной проги написаной Indy Clerk'ом при исследовании родились вопросы. 1. Почему Инди использует int 2eh, а не sysenter. Может для совместимости с 2к или обхода какой то проактивки? Может префиксы только к int можно поставить ? 2. Пото еще пишет вроде базонезависимый код, но вызывает call. При компелации там же будет виртуальный адрес. Почему он так пишет, ведь у него был макросс $CALL с релатив вызовом. Код (Text): $NtMapViewOfSection macro movzx eax,[ebx]._NtMapViewOfSection Call SystemStubEntry lea esp,[esp + 10*4] endm 3. Почему он так сильно использует сегменты. Они же раны нулю в ринг3. Я конечно знаю что их можно изменить посредством добавления в LDT из функции ntdll.dll. Но почему? может он их собирается изменить ?
19841204 Оо хм. Там старые коды. Отвечаем: 1. При возврате из быстрых вызовов(посредством Sysenter) адрес возврата фиксирован, это ntdll.KiFastSystemCallRet. В таком случае все сервисы будут отслежены из юзермода просто брейком на этот адрес, чего быть не должно. Поэтому юзается 0x2E шлюз. 2. В моём понимании базонезависимый код(пикод) это тот, для которого не имеет значения смещение в сегменте. По сему Call near относительное ветвление и не привязано к базе сегмента. 3. Есть некоторые нюансы связанные с трассировкой.
Clerk То, что call near не привязан к базе сегмента, — это, конечно, верно, но никакого отношения к базонезависимости не имеет. Важно то, что он не привязан к базе загрузки самого кода, а не к базе сегмента, в котором находится этот код. P.S. И можно наконец перестать называть все инструкции передачи управления ветвлениями? Если с "пикодом" ещё можно мириться, то "процедурное ветвление" звучит настолько ужасно, что даже не смешно. Ветвление подразумевает несколько различных вариантов исполнения в зависимости от некоторого условия. Т.к. call является инструкцией безусловной передачи управления, то к ветвлениям отношения не имеет.
l_inc База загрузки кода определяется смещением в сегменте. Тоесть 0:Offset. Это и сказано выше. С точки зрения графа инструкция Call такаяже как и Jnz по сути. Тоесть ветвление, процедурное.
Clerk Согласен. Не согласен. Не соответствует фразе: Про базу сегмента вижу. Про смещение в сегменте не вижу... Ну да ладно. С точки зрения графа исполнения? По какой это сути она "такаяже", если call допускает единственный вариант исполнения, а jnz провоцирует настоящее ветвление в графе?
l_inc Ну мб написал не так про смещение. Подразумевалась базовый адрес загрузки кода. По той сути, что при трассировке графа никакие флажки не учитываются. Вобще незачем к словам цепляться. Какие термины использую, те и буду использовать. Вы альтернативы не предложили, как и вобще ничего по теме.
Clerk Я бы и не придирался, если бы использование Вашей альтернативной терминологии не провоцировало недопонимание. А вообще Ваше право, конечно. Альтернатива? Как насчёт общепринятых "вызов подпрограммы/процедуры" или "инструкция вызова подпрограммы/процедуры"?
l_inc Когда вы будите долго размышлять над чемто, у вас появится необходимость обобщения. Для этого термины и нужны. Вы ведь меня без труда понимаете, иначе не поправляли бы опечтки Вызов подпрограммы или процедуры не отражает суть. Тогда процедура рассматривается как отдельная от текущей. Какраз к дельта-смещению это и не подходит. Процедуры то нет: Call $+5/pop eax - какая тут подпрограмма. Процедуры связывает стек. В графе нет понятия стека. Именно поэтому при трассировке графа число процедурных ветвлений не соответствует числу Ret-в. Думаю понятно почему. Тут нет понятия процедуры. Меняйте свои взгляды вобщем.
Clerk Общепринятые названия инструкциям даны согласно цели, для которой они проектировались. Несмотря на то, что для call можно найти извращённые применения вроде получения eip, проектировалась она для вызова подпрограмм, о чём свидетельствует сама её мнемоника. Я не строю свои взгляды по поводу наименований, а принимаю общепринятые, поэтому не вижу смысла их менять. Хотя, как я уже сказал, если Вам нравится придумывать собственную терминологию в противовес существующей и в поддержку извращённых (не предусмотренных) применений, это Ваше право. К тому же Вы ведь сами называете call "процедурным ветвлением", несмотря на то, что по Вашим словам "процедуры то нет". Если не убедил, ну и ладно.
l_inc Вот код, который загружает ссылку на процедуру: Код (Text): Callback proc ... Callback endp ; ~~~~~~~~~~~~ ... Call Dt Dt: pop eax add eax,(offset Callback - offset Dt) ... ; Eax = @Callback Выполняющий тоже, но немного изменённый: Код (Text): Load: pop eax ret GetRef: Call Load ; ~~~~~~~~~~~~ Callback proc ... Callback endp ; ~~~~~~~~~~~~ ... Call GetRef ... ; Eax = @Callback Зачем во втором случае столь извращённо по вашему ссыль определяется и как назовём два типа кода этого ?
Clerk Зачем здесь это делается, не знаю, но в первом случае в call четыре байта нулей, а во втором случае код будет состоять из печатаемых ASCII-символов. Сам похожим образом делал получение дельты в печатаемом коде (кстати, Вам же пример и приводил). Называть именно оба куска кода? Вообще кусок кода не так уж и часто требует собственное название в отличие от инструкции. В данном случае оба куска кода есть не более, чем "базонезависимое получение указателя на процедуру Callback". Если речь о наименовании call, то я при своих: "инструкция вызова подпрограммы".
l_inc Вот если не понимаете разницы, как можите судить про то, как я называю инструкцию Call. Когда осознаете буду рад обсудить.
Clerk Если не ошибаюсь, я привёл пример разницы. И таких разниц, думаю, можно придумать ещё немало, поэтому можно ещё долго играть в "найдите десять отличий между ромашкой и унитазом". Кстати, надеюсь, речь не том, какой из них "пермутирующий".
l_inc Именно второй пермутирующий. Первый пикод, второй микод. Инструкция Call Load является одним целым с калбэком. Это очень важно, иначе после перестройки код будет не рабочим. Вы видите мелочи, но не можите увидеть главного. Термины такими и остануться, Call - процедурное ветвление, Jxx/Loop/Jcxz - условные ветвления, Jmp - безусловные. Int, Ret, Iret, Retf, Int3 и всякие иные инструкции - линейные.