Перейти к содержимому

Entry point testing что это

  • автор:

Entry Point Testing

Фотография

Скажите, в чем заключается суть этого вида тестирования. Спасибо.

#2 BadMF

Отправлено 10 сентября 2014 — 12:37

и откуда эта мода называть любую ерунду «видом тестирования».

«Входные точки» приложения сильно зависят от приложения, и в большинстве случаев речь идёт не о ГУИ тестировании, хотя и ГУИ тестирование, с большой натяжкой, является входной точкой.

Тестирование входных точек, это тестирование приложения на предмет корректности приёма входных данных и ожидаемых состояний на выходе.

#3 bagsbunny

Отправлено 10 сентября 2014 — 17:22

и откуда эта мода называть любую ерунду «видом тестирования».

«Входные точки» приложения сильно зависят от приложения, и в большинстве случаев речь идёт не о ГУИ тестировании, хотя и ГУИ тестирование, с большой натяжкой, является входной точкой.

Тестирование входных точек, это тестирование приложения на предмет корректности приёма входных данных и ожидаемых состояний на выходе.

Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных

Ответить цитируемым сообщениям Очистить

  1. Форум тестировщиков
  2. → Тестирование
  3. → Начинающему тестировщику
  4. Политика Конфиденциальности
  5. Правила форума ·

  • RSS поток
  • Помощь

Entry Point

An executable statement or process step which defines a point at which a given process is intended to begin.

Present in sylabi

Original definition: Entry Point @ISTQB Glossary

Share this page

Translations and synonyms

Recommend more content related to this term

Browse by Syllabus

gbdeitfrjpbrplptruczskdksenlhunokr

Got praise, complaint or idea? Feedback is very welcome!

Source: official ISTQB Glossary This page was created, because the original one is notoriously hard to work with.

Based on Bare Hugo theme. Blog source code available on Github.

Статья Entry Point – дело о пропавшем индексе (часть 1)

Термин EntryPoint знаком каждому программисту – это адрес точки входа в программу, т.е. первой инструкции исполняемого кода. Компиляторы прошивают этот адрес в РЕ-заголовок по смещению 28h , а системный «загрузчик образов» потом считывает его от туда, и передаёт на него управление. Такому алгоритму следуют все LDR-загрузчики, начиная с Win98 и до наших дней. Сам загрузчик оформлен в виде функции LdrpInitializeProcess() из библиотеки Ntdll.dll.

В данной статье рассмотрим несколько способов реализации фиктивных точек EntryPoint, что позволит защитить наши программы от взлома и отладки. Например зачем выставлять на показ процедуру проверки введённого пароля, или какой-нибудь авторской техники? До тех пор пока она не станет достоянием общественности, мы сможем использовать её в своих программах снова и снова. Но как-только корабль даст течь, придётся латать дыры, на что нужно время, которого всегда не хватает.

Проблема в том, что если в наших планах написать использующее системные механизмы кроссплатформенное приложение, то мы непременно столкнёмся с трудностями. Связано это с тем, что детали реализации того-же загрузчика отличаются на разных осках, хотя и исповедуют идентичные концепции. Конечно-же можно протестить все версии Win от хрюши до десятки и создать базу фундаментальных особенностей, но это не наши методы – слишком сомнительной будет репутация у такого приложения. Правильным решением будет поиск необходимых сигнатур по ходу дела в реальной обстановке, на что и сделаем ставку.

Места обитания точки-входа

Найти и хакнуть EntryPoint не проблема, гораздо трудней скрыть сам факт подмены. Такие отладчики как WinDbg, Syser, OllyDbg сейчас доступны всем и подняли с горшка не одно поколение начинающих крэкеров. Даже беглый анализ приложения может сразу выявить подвох, что сведёт на-нет все наши планы. К примеру, вот окно утилиты «DiE» для сбора информации об исполняемом файле, где как феникс из пепла восстаёт адрес EP:

die.png

