Image

Imagecpplang 😦busy

Category:

Сам себе обфускатор

 Навеяно замечаниями СБ
 Предположим, что есть такой вот фрагмент кода на perl:
 my $ID = 0;
 modifyID($ID);
 print "$ID\n" if ($ID > 0);

На первый взгляд условие if ($ID > 0) никогда не выполнится. Действительно, переменная $ID передаётся в функцию по значению, следовательно, по выходе из неё значение переменной останется прежним. Однако, в perl возможно всё. Поэтому то, как показано ниже писать можно, но не нужно, чтобы не пугать гражданское население:

sub modifyID{
  $_[0] = 1;
}

В подпрограмме modifyID я обратился непосредственно к $_ элементам массива @_, и произвёл изменения в фактических переменных, передаваемых подпрограмме. Плохо то, что такое поведение подпрограммы абсолютно не очевидно, если не заглядывать в код. Сам же код подпрограммы может находиться совершенно в другом месте и вероятность того, что код скрипта будет "оптимизирован" выбрасыванием якобы никогда не выполняющегося условия очень высока.

Более гуманный способ – заставить передавать значение по ссылке. Код будет выглядеть так:

sub modifyID {
  my $ID = shift;
  $$ID = 1;
}

Для справки: shift удаляет из массива его первый элемент, сдвигает все оставшиеся в начало и возвращает удаленный элемент в качестве значения. Длина массива сокращается на 1.

Фрагмент кода стал выглядеть немного иначе:
my $ID = 0;
modifyID(\$ID);
print "$ID\n" if ($ID > 0);

Теперь переменная $ID не только передаётся по ссылке, но и при попытке передачи по значению perl выдаст сообщение об ошибке наподобие такого: 
Can't use string ("0") as a SCALAR ref while "strict refs" in use at blabla.pl line 6.

Неплохое руководство по написанию подпрограмм нашёл здесь.