build: implement php obfustation

This commit is contained in:
2025-11-18 15:33:11 +03:00
parent d6db083dea
commit 3d078900a1
7 changed files with 207 additions and 8 deletions

View File

@@ -63,3 +63,7 @@ test-telegram:
test-coverage: test-coverage:
docker compose exec -w /module/oc_telegram_shop/upload/oc_telegram_shop web bash -c "./vendor/bin/phpunit --coverage-html coverage tests/" docker compose exec -w /module/oc_telegram_shop/upload/oc_telegram_shop web bash -c "./vendor/bin/phpunit --coverage-html coverage tests/"
phar:
docker build -t telecart_local_build -f ./docker/build.dockerfile . && \
docker run -v "./src/upload/system/library/oc_telegram_shop:/build" telecart_local_build sh -c 'sh /scripts/build_phar.sh'

View File

@@ -6,6 +6,7 @@ services:
- "./src:/web" - "./src:/web"
- "./scripts:/scripts" - "./scripts:/scripts"
- "./module:/module" - "./module:/module"
- "./build:/build"
- "/Users/nikitakiselev/code/msvlad.com/image/catalog/products:/web/upload/image/catalog/products" - "/Users/nikitakiselev/code/msvlad.com/image/catalog/products:/web/upload/image/catalog/products"
ports: ports:
- "8000:80" - "8000:80"

View File

@@ -1,11 +1,15 @@
FROM node:latest FROM php:7.4-alpine
RUN apt update && apt install -y zip RUN apk update
RUN mkdir -p /app RUN apk add git
COPY ./frontend /app/frontend
COPY ./module /app/module
COPY ./scripts/build.sh /app/scripts/build.sh
WORKDIR /app RUN mkdir -p /usr/local && \
cd /usr/local && git clone https://github.com/pk-fr/yakpro-po.git && \
cd yakpro-po && git clone https://github.com/nikic/PHP-Parser.git --branch 4.x && \
chmod a+x yakpro-po.php && \
ln -s /usr/local/yakpro-po/yakpro-po.php /usr/local/bin/yakpro-po
CMD ["./scripts/build.sh"] COPY ./docker/config.php /usr/local/yakpro-po
COPY ./module/oc_telegram_shop/upload/oc_telegram_shop /app
COPY ./scripts /scripts

100
docker/config.php Normal file
View File