Все утилиты подобного рода, в числе которых PeTools, PEiD и прочие, черпают информацию из заголовка дискового файла. Если мы хотим скрыть от них фактическую точку-входа в программу, то не должны трогать поля РЕ заголовка – пусть тулзы и оседлавшие их взломщики думают, что это типичный файл дилетанта, который можно вскрыть одним пальцем. Отличной идеей будет перехват и правка EntryPoint в динамике, непосредственно в процессе загрузки образа в память — это гораздо труднее обнаружить и мы выполним свою задачу(х). Смещения базы и точки-входа в заголовке представлены ниже (указатель на РЕ лежит по смещению 0х3С от начала образа):

ep_0.png

Здесь видно, что в поле РЕ.28h зашито значение 0х00002000 – это т.н. Relative_Virtual_Address (RVA). Что будет, если сбросить его в нуль? Тогда точкой-входа получится базовый адрес 0х00400000 , поскольку RVA представляет из-себя адрес относительно базы. А что у нас лежит по этому адресу в памяти? Правильно.. тот-же РЕ-заголовок, под который загрузчик имиджей выделяет целую страницу виртуальной памяти так, что первая секция экзешника всегда начинается по смещению Base+1000h (одна страница = 1000h или 4Кб, хвост забивается нулями):

peMem.png

На этом этапе, «горячие головы» ринулись-бы подменять EntryPoint в заголовке находящегося в памяти файла, и.. обломались-бы по полной! Здесь и начинается самое интересное..

Детали системного лоадера LDR

Дело в том, что загрузчик образов считывает значение EntryPoint из РЕ.28h только один раз, на начальном этапе своей работы, и больше к заголовку не обращается вообще. Получив точку-входа, загрузчик кидает её на самое дно стека, а завершающая работу лоадера функция ZwContinue() потом использует это значение как свой аргумент, передавая на неё управление.

Кстати функция Nt/ZwContinue() является подопечной диспетчера исключений – он использует её для возобновления работы потока, после обработки ошибок. На системах х64 вместо неё используется функция RtlRestoreContext() . Вот как выглядит стек в отладчике, когда он только загрузил клиента и не сделал ещё ни одного шага:

dualStack.png

Судя по рисунку, алгоритм работы загрузчиков XP и семёрки отличается. В частности на семке маячат две точки-входа, в то время-как хрюше достаточно одной.

Но в любом случае, если мы получим указатель на дно стека, то двигаясь вверх (назад) можно найти адрес EntryPoint’a перебором всех значений, предварительно сформировав для этого сигнатуру поиска – в данном случае это значение 0х00402000 . Такой финт будет работать на любой системе и получим кросплатформенность. Указатель на дно стека система прописывает в структуре ТЕВ по смещению 04h , что демонстрирует отладчик WinDbg:

teb_Stack.png

Рассмотрим такой код..
Позже мы оформим его в виде процедуры, а пока это просто демонстрация того, как можно получить сигнатуру поиска EntryPoint в стеке,. Здесь следует обратить внимание на механизм ASLR – Address Space Layout Randomization , который ввели начиная с Win-7. Если в двух словах, то ASLR присутствует в системе как часть загрузчика и призвана рандомизировать ImageBase в памяти. При этом текущая база в PE.34h уже игнорируется, и в вместо неё подставляется рандомное значение.

В результате, запустили мы файл в первый раз – получили базу, например, 0х00500000 . Запустили второй раз тот-же файл – получили уже совсем другую базу типа 0х00700000 и т.д. Механизм ASLR позволил «выкурить» из операционной системы целый класс вирусов и червей, для которых база в РЕ-заголовке была центром вселенной.

Практика – сбор информации

Таким образом, с приходом ASLR поле PE.34h на вещдок уже не тянет – нам нужна реальная база, вытащить которую можно из структуры PEB.08h . Рrocess Еnvironment Вlock – это системная структура и левых значений в ней быть не может. Поскольку мы стремимся к дзену, в исходники предусмотрена эта фишка и адрес ImageBase парсится напрямую из структуры РЕВ, а не из файлового заголовка РЕ.34h. Код содержит комментарии, так-что повторяться не буду:

