{
This function can be used to determine whether your program is
running from within Connectrix's Virtual PC
}function running_inside_vpc: boolean; assembler;
asm
push ebp
mov ecx, offset @@exception_handler
mov ebp, esp
push ebx
push ecx
push dword ptr fs:[0]
mov dword ptr fs:[0], esp
mov ebx, 0 // flag
mov eax, 1 // VPC function number // call VPC
db 00Fh, 03Fh, 007h, 00Bh
mov eax, dword ptr ss:[esp]
mov dword ptr fs:[0], eax
add esp, 8
test ebx, ebx
setz al
lea esp, dword ptr ss:[ebp-4]
mov ebx, dword ptr ss:[esp]
mov ebp, dword ptr ss:[esp+4]
add esp, 8
jmp @@ret
@@exception_handler:
mov ecx, [esp+0Ch]
mov dword ptr [ecx+0A4h], -1 // EBX = -1 -> not running, ebx = 0 -> running
add dword ptr [ecx+0B8h], 4 // -> skip past the detection code xor eax, eax // exception is handled
ret
@@ret:
end;
Перевод контента на русский язык:
Функция running_inside_vpc в Delphi, написанная на ассемблере, определяет, запущен ли программный код внутри виртуальной машины Connectrix' Virtual PC (VPC). Вот шаг за шагом, что происходит в этом коде:
Функция running_inside_vpc не принимает параметров и возвращает булевое значение (boolean; assembler;).
Ассемблерный код начинает с того, что кладет текущий базовый указатель (ebp) на стек.
Затем он перемещает адрес исключения (@@exception_handler) в регистр ecx и устанавливает стэк-фрейм, перемещая текущий указатель стека (esp) в ebp.
Функция кладет три значения на стек: ebx, ecx и указатель на стек (dword ptr fs:[0]). Это, вероятно, используется для сохранения регистров и памяти.
Она устанавливает флаг (ebx) в 0 (false), который будет использоваться для указания, запущен ли программный код внутри VPC или нет.
Функция затем вызывает функцию VPC с неизвестным оперкодом (db 00Fh, 03Fh, 007h, 00Bh). Это, вероятно, является специфическим инструкцией, возвращающей информацию о runtime-окружении.
После вызова функции VPC код получает результат из стека и проверяет, остается ли ebx установленным в 0 (false). Если это так, то программный код не запущен внутри VPC.
Исключение (@@exception_handler) вызывается, если происходит исключение при выполнении функции VPC. Это рутинка устанавливает EBX в -1 (указывая, что программный код не запущен внутри VPC) и пропускает через детекцию кода, добавляя 4 к памятному адресу (dword ptr [ecx+0B8h]). Затем она возвращает из исключения.
Наконец, функция прыгает назад к метке @@ret, которая возвращает булевое значение, указывающее, запущен ли программный код внутри VPC или нет.
Альтернативное решение заключается в использовании другого метода для определения, запущен ли программный код внутри Virtual PC, например, проверки конкретных системных свойств или регистровых ключей. Однако данный код специально разработан для работы с Connectrix' Virtual PC и ее проприетарным API.
Вот некоторые потенциальные улучшения:
Используйте более описательные имена переменных, чтобы сделать код более понятным.
Рассмотрите добавление обработки ошибок для случаев, когда функция VPC не работает или возвращает неожиданный результат.
Если это возможно, рассмотрите использование более платформо-независимого метода для определения, запущен ли программный код внутри Virtual PC, а не полагаться на проприетарные API-запросы.
В статье описывается функция assembly-языка для определения запуска программы в пространстве Virtual PC (VPC) Connectrix.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.