@@ -0,0 +1,100 @@
<?php
// YAK Pro - Php Obfuscator: Config File
// Do not delete the previous line! it's a magic string for config file!
//========================================================================
// Author: Pascal KISSIAN
// Resume: http://pascal.kissian.net
//
// CopyRight (c) 2015-2019 Pascal KISSIAN
//
// Published under the MIT License
// Consider it as a proof of concept!
// No warranty of any kind.
// Use and abuse at your own risks.
//========================================================================
// when we use the word ignore, that means that it is ignored during the obfuscation process (i.e. not obfuscated)
$conf->t_ignore_pre_defined_classes = 'all'; // 'all' (default value) , 'none', or array of pre-defined classes that you use in your software:
// ex: array('Exception', 'PDO', 'PDOStatement', 'PDOException');
// As instantiation is done at runtime, it is impossible to statically determinate when a method call is detected, on which class the object belong.
// so, all method names that exists in a pre_defined_class to ignore are ignored within every classes.
// if you have some method names in your classes that have the same name that a predefine class method, it will not be obfuscated.
// you can limit the number of method names to ignore by providing an array of the pre-defined classes you really use in your software!
// same behaviour for properties...
$conf->t_ignore_constants = null; // array where values are names to ignore.
$conf->t_ignore_variables = null; // array where values are names to ignore.
$conf->t_ignore_functions = null; // array where values are names to ignore.
$conf->t_ignore_class_constants = null; // array where values are names to ignore.
$conf->t_ignore_methods = null; // array where values are names to ignore.
$conf->t_ignore_properties = null; // array where values are names to ignore.
$conf->t_ignore_classes = null; // array where values are names to ignore.
$conf->t_ignore_interfaces = null; // array where values are names to ignore.
$conf->t_ignore_traits = null; // array where values are names to ignore.
$conf->t_ignore_namespaces = null; // array where values are names to ignore.
$conf->t_ignore_labels = null; // array where values are names to ignore.
$conf->t_ignore_constants_prefix = null; // array where values are prefix of names to ignore.
$conf->t_ignore_variables_prefix = null; // array where values are prefix of names to ignore.
$conf->t_ignore_functions_prefix = null; // array where values are prefix of names to ignore.
$conf->t_ignore_class_constants_prefix = null; // array where values are prefix of names to ignore.
$conf->t_ignore_properties_prefix = null; // array where values are prefix of names to ignore.
$conf->t_ignore_methods_prefix = null; // array where values are prefix of names to ignore.
$conf->t_ignore_classes_prefix = null; // array where values are prefix of names to ignore.
$conf->t_ignore_interfaces_prefix = null; // array where values are prefix of names to ignore.
$conf->t_ignore_traits_prefix = null; // array where values are prefix of names to ignore.
$conf->t_ignore_namespaces_prefix = null; // array where values are prefix of names to ignore.
$conf->t_ignore_labels_prefix = null; // array where values are prefix of names to ignore.
$conf->parser_mode = 'ONLY_PHP7';// allowed modes are 'PREFER_PHP7', 'PREFER_PHP5', 'ONLY_PHP7', 'ONLY_PHP5'
// see PHP-Parser documentation for meaning...
$conf->scramble_mode = 'identifier'; // allowed modes are 'identifier', 'hexa', 'numeric'
$conf->scramble_length = 5; // min length of scrambled names (min = 2; max = 16 for identifier, 32 for hexa and numeric)
$conf->t_obfuscate_php_extension = array('php'); // array where values are extensions of php files to be obfuscated.
$conf->obfuscate_constant_name = false; // self explanatory
$conf->obfuscate_variable_name = false; // self explanatory
$conf->obfuscate_function_name = false; // self explanatory
$conf->obfuscate_class_name = false; // self explanatory
$conf->obfuscate_interface_name = false; // self explanatory
$conf->obfuscate_trait_name = false; // self explanatory
$conf->obfuscate_class_constant_name = false; // self explanatory
$conf->obfuscate_property_name = false; // self explanatory
$conf->obfuscate_method_name = false; // self explanatory
$conf->obfuscate_namespace_name = false; // self explanatory
$conf->obfuscate_label_name = false; // label: , goto label; obfuscation
$conf->obfuscate_if_statement = false; // obfuscation of if else elseif statements
$conf->obfuscate_loop_statement = false; // obfuscation of for while do while statements
$conf->obfuscate_string_literal = true; // pseudo-obfuscation of string literals
$conf->shuffle_stmts = true; // shuffle chunks of statements! disable this obfuscation (or minimize the number of chunks) if performance is important for you!
$conf->shuffle_stmts_min_chunk_size = 1; // minimum number of statements in a chunk! the min value is 1, that gives you the maximum of obfuscation ... and the minimum of performance...
$conf->shuffle_stmts_chunk_mode = 'fixed'; // 'fixed' or 'ratio' in fixed mode, the chunk_size is always equal to the min chunk size!
$conf->shuffle_stmts_chunk_ratio = 20; // ratio > 1 100/ratio is the percentage of chunks in a statements sequence ratio = 2 means 50% ratio = 100 mins 1% ...
// if you increase the number of chunks, you increase also the obfuscation level ... and you increase also the performance overhead!
$conf->strip_indentation = true; // all your obfuscated code will be generated on a single line
$conf->abort_on_error = true; // self explanatory
$conf->confirm = true; // rfu : will answer Y on confirmation request (reserved for future use ... or not...)
$conf->silent = false; // display or not Information level messages.
$conf->source_directory = null; // self explanatory
$conf->target_directory = null; // self explanatory
$conf->t_keep = null; // array of directory or file pathnames, to keep 'as is' (i.e. not obfuscate.)
$conf->t_skip = null; // array of directory or file pathnames, to skip when exploring source tree structure ... they will not be on target!
$conf->allow_and_overwrite_empty_files = true; // allow empty files to be kept as is
$conf->max_nested_directory = 99;
$conf->follow_symlinks = false; // WARNING: setting it to true will copy the directory instead of replicating the link...
// WARNING: if there is a loop of links, $conf->max_nested_directory can be created...
$conf->user_comment = null; // user comment to insert inside each obfuscated file
$conf->extract_comment_from_line = null; // when both 2 are set, each obfuscated file will contain an extract of the corresponding source file,
$conf->extract_comment_to_line = null; // starting from extract_comment_from_line number, and ending at extract_comment_to_line line number.