format pe console include 'win32ax.inc' entry start ;//------ .data capt db 13,10,' Fix EntryPoint file --> %s' db 13,10,' ******************************************',0 info db 13,10,' Stack Base in TEB.04h. %08X' db 13,10,' Image Base in PEB.08h. %08X' db 13,10,' EPoint RVA in PE.28h. %08X' db 13,10,' ------------------------------------------' db 13,10,' Signature = PEB.08h + PE.28h: %08X',0 stAddr db 13,10,' EntryPoint stack address. %08X',0 frmt db '%s',0 fName db 0 ;//------ .code start: invoke GetModuleFileName,0,fName,128 ;// сбрасываем своё имя в буфер cinvoke printf,capt,fName ;// выводим шапку на экран ;//=== Получаем сигнатуру поиска в виде ImageBase + ePoint RVA ;//============================================================= mov eax,[fs:4] ;// EAX = TEB.04 StackBase push eax ;// запомнить mov ebx,[fs:30h] ;// EBX = указатель на PEB mov ebx,[ebx+8] ;// EBX = PEB.08 ImageBase mov ecx,[ebx+3Ch] ;// ECX = Base.3Ch = RVA на РЕ-заголовок add ecx,ebx ;// ECX = виртуальный адрес РЕ-заголовка mov ecx,[ecx+28h] ;// ECX = PE.28h EntryPoint RVA mov edx,ebx ;// EDX = PEB.08h ImageBase add edx,ecx ;// EDX = ImageBase + EntryPoint RVA push edx ;// запомнить сигнатуру! cinvoke printf,info,eax,ebx,ecx,edx ;//=== Кроссплатформенный поиск адреса ePoint в стеке, по его сигнатуре ;//==================================================================== pop ebx esi ;// EBX = сигнатура (маска для поиска), ESI = StackBase std ;// SetDirection - флаг процессора DF=1, обратное чтение из ESI @find_Jocker: lodsd ;// EAX = dword из ESI (esi авто/уменьшается на 4) cmp eax,ebx ;// сравнить с маской jne @find_Jocker ;// повторить, если не равно.. cld ;// иначе: ClearDirection - сбросить флаг обратного шага add esi,4 ;// коррекция указателя ESI cinvoke printf,stAddr,esi ;// выводим его на экран! cinvoke scanf,frmt,capt ;// ждём нажатие клавиши.. invoke exit,0 ; ;//=== Секция импорта ======================= data import library msvcrt, 'msvcrt.dll',kernel,'kernel32.dll' import msvcrt, printf,'printf',scanf,'scanf',exit,'exit' import kernel, GetModuleFileName,'GetModuleFileNameA' end data

signature.png

Как видим, код с более-чем скромным функционалом позволил найти адрес в стеке, куда загрузчик LDR сбрасывает точку-входа для функции ZwContinue() . Причём поиск по такому алго даст положительный результат на любой системе Win, от хр и до десятки. Статическая база адресов тут не преемлема из-за ASLR, зато приведённый выше динамический скан – осечки уже не даст.

Теперь, правка значения по указанному адресу 0х0006FFF8 приведёт к тому, что ZwContinue() снимет со-стека не реальный, а фиктивный EntryPoint и мы можем стартануть основной поток программы с любого адреса. На этот адрес можно повесить, например, распаковщик основного тела или что-то ещё. До недавнего времени, за такой трюк антивирусы сожгли-бы нас на костре, а сейчас – это легальный способ большинства протекторов типа Armadillo, ORiEN и прочих. Так-что если антивирус и горит желанием порубить нашу прожку на мелкие куски, то не сможет этого сделать из эстетических соображений – сразу откажет целый класс программ, чего бизнес позволить себе не может.

И тут мы сталкиваемся с основной проблемой!
Нам нужно подменить значение в стеке задолго до того, как загрузчик закончит свою работу и передаст управление на первую инструкцию секции-кода. Другими словами, нам нужно вмешаться в работу загрузчика образов LDR. Как это сделать? На первый взгляд – миссия не выполнима, т.к. наш код ещё не получил управления. Но посмотрим на рисунок ниже..

