Spec-Zone.ru › Perl 5.38

Opcode

СОДЕРЖАНИЕ

  • ИМЯ
  • СИНТАКСИС
  • ОПИСАНИЕ
  • ЗАМЕЧАНИЕ
  • ПРЕДУПРЕЖДЕНИЕ
  • Имена операторов и списки операторов
  • Функции Opcode
  • Работа с наборами операторов
  • ТО ЧТО НУЖНО СДЕЛАТЬ (возможно)
  • Предопределённые теги Opcode
  • СМОТРИТЕ ТАКЖЕ
  • АВТОРЫ

ИМЯ

Opcode — Отключение именованных операторов при компиляции кода Perl

СИНТАКСИС

use Opcode;

ОПИСАНИЕ

Код Perl всегда компилируется во внутренний формат перед выполнением.

Вычисление кода Perl (например, с помощью "eval" или "do 'file'") приводит к компиляции кода во внутренний формат, а затем, при отсутствии ошибок компиляции, к выполнению. Внутренний формат основан на многих различных кодах операций.

По умолчанию никакая маска операторов не активна, и любой код может быть скомпилирован.

Модуль Opcode позволяет вам определить маску операторов, которая будет активна, когда Perl будет компилировать любой код. Попытка скомпилировать код, содержащий замаскированный код операции, приведёт к ошибке компиляции. Код не будет выполнен.

ЗАМЕЧАНИЕ

Модуль Opcode обычно не используется напрямую. Обратитесь к оператору ops и модулям Safe для более типичных случаев использования.

ПРЕДУПРЕЖДЕНИЕ

Модуль Opcode не реализует эффективную защищённую среду для оценки недоверенного кода с помощью интерпретатора Perl.

Ошибки в интерпретаторе Perl, которые могли бы быть использованы для обхода ограничений Opcode, не рассматриваются как уязвимости. Смотрите perlsecpolicy для получения дополнительной информации.

Авторы не гарантируют пригодность данного программного обеспечения для целей безопасности.

Авторы в любом случае не несут ответственности за особые, случайные, косвенные или иные подобные убытки, возникающие в результате использования данного программного обеспечения.

Результаты могут различаться. При сомнениях не используйте его.

Имена операторов и списки операторов

Канонический список имён операторов — содержимое массива 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. Другими словами, обе стороны битового оператора должны быть наборами операторов, возвращаемыми функциями 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 padsv_store

    rv2av aassign aelem aelemfast aelemfast_lex aslice kvaslice
    av2arylen aelemfastlex_store

    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
    isa

    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
    helemexistsor

    warn die lineseq nextstate scope enter leave

    rv2cv anoncode prototype coreargs avhvswitch anonconst
    emptyavhv

    entersub leavesub leavesublv return method method_named
    method_super method_redir method_redir_super
     -- XXX loops via recursion?

    cmpchain_and cmpchain_dup

    is_bool
    is_weak weaken unweaken

    leaveeval -- needed for Safe to operate, is safe
		 without entereval

    methstart initfield
: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

Эти операции позволяют выполнять ввод-вывод, основываясь на дескрипторе файла (а не на имени файла). Они безопасны при условии, что доступны только существующие дескрипторы файлов. Обычно для создания новых дескрипторов файлов необходимо включить другие операции, такие как открытие, если вы не учитываете магическое открытие 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
    blessed refaddr reftype

    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
    entertrycatch poptry catch leavetrycatch -- similar

    entergiven leavegiven
    enterwhen leavewhen
    break continue
    smartmatch

    pushdefer

    custom -- where should this go

    ceil floor

    is_tainted
: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?), то вы не должны полагаться на определение этой или любой другой метки!

: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 (и действительно все остальные метки), её текущее определение нестабильно во время разработки. Оно будет изменено.

Метка :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

Эта метка содержит группы различных специализированных инструкций, для которых нецелесообразно определять метки.

Межпроцессное взаимодействие 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 для модуля Opcode.

Safe — отсеки выполнения с ограниченным доступом к Opcode и именованному пространству имён

АВТОРЫ

Первоначально разработано и реализовано Malcolm Beattie, mbeattie@sable.ox.ac.uk, в рамках Safe версии 1.

Вынесено из модуля Safe версии 1, добавлены имена меток opcode и другие изменения, внесенные Tim Bunce.

© 1993–2023 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.38.0/Opcode

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API