34
scripts/build_phar.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/sh
set -e
SRC_PATH="/app"
BUILD_PATH="/build"
MODULE_NAME="oc_telegram_shop"
PHAR_PATH="${BUILD_PATH}/${MODULE_NAME}.phar"
echo "PHP Obfuscation: framework"
yakpro-po --config-file /usr/local/yakpro-po/config.php ${SRC_PATH}/framework -o /tmp/obfuscated
rm -rf ${SRC_PATH}/framework
mv /tmp/obfuscated/yakpro-po/obfuscated ${SRC_PATH}/framework
echo "PHP Obfuscation: src"
yakpro-po --config-file /usr/local/yakpro-po/config.php ${SRC_PATH}/src -o /tmp/obfuscated
rm -rf ${SRC_PATH}/src
mv /tmp/obfuscated/yakpro-po/obfuscated ${SRC_PATH}/src
echo "PHP Obfuscation: bastion"
yakpro-po --config-file /usr/local/yakpro-po/config.php ${SRC_PATH}/bastion -o /tmp/obfuscated
rm -rf ${SRC_PATH}/bastion
mv /tmp/obfuscated/yakpro-po/obfuscated ${SRC_PATH}/bastion
echo "📜 Creating Phar archive..."
rm -rf "${BUILD_PATH}/extracted"
mkdir -p "${BUILD_PATH}"
echo "Source path: ${SRC_PATH}"
echo "Destination: ${PHAR_PATH}"
php -d phar.readonly=0 /scripts/ci/create-phar.php "${SRC_PATH}" "${PHAR_PATH}"
echo "Extracting ..."
php -d phar.readonly=0 /scripts/ci/extract-phar.php "${PHAR_PATH}" "${BUILD_PATH}/extracted"

View File

@@ -71,6 +71,45 @@ echo "Copy .env for production"
cp "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/.env.production" \ cp "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/.env.production" \
"${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/.env" "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/.env"
echo "Install PHP Obfuscation lib"
mkdir -p /usr/local
cd /usr/local
wget https://github.com/pk-fr/yakpro-po/archive/refs/heads/master.zip
unzip -o "master.zip" -d /usr/local/yakpro-po
rm master.zip
ls -la /usr/local/yakpro-po
cd /usr/local/yakpro-po
wget https://github.com/nikic/PHP-Parser/archive/refs/heads/4.x.zip -O parser.zip
unzip -o "parser.zip" -d /usr/local/yakpro-po/PHP-Parser
ls -la /usr/local/yakpro-po
ls -la /usr/local/yakpro-po/PHP-Parser
chmod a+x /usr/local/yakpro-po/yakpro-po.php
ln -s /usr/local/yakpro-po/yakpro-po.php /usr/local/bin/yakpro-po
echo "PHP Obfuscation: framework"
yakpro-po --config-file \
"${SRC_PATH}/docker/config.php" \
"${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/framework" \
-o /tmp/obfuscated
rm -rf "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/framework"
mv /tmp/obfuscated/yakpro-po/obfuscated "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/framework"
echo "PHP Obfuscation: src"
yakpro-po --config-file \
"${SRC_PATH}/docker/config.php" \
"${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/src" \
-o /tmp/obfuscated
rm -rf "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/src"
mv /tmp/obfuscated/yakpro-po/obfuscated "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/src"
echo "PHP Obfuscation: bastion"
yakpro-po --config-file \
"${SRC_PATH}/docker/config.php" \
"${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/bastion" \
-o /tmp/obfuscated
rm -rf "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/bastion"
mv /tmp/obfuscated/yakpro-po/obfuscated "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/bastion"
echo "📜 Creating Phar archive..." echo "📜 Creating Phar archive..."
rm -rf \ rm -rf \
"${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/tests" \ "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/tests" \

View File

@@ -0,0 +1,17 @@
<?php
$pharFile = $argv[1] ?? null;
$dstPath = $argv[2] ?? null;
if (! $dstPath) {
throw new InvalidArgumentException('Dst path must be provided');
}
if (! $pharFile) {
throw new InvalidArgumentException('Phar file must be provided');
}
$phar = new Phar($pharFile);
$phar->extractTo($dstPath);
echo "Phar extracted: $pharFile\n";