LDR.png

Важными для нас тут являются пункты 3 и 4 – это предварительная загрузка статически прилинкованных к нашему приложению библиотек импорта , после чего загрузчик вызывает цепочку Callback-процедур из секции TLS (если таковая имеется). Причём анализ импорта опережает цепочку коллбэков, т.к. в каталоге секций РЕ-заголовка импорт лежит под номером(1), а TLS – аж под номером(9). С деталями этой кухни можно ознакомится в предыдущей статье TLS-Callback. По этой причине, подмену точки-входа лучше осуществлять внутри Callback-процедуры. — на этот момент импортируемые нашим приложением библиотеки DLL уже находятся в памяти, и мы можем вызывать из коллбэка, API-функции.

Но если душа желает хардкора, нично не мешает осуществить перехват EP и внутри статической библиотеки. Правила оформления кода DLL требуют вполне документированной функции инициализации под названием DllEntryPoint() из Ntdll.dll (точка-входа в библиотеку). Она позволяет вызывать свои экспортируемые функции по четырём внешним факторам:

• Dll_Process_Attach – вызов функции при подключении библиотеки к процессу (наш клиент).
• Dll_Process_Detach – вызов функции экспорта при завершении родительского процесса.
• Dll_Thread_Attach – родитель создаёт новый поток (на основной поток не распространяется).
• Dll_Thread_Detach – поток отработал и завершается.

Основное ограничение тут – это запрет на вызов некоторых API, и большинство вещей приходится делать вручную. Использовать для шпионажа статически прилинкованные либы намного интересней и позволяют перехватывать различные действия системы на более раннем этапе запуска процесса на исполнение. Зато в коллбэках можно избавиться от рутины, озадачивая этим функции API. Так-что свобода выбора тут имеется.

Тема манипуляции с EntryPoint требует понимания общих принципов функционирования системного загрузчика образов LDR. В этой части и так уже сказано многое, поэтому поставим здесь точку, чтобы всё/это переварить. Во-второй части попробуем реализовать сказанное на практике, создав небольшой crackme . Мы окунёмся в шифрование и полиморфизм, что сносит башню не только отладчикам, но и дизассемблерам. До скорого..

Использование Docker-инструкций

Инструкции в Dockerfile можно условно разделить на две группы: сборочные инструкции и инструкции, которые влияют на manifest Docker-образа. Так как werf-сборщик использует свой синтаксис для описания сборки, поддерживаются только следующие Dockerfile-инструкции второй группы:

  • USER — имя пользователя (или UID) и опционально пользовательская группа (или GID) (подробнее);
  • WORKDIR — рабочая директория (подробнее);
  • VOLUME — точка монтирования (подробнее);
  • ENV — переменные окружения (подробнее);
  • LABEL — метаданные (подробнее);
  • EXPOSE — описание сетевых портов, которые будут прослушиваться в запущенном контейнере (подробнее);
  • ENTRYPOINT — команда по умолчанию, которая будет выполнена при запуске контейнера (подробнее);
  • CMD — аргументы по умолчанию для ENTRYPOINT (подробнее);
  • HEALTHCHECK — инструкции, которые Docker может использовать для проверки работоспособности запущенного контейнера (подробнее).

Эти инструкции могут быть указаны с помощью директивы docker в конфигурации.

docker: WORKDIR: /app CMD: ["python", "./index.py"] EXPOSE: '5000' ENV: TERM: xterm LC_ALL: en_US.UTF-8 

Указанные в конфигурации Docker-инструкции применяются на последней стадии конвейера стадий, стадии docker_instructions . Поэтому указание Docker-инструкций в werf.yaml никак не влияет на сам процесс сборки, а только добавляет данные к уже собранному образу.

Если вам требуются определённые переменные окружения во время сборки (например, TERM ), то вам необходимо использовать базовый образ, в котором эти переменные окружения установлены, или экспортировать их в пользовательской стадии.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *