Алгоритм динамической расшифровки, реализованный в протекторе Armadillo и известный под именем CopyMem, в общих чертах выглядит так: защита порождает отладочный процесс, передавая функции CreateProcess в качестве имени нулевой аргумент командной строки, "благодаря" чему в диспетчере задач отображается две копии запущенной программы. Одна из них сервер (условно), другая — клиент. Сервер посредством функции VirtualProtectEx делает все страницы клиента недоступными (атрибут PAGE_NOACCESS) и передает ему управление, ожидая отладочных событий с помощью функции WaitForDebugEvent, а события долго ждать себя не заставляют и при первой же попытке выполнения кода в недоступной странице возбуждается исключение, передающее серверу бразды правления. Сервер расшифровывает текущую страницу, взаимодействуя с клиентов посредством API-функций ReadProcessMemory/WriteProcessMemory, устанавливает необходимые атрибуты доступа и возвращает клиенту управление.
Остальные страницы остаются зашифрованными, и при обращении к ним вновь возбуждается исключение, которое передается серверу через WaitForDedugEvent. Сервер зашифровывает предыдущую страницу, отбирая все атрибуты доступа, какие у нее только есть, и расшифровывает текущую страницу, возбудившую исключение (в действительности, для увеличения производительности защита поддерживает примитивный кэш, позволяя клиенту иметь несколько расшифрованных страниц одновременно).
Потребность в отладочном процессе-сервере объясняется тем, что по другому ловить исключения на прикладном уровне просто не получается. А как же механизм структурных исключений или, сокращенно, SEH? Регистрируем свой собственный обработчик и ловим исключения, что называется по месту возникновения. Это избавляет нас от API-вызовов, обеспечивающих межпроцессорного взаимодействия, которые элементарно перехватываются хакером. Увы! Если защищаемое приложение использует SEH (а подавляющее большинство приложений его используют), наш обработчик окажется перекрыт другим.