Opcode
СОДЕРЖАНИЕ
- ИМЯ
- СИНТАКСИС
- ОПИСАНИЕ
- ПРИМЕЧАНИЕ
- ПРЕДУПРЕЖДЕНИЕ
- Имена операторов и списки операторов
- Функции Opcode
- Работа с наборами опкодов
- ЗАДАЧИ НА БУДУЩЕЕ (возможно)
- Предопределённые теги Opcode
- СМОТРИТЕ ТАКЖЕ
- АВТОРЫ
ИМЯ
Opcode - Отключение именованных опкодов при компиляции кода Perl
СИНТАКСИС
use Opcode; ОПИСАНИЕ
Код Perl всегда компилируется во внутренний формат перед выполнением.
Выполнение кода Perl (например, через "eval" или "do 'file'") приводит к компиляции кода во внутренний формат, а затем, при отсутствии ошибок компиляции, к его выполнению. Внутренний формат основан на множестве различных опкодов.
По умолчанию никакая маска опкодов не активна, и любой код может быть скомпилирован.
Модуль Opcode позволяет определить маску операторов, которая будет активна при следующей компиляции кода Perl. Попытка компиляции кода, содержащего замаскированный опкод, приведёт к ошибке компиляции. Код не будет выполнен.
ПРИМЕЧАНИЕ
Модуль Opcode обычно не используется напрямую. См. псевдоним ops и модули Safe для более типичных вариантов использования.
ПРЕДУПРЕЖДЕНИЕ
Авторы не предоставляют никаких гарантий, явных или подразумеваемых, относительно пригодности данного программного обеспечения для целей безопасности или безопасности.
Авторы ни при каких обстоятельствах не несут ответственности за особые, случайные, косвенные или иные аналогичные убытки, возникшие в результате использования данного программного обеспечения.
Результат может варьироваться. При любых сомнениях не используйте его.
Имена операторов и списки операторов
Канонический список имён операторов — содержимое массива PL_op_name, определённого и инициализированного в файле opcode.h распределения исходного кода Perl (и установленного в библиотеку perl).
Каждый оператор имеет краткое имя (его opname) и более подробное или узнаваемое описательное имя. Функция opdesc может использоваться для возвращения списка описаний для списка операторов.
Многие из перечисленных ниже функций и методов принимают список операторов в качестве параметров. Большинство списков операторов могут быть составлены из нескольких типов элементов. Каждый элемент может быть одним из:
- имя оператора (opname)
-
Имена операторов обычно представляют собой короткие слова с маленькими буквами, такие как enterloop, leaveloop, last, next, redo и т.д. Иногда они довольно загадочные, например, gv2cv, i_ncmp и ftsvtx.
- имя тега оператора (optag)
-
Теги операторов могут использоваться для ссылки на группы (или наборы) операторов. Имена тегов всегда начинаются с двоеточия. Модуль Opcode определяет несколько тегов опкодов, и пользователь может определить другие с помощью функции define_optag.
- отрицательное имя opname или optag
-
Имени opname или optag может предшествовать знак восклицания, например, !mkdir. Отрицание имени opname или optag означает удаление соответствующих операторов из накопленного набора операторов на этом этапе.
- набор операторов (opset)
-
opset как двоичная строка примерно из 44 байт, которая содержит набор из одного или нескольких операторов.
Функции opset и opset_to_ops могут использоваться для преобразования списка операторов в opset и наоборот.
В местах, где может быть указан список операторов, можно использовать один или несколько opset. См. также раздел «Работа с наборами опкодов» ниже.
Функции Opcode
Пакет Opcode содержит функции для работы с именами операторов, тегами и наборами. Все они доступны для экспорта из пакета.
- opcodes
-
В скалярном контексте opcodes возвращает количество опкодов в данной версии Perl (около 350 для Perl-5.7.0).
В контексте списка возвращает список всех имён операторов. (Пока не реализовано, используйте @names = opset_to_ops(full_opset).)
- opset (OP, ...)
-
Возвращает opset, содержащий указанные операторы.
- opset_to_ops (OPSET)
-
Возвращает список имён операторов, соответствующих операторам в наборе.
- opset_to_hex (OPSET)
-
Возвращает строковое представление opset. Может быть полезно для отладки.
- full_opset
-
Возвращает opset, который включает все операторы.
- empty_opset
-
Возвращает opset, который не содержит операторов.
- invert_opset (OPSET)
-
Возвращает opset, который является обратным набору, предоставленному в качестве параметра.
- verify_opset (OPSET, ...)
-
Возвращает true, если предоставленный opset выглядит как допустимый opset (имеет правильную длину и т.д.), в противном случае возвращает false. Если в качестве необязательного второго параметра передано true, verify_opset выведет ошибку для недопустимого opset вместо возврата false.
Большинство других функций Opcode автоматически вызывают verify_opset и выдадут ошибку, если в качестве параметра будет передан недопустимый opset.
- define_optag (OPTAG, OPSET)
-
Определяет OPTAG как символьное имя для OPSET. Имена optag всегда начинаются с двоеточия
:.Используемое имя optag не должно быть уже определено (define_optag выведет ошибку, если оно уже определено). Имена optag являются глобальными для процесса Perl, и определения optag не могут быть изменены или удалены после их определения.
Настоятельно рекомендуется, чтобы приложения, использующие Opcode, использовали имя тега с заглавной буквы, поскольку имена со строчными буквами зарезервированы для использования модулем Opcode. Если вы используете Opcode в модуле, вы должны префикс своих тегов именем вашего модуля для обеспечения уникальности и, таким образом, избежать конфликтов с другими модулями.
- opmask_add (OPSET)
-
Добавляет предоставленный opset к текущей opmask. Обратите внимание, что в настоящее время нет механизма для отмены маскирования опкодов после того, как они были замаскированы. Это сделано намеренно.
- opmask
-
Возвращает opset, соответствующий текущей opmask.
- opdesc (OP, ...)
-
Принимает список имён операторов и возвращает соответствующий список описаний операторов.
- opdump (PAT)
-
Выводит в STDOUT список имён и описаний операторов в двух столбцах. Если указан необязательный шаблон, то будут выведены только строки, соответствующие шаблону (без учёта регистра).
Он предназначен для использования в качестве удобной утилиты командной строки:
perl -MOpcode=opdump -e opdump perl -MOpcode=opdump -e 'opdump Eval'
Работа с наборами опкодов
Наборы опкодов можно обрабатывать с помощью битовых операторов Perl & (и), | (или), ^ (исключающее или) и ~ (отрицание/инверсия).
Однако не следует полагаться на числовое положение любого опкода в opset. Другими словами, обе части битового оператора должны быть opset, возвращёнными функциями Opcode.
Кроме того, поскольку количество опкодов в вашей текущей версии Perl может не быть точным кратным восьми, в последнем байте opset могут быть неиспользуемые биты. Это не должно вызывать никаких проблем (функции Opcode игнорируют эти дополнительные биты), но это означает, что использование оператора ~ обычно не даст той же «физической» строки opset, что и функция invert_opset.
ЗАДАЧИ НА БУДУЩЕЕ (возможно)
$bool = opset_eq($opset1, $opset2) true if opsets are logically
equivalent
$yes = opset_can($opset, @ops) true if $opset has all @ops set
@diff = opset_diff($opset1, $opset2) => ('foo', '!bar', ...) Предопределённые теги Opcode
- :base_core
-
null stub scalar pushmark wantarray const defined undef rv2sv sassign rv2av aassign aelem aelemfast aelemfast_lex aslice kvaslice av2arylen rv2hv helem hslice kvhslice each values keys exists delete aeach akeys avalues multideref argelem argdefelem argcheck preinc i_preinc predec i_predec postinc i_postinc postdec i_postdec int hex oct abs pow multiply i_multiply divide i_divide modulo i_modulo add i_add subtract i_subtract left_shift right_shift bit_and bit_xor bit_or nbit_and nbit_xor nbit_or sbit_and sbit_xor sbit_or negate i_negate not complement ncomplement scomplement lt i_lt gt i_gt le i_le ge i_ge eq i_eq ne i_ne ncmp i_ncmp slt sgt sle sge seq sne scmp substr vec stringify study pos length index rindex ord chr ucfirst lcfirst uc lc fc quotemeta trans transr chop schop chomp schomp match split qr list lslice splice push pop shift unshift reverse cond_expr flip flop andassign orassign dorassign and or dor xor warn die lineseq nextstate scope enter leave rv2cv anoncode prototype coreargs avhvswitch anonconst entersub leavesub leavesublv return method method_named method_super method_redir method_redir_super -- XXX loops via recursion? leaveeval -- needed for Safe to operate, is safe without entereval - :base_mem
-
Эти операции, связанные с памятью, не включены в :base_core, потому что их легко можно использовать для атаки на ресурсы (например, для потребления всей доступной памяти).
concat multiconcat repeat join range anonlist anonhashОбратите внимание, что, несмотря на существование этой опции, атака на ресурсы памяти всё ещё возможна с использованием только операций :base_core.
Отключение этих операций является очень грубым способом предотвращения атаки на ресурсы памяти. Вероятно, в ближайшем будущем в perl будет добавлен механизм конкретного ограничения памяти.
- :base_loop
-
Эти циклические операции не включены в :base_core, потому что их легко можно использовать для атаки на ресурсы (например, для потребления всего доступного времени процессора).
grepstart grepwhile mapstart mapwhile enteriter iter enterloop leaveloop unstack last next redo goto - :base_io
-
Эти операции позволяют выполнять ввод и вывод данных, используя дескриптор файла (а не имя файла). Они считаются безопасными при условии, что доступны только уже существующие дескрипторы файлов. Обычно для создания новых дескрипторов файлов необходимо включить другие операции, такие как open, если вы не учитываете магическое открытие ARGV.
readline rcatline getc read formline enterwrite leavewrite print say sysread syswrite send recv eof tell seek sysseek readdir telldir seekdir rewinddir - :base_orig
-
Это набор команд-остатков, которые ещё предстоит рассмотреть
gvsv gv gelem padsv padav padhv padcv padany padrange introcv clonecv once rv2gv refgen srefgen ref refassign lvref lvrefslice lvavref bless -- could be used to change ownership of objects (reblessing) regcmaybe regcreset regcomp subst substcont sprintf prtf -- can core dump crypt tie untie dbmopen dbmclose sselect select pipe_op sockpair getppid getpgrp setpgrp getpriority setpriority localtime gmtime entertry leavetry -- can be used to 'hide' fatal errors entergiven leavegiven enterwhen leavewhen break continue smartmatch custom -- where should this go - :base_math
-
Эти операции не включены в :base_core из-за риска использования для генерации исключений с плавающей точкой (которые необходимо было бы перехватывать с помощью обработчика $SIG{FPE}).
atan2 sin cos exp log sqrtЭти операции не включены в :base_core, потому что они оказывают влияние, выходящее за пределы области.
rand srand - :base_thread
-
Эти операции относятся к многопоточности.
lock - :default
-
Удобное имя тега для разумного набора базовых операций. (Текущий набор разрешённых операций нестабилен во время разработки. Он будет изменяться.)
:base_core :base_mem :base_loop :base_orig :base_threadЭтот список содержал :base_io до Opcode 1.07.
Если для вас важна безопасность (а зачем иначе вы используете модуль Opcode?), то вы не должны полагаться на определение этого или любого другого тега optag!
- :filesys_read
-
stat lstat readlink ftatime ftblk ftchr ftctime ftdir fteexec fteowned fteread ftewrite ftfile ftis ftlink ftmtime ftpipe ftrexec ftrowned ftrread ftsgid ftsize ftsock ftsuid fttty ftzero ftrwrite ftsvtx fttext ftbinary fileno - :sys_db
-
ghbyname ghbyaddr ghostent shostent ehostent -- hosts gnbyname gnbyaddr gnetent snetent enetent -- networks gpbyname gpbynumber gprotoent sprotoent eprotoent -- protocols gsbyname gsbyport gservent sservent eservent -- services gpwnam gpwuid gpwent spwent epwent getlogin -- users ggrnam ggrgid ggrent sgrent egrent -- groups - :browse
-
Удобное имя тега для разумного набора базовых операций за пределами тега :default. Как и :default (и, по сути, все другие теги optag), его текущее определение нестабильно во время разработки. Оно будет изменяться.
Тег :browse представляет собой следующий шаг после :default. Он является супермножеством операций :default и добавляет :filesys_read и :sys_db. Цель заключается в том, чтобы скрипты могли получать доступ к большей (возможно, конфиденциальной) информации о вашей системе, но не могли её изменить.
:default :filesys_read :sys_db - :filesys_open
-
sysopen open close umask binmode open_dir closedir -- other dir ops are in :base_io - :filesys_write
-
link unlink rename symlink truncate mkdir rmdir utime chmod chown fcntl -- not strictly filesys related, but possibly as dangerous? - :subprocess
-
backtick system fork wait waitpid glob -- access to Cshell via <`rm *`> - :ownprocess
-
exec exit kill time tms -- could be used for timing attacks (paranoid?) - :others
-
Этот тег содержит группы различных специализированных команд, для которых нецелесообразно определять отдельные теги optag.
Межпроцессное взаимодействие SystemV:
msgctl msgget msgrcv msgsnd semctl semget semop shmctl shmget shmread shmwrite - :load
-
Этот тег содержит команды, связанные с загрузкой модулей и получением информации об окружении вызова и аргументах.
require dofile caller runcv - :still_to_be_decided
-
chdir flock ioctl socket getpeername ssockopt bind connect listen accept shutdown gsockopt getsockname sleep alarm -- changes global timer state and signal handling sort -- assorted problems including core dumps tied -- can be used to access object implementing a tie pack unpack -- can be used to create/use memory pointers hintseval -- constant op holding eval hints entereval -- can be used to hide code from initial compile reset dbstate -- perl -d version of nextstate(ment) opcode - :dangerous
-
Этот тег — просто контейнер для команд, которые, скорее всего, не будут использоваться через имя тега, но которые необходимо пометить для полноты и документации.
syscall dump chroot
СПРАВКА
ops -- интерфейс Perl-pragma к модулю Opcode.
Safe -- Opcode и ограниченные по именам пространства имен контейнеры выполнения.
АВТОРЫ
Первоначально разработан и реализован Malcolm Beattie, mbeattie@sable.ox.ac.uk, в рамках Safe версии 1.
Выделен из модуля Safe версии 1, добавлены имена тегов opcode и другие изменения, внесённые Tim Bunce.
© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.30.3/Opcode