FAQ
Hi all,

I'm currently facing the situation, that I need to protect my php sources
and retain opcache compatibility.

I know there are quite a few commercial tools for "encoding" and protecting
php sources, but none of them seems to work in conjunction with php's
opcache extension.

Most products see this as part of their protection scheme.

Basically it would be ok to just dump the _zend_op_array struct (defined in
zend_compile.h) to a file and make the zend engine able to load it again.
Once it is loaded, it could be server from opcache.

Unfortunately bcompiler is not (yet?) compatible with php 5.5.x, and
digging through the source it seems to be not an easy task to serialize the
opcode array (seems as if the code is borrowed from apc).

I also had a look at blenc, which just overrides the compile_function to
read an encrypted source file and then compile the resulting string. This
might be a first solution, though I'd rather deliver opcodes to the
client's server than just an encrypted script. Sadly blenc just crashes php
when it tries to serve an encrypted script from opcache and I could not
figure out yet, what's wrong there (tested on windows and linux using php
5.5.12).

Is there any solution for my situation?
Are there any plans to add the "serialize opcode to string, dump string to
file and load it again"-functionality to php?
How easy would it be to add this functionality?

Maybe there are already functions I don't know about to ease this process ?

Any hint is greatly appreciated!

Greetings

Nico

Search Discussions

  • Andrea Faulds at May 21, 2014 at 1:29 pm

    On 21 May 2014, at 11:20, Nicolai Scheer wrote:

    I'm currently facing the situation, that I need to protect my php sources
    and retain opcache compatibility.
    “Protect”? Why? Are you trying to ship a product to customers which will be run by them, and not have them view the source?

    In which case, what’s wrong with obfuscation?
    --
    Andrea Faulds
    http://ajf.me/
  • Kevin Ingwersen at May 21, 2014 at 1:47 pm

    Am 21.05.2014 um 15:28 schrieb Andrea Faulds <ajf@ajf.me>:

    On 21 May 2014, at 11:20, Nicolai Scheer wrote:

    I'm currently facing the situation, that I need to protect my php sources
    and retain opcache compatibility.
    “Protect”? Why? Are you trying to ship a product to customers which will be run by them, and not have them view the source?

    In which case, what’s wrong with obfuscation?
    There are decent obfuscators? … have not seen any.
    And then, obfuscated code can be reversed still, whilst „sort of“ compiled code is far harder to reverse engeneer.
  • Andrea Faulds at May 21, 2014 at 1:52 pm

    On 21 May 2014, at 14:47, Kevin Ingwersen wrote:

    There are decent obfuscators? … have not seen any.
    And then, obfuscated code can be reversed still, whilst „sort of“ compiled code is far harder to reverse engeneer.
    For languages which don’t compile down to machine code, like PHP, C#, Java, JavaScript, Python, Perl or Ruby, obfuscation and (if it doesn’t use byte code) minification is really the best you can get. Such languages necessarily cannot be compiled down to the metal, so if you really don’t want anyone to read your code, I’m not sure there’s anything you can do. Then again, even x86 machine code can be decompiled.
    --
    Andrea Faulds
    http://ajf.me/
  • Nicolai Scheer at May 21, 2014 at 2:27 pm
    Hi,

    yes, we are shipping code to customers and they should not read the source.
    The level of protection gained from obfuscated code is not enough, but just
    delivering the opcodes would be ok.

    I know that the opcode array might be dumped, this is just to raise the
    bar. If I just obfuscate the code there's still the possibilty left to edit
    the code directly.

    Greetings

    Nico

    On 21 May 2014 15:52, Andrea Faulds wrote:

    On 21 May 2014, at 14:47, Kevin Ingwersen wrote:

    There are decent obfuscators? … have not seen any.
    And then, obfuscated code can be reversed still, whilst „sort of“
    compiled code is far harder to reverse engeneer.

    For languages which don’t compile down to machine code, like PHP, C#,
    Java, JavaScript, Python, Perl or Ruby, obfuscation and (if it doesn’t use
    byte code) minification is really the best you can get. Such languages
    necessarily cannot be compiled down to the metal, so if you really don’t
    want anyone to read your code, I’m not sure there’s anything you can do.
    Then again, even x86 machine code can be decompiled.
    --
    Andrea Faulds
    http://ajf.me/



  • Rasmus Lerdorf at May 21, 2014 at 2:51 pm

    On 5/21/14, 7:27 AM, Nicolai Scheer wrote:
    Hi,

    yes, we are shipping code to customers and they should not read the source.
    The level of protection gained from obfuscated code is not enough, but just
    delivering the opcodes would be ok.

    I know that the opcode array might be dumped, this is just to raise the
    bar. If I just obfuscate the code there's still the possibilty left to edit
    the code directly.
    It is completely trivial to turn opcodes back into PHP code. Sure, it
    won't look exactly like the original, but it will run exactly the same
    and can easily be modified. There are tools out there that let even a
    complete neophyte do it.

    If you truly want to protect your code, ship a signed compiled C/C++
    extension and put key components of your application in it. That is much
    harder to reverse (anything can be reversed, of course) and it has the
    added advantage of likely making your application faster.

    -Rasmus
  • Martin Keckeis at May 21, 2014 at 7:40 pm

    Am 21.05.2014 16:51 schrieb "Rasmus Lerdorf" <rasmus@lerdorf.com>:
    On 5/21/14, 7:27 AM, Nicolai Scheer wrote:
    Hi,

    yes, we are shipping code to customers and they should not read the
    source.
    The level of protection gained from obfuscated code is not enough, but
    just
    delivering the opcodes would be ok.

    I know that the opcode array might be dumped, this is just to raise the
    bar. If I just obfuscate the code there's still the possibilty left to
    edit
    the code directly.
    It is completely trivial to turn opcodes back into PHP code. Sure, it
    won't look exactly like the original, but it will run exactly the same
    and can easily be modified. There are tools out there that let even a
    complete neophyte do it.

    If you truly want to protect your code, ship a signed compiled C/C++
    extension and put key components of your application in it. That is much
    harder to reverse (anything can be reversed, of course) and it has the
    added advantage of likely making your application faster.

    -Rasmus
    Wasnt there zend guard sometime ago for this?
  • Nicolai Scheer at May 21, 2014 at 8:06 pm
    Hi!
    On 21 May 2014 21:40, Martin Keckeis wrote:

    Am 21.05.2014 16:51 schrieb "Rasmus Lerdorf" <rasmus@lerdorf.com>:
    On 5/21/14, 7:27 AM, Nicolai Scheer wrote:
    Hi,

    yes, we are shipping code to customers and they should not read the
    source.
    The level of protection gained from obfuscated code is not enough, but
    just
    delivering the opcodes would be ok.

    I know that the opcode array might be dumped, this is just to raise the
    bar. If I just obfuscate the code there's still the possibilty left to
    edit
    the code directly.
    It is completely trivial to turn opcodes back into PHP code. Sure, it
    won't look exactly like the original, but it will run exactly the same
    and can easily be modified. There are tools out there that let even a
    complete neophyte do it.

    If you truly want to protect your code, ship a signed compiled C/C++
    extension and put key components of your application in it. That is much
    harder to reverse (anything can be reversed, of course) and it has the
    added advantage of likely making your application faster.

    -Rasmus
    Wasnt there zend guard sometime ago for this?
    Zen guard is not an option, since it currently does not work with php 5.5.
    It did not check if the encoded scripts for php 5.4 are usable with
    opcache, though. Might be, because opcache was made out of ZendOptimizer+
    if I remember correctly.

    Greetings

    Nico
  • Nicolai Scheer at May 21, 2014 at 8:12 pm
    Hi
    On 21 May 2014 16:51, Rasmus Lerdorf wrote:
    On 5/21/14, 7:27 AM, Nicolai Scheer wrote:
    Hi,

    yes, we are shipping code to customers and they should not read the source.
    The level of protection gained from obfuscated code is not enough, but just
    delivering the opcodes would be ok.

    I know that the opcode array might be dumped, this is just to raise the
    bar. If I just obfuscate the code there's still the possibilty left to edit
    the code directly.
    It is completely trivial to turn opcodes back into PHP code. Sure, it
    won't look exactly like the original, but it will run exactly the same
    and can easily be modified. There are tools out there that let even a
    complete neophyte do it.

    If you truly want to protect your code, ship a signed compiled C/C++
    extension and put key components of your application in it. That is much
    harder to reverse (anything can be reversed, of course) and it has the
    added advantage of likely making your application faster.

    -Rasmus
    But that would imply developing our key components in C, wouldn't it?
    Unfortunately that is not feasible for our project.

    Do you have an example of a tool that can reverse opcodes to php code?
    Maybe I did not search for the right thing, I did not stumble upon any.

    I always thought the opcodes where kind of cryptic, at least a bit... I'm
    not longing for "true" protection. It's enough if the scripts can not be
    read and modified in an easy way.
    All I'm asking for is a way do so in way, that scripts are still cacheable
    (even if this makes dumping the opcodes easier...).

    I found Derick's Vulcan Logic Disassembler, I think this can help my
    understanding of what opcodes of a script look like.

    Greetings

    Nico
  • Andrea Faulds at May 21, 2014 at 8:20 pm

    On 21 May 2014, at 21:12, Nicolai Scheer wrote:

    I always thought the opcodes where kind of cryptic, at least a bit... I'm
    not longing for "true" protection. It's enough if the scripts can not be
    read and modified in an easy way.
    I don’t believe there’s any way to do that.

    --
    Andrea Faulds
    http://ajf.me/
  • Andrey Andreev at May 21, 2014 at 9:39 pm

    On Wed, May 21, 2014 at 11:19 PM, Andrea Faulds wrote:
    On 21 May 2014, at 21:12, Nicolai Scheer wrote:

    I always thought the opcodes where kind of cryptic, at least a bit... I'm
    not longing for "true" protection. It's enough if the scripts can not be
    read and modified in an easy way.
    I don’t believe there’s any way to do that.
    There's Zend Guard, ionCube and I also recall a third similar product
    (that probably no longer exists), but AFAIK none of them works with
    PHP 5.5 and OpCache is most likely the blocker for them.

    If OpCache and/or some syntax sugar isn't really a requirement though,
    I remember some years ago I had to use a Zend Guard version that was
    built for PHP 5.2 in a 5.3 environment ... using syntax compatible
    with 5.2 did the trick.

    My $0.02,
    Andrey.
  • Johannes Schlüter at May 21, 2014 at 10:25 pm

    On Thu, 2014-05-22 at 00:39 +0300, Andrey Andreev wrote:
    There's Zend Guard, ionCube and I also recall a third similar product
    (that probably no longer exists), but AFAIK none of them works with
    PHP 5.5 and OpCache is most likely the blocker for them.
    I assume that the Zend Guard authors have good access to Opcache
    authors, so if there are issues they'll find a way to solve these.

    The third conmercial one (next to Zend and ioncube) is
    http://www.camouflage-encoder.com/ which promises "guaranteed support
    for new PHP versions within 3 months" and "full support for PHP 5.3 and
    PHP 5.4" (both quotes from the mentioned page)

    If the commercial vendors don't provide 5.5 versions apparently they
    don't care about that market. So if you want it you should talk to them
    and convince them that they loose profits ... nothing we can do and this
    is not the forum for that conversation.

    From the non-commercial side these bcompiler etc. seem not to attract
    developers. So apparently there seem to be no sponsors willing to take
    that work ... while it is hard to find qualified developers with both,
    knowledge of PHP internals and crypto/security ... but checking commit
    logs, credits etc. might lead to people one could eventually ask ...
    while this list is no job market either ;)

    johannes
  • Matteo Beccati at May 22, 2014 at 7:37 am

    On 22/05/2014 00:25, Johannes Schlüter wrote:
    The third conmercial one (next to Zend and ioncube) is
    http://www.camouflage-encoder.com/ which promises "guaranteed support
    for new PHP versions within 3 months" and "full support for PHP 5.3 and
    PHP 5.4" (both quotes from the mentioned page)
    Given I've seen a few commercial products listed already, I feel
    compelled as a long time customer to also remind you about Sourceguardian.

    IIRC one of the first alternatives the the early Zend Encoder on the market.

    It works for me and it's 5.5 compatible, although I don't know exactly
    what is its current behaviour with opcode caches. I've asked if they can
    shed a light.


    Cheers
    --
    Matteo Beccati

    Development & Consulting - http://www.beccati.com/
  • Nicolai Scheer at May 22, 2014 at 8:18 am
    Hi!

    On 22 May 2014 09:37, Matteo Beccati wrote:
    On 22/05/2014 00:25, Johannes Schlüter wrote:
    The third conmercial one (next to Zend and ioncube) is
    http://www.camouflage-encoder.com/ which promises "guaranteed support
    for new PHP versions within 3 months" and "full support for PHP 5.3 and
    PHP 5.4" (both quotes from the mentioned page)
    Given I've seen a few commercial products listed already, I feel
    compelled as a long time customer to also remind you about Sourceguardian.

    IIRC one of the first alternatives the the early Zend Encoder on the
    market.

    It works for me and it's 5.5 compatible, although I don't know exactly
    what is its current behaviour with opcode caches. I've asked if they can
    shed a light.


    Cheers
    --
    Matteo Beccati
    Sourceguardian "works" with opcache, but not the way it is supposed to.
    SourcGuardian encoded scripts essentially consist just of a function call
    to sg_load() which takes the encrypted script as a parameter. Therefor, the
    script itself gets cached by opcache but since the decryption process and
    class loading ist just a function call, there's not the speed improvement I
    need.

    Greetings

    Nico
  • Nicolai Scheer at May 23, 2014 at 1:31 pm
    Hi!
    On 22 May 2014 00:25, Johannes Schlüter wrote:
    On Thu, 2014-05-22 at 00:39 +0300, Andrey Andreev wrote:
    There's Zend Guard, ionCube and I also recall a third similar product
    (that probably no longer exists), but AFAIK none of them works with
    PHP 5.5 and OpCache is most likely the blocker for them.
    I assume that the Zend Guard authors have good access to Opcache
    authors, so if there are issues they'll find a way to solve these.

    The third conmercial one (next to Zend and ioncube) is
    http://www.camouflage-encoder.com/ which promises "guaranteed support
    for new PHP versions within 3 months" and "full support for PHP 5.3 and
    PHP 5.4" (both quotes from the mentioned page)

    If the commercial vendors don't provide 5.5 versions apparently they
    don't care about that market. So if you want it you should talk to them
    and convince them that they loose profits ... nothing we can do and this
    is not the forum for that conversation.

    From the non-commercial side these bcompiler etc. seem not to attract
    developers. So apparently there seem to be no sponsors willing to take
    that work ... while it is hard to find qualified developers with both,
    knowledge of PHP internals and crypto/security ... but checking commit
    logs, credits etc. might lead to people one could eventually ask ...
    while this list is no job market either ;)

    johannes
    The people from Zend where not able to comment on the release date of
    ZendGuard for php 5.5.
    I asked the SourceGuardian staff, it's on their wish list...

    "guaranteed support for new PHP versions within 3 months"... and they don't
    support php 5.5? :)
    So camouflage-encoder is not an option either.

    Greetings

    Nico
  • Derick Rethans at May 21, 2014 at 10:53 pm

    On Wed, 21 May 2014, Nicolai Scheer wrote:

    Do you have an example of a tool that can reverse opcodes to php code?
    Maybe I did not search for the right thing, I did not stumble upon any.
    It exists, there are tools. I might have seen code that does it.
    I always thought the opcodes where kind of cryptic, at least a bit... I'm
    not longing for "true" protection. It's enough if the scripts can not be
    read and modified in an easy way.
    Yes, that is definitely possible. I actually have a working extension
    for PHP 5.3 and 5.4 that stores encrypted opcodes. PHP 5.5 not yet
    implemented.
    All I'm asking for is a way do so in way, that scripts are still
    cacheable (even if this makes dumping the opcodes easier...).
    Yes, correct. You can get to the opcodes, it's not difficult, it even
    works with VLD, that you mention here:
    I found Derick's Vulcan Logic Disassembler, I think this can help my
    understanding of what opcodes of a script look like.
    cheers,
    Derick
  • Nicolai Scheer at May 23, 2014 at 1:52 pm
    Hi!
    On 22 May 2014 00:53, Derick Rethans wrote:
    On Wed, 21 May 2014, Nicolai Scheer wrote:

    Do you have an example of a tool that can reverse opcodes to php code?
    Maybe I did not search for the right thing, I did not stumble upon any.
    It exists, there are tools. I might have seen code that does it.
    I always thought the opcodes where kind of cryptic, at least a bit... I'm
    not longing for "true" protection. It's enough if the scripts can not be
    read and modified in an easy way.
    Yes, that is definitely possible. I actually have a working extension
    for PHP 5.3 and 5.4 that stores encrypted opcodes. PHP 5.5 not yet
    implemented.
    That's very interesting. Guess you won't share the code?

    Maybe we can get a little more technical again... As I already said, the
    blenc extension would be a good start (just store encrypted php sources),
    at least for me to experiment with. Unfortunately it crashes php when used
    with opcache. To be more precise it seems to crash, when an included file
    is served from opcache's cache.

    I tried to do my own minimal extension for testing purposes. It justs
    overrides zend_compile_file, so it can read base64 encoded files.

    It boils down to:

    zend_op_array *my_compile(zend_file_handle *file_handle, int type TSRMLS_DC)
    {
         char *buf, *decoded_buf;
         size_t buf_size, decoded_buf_size = 0;
         zval *code;
         zend_op_array *opcode = NULL;

         zend_stream_fixup( file_handle, &buf, &buf_size );

         if ( strncasecmp( buf, "BS64:", 5 ) == 0 )
         {
             MAKE_STD_ZVAL(code);

             // just base64_decode the file...
             decoded_buf = php_base64_decode(buf+5, buf_size-5,
    &decoded_buf_size );

             // cut <?php...
             ZVAL_STRINGL( code, decoded_buf+5, decoded_buf_size-5, TRUE );

             opcode = zend_compile_string( code, (char*)file_handle->filename
    TSRMLS_CC );

             efree(decoded_buf);
             efree(code);
         }
         else
         {
             opcode = zend_compile_file_original( file_handle, type TSRMLS_CC );
         }

         return opcode;
    }

    The "encoded" files just contain the string "BS64:" followed by the base64
    encoded script.

    I tested this one on windows, 32bit, php 5.5.12, VC11 NTS using the shipped
    opcache extension using the php embedded webserver.

    The main file:

    <?php

    echo "hello world - me\n";
    require_once __DIR__ . '/class_1.php';
    #echo "stuff?";


    The "encoded" file class_1.php:

    BS64:PD9waHANCg0KY2xhc3MgY2xhc3NfMQ0Kew0KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpDQoJew0KCQllY2hvICJjcmVhdGVkIG9iamVjdCBmcm9tIGNsYXNzIDFcbiI7DQoJfQ0KDQp9DQo=

    If I run this once (php started via php -S localhost:8000) it works fine. I
    added a lot of debug comments to the opcache code ensuring it runs through
    the methods I expect.
    If I run this twice, everything is still ok. Now, if I just uncomment the
    "echo stuff" in the main script and run it again, php crashes.

    That's the very same behaviour I get with blenc. I don't know why it is
    crashing. I had an intermediate example where it crashed everytime I used
    an included encoded script, but I can not reproduce this again.

    It seems, as if the opcode returned from zend_compile_string differs from
    the usual zend_compile and this crashes the engine when this opcode is
    executed again (fetched from opache). Also, there are memory leaks reported
    for the function above (zend_opcode.c and plain_wrapper.c), maybe I'm just
    doing it wrong?

    Any insight is very appreciated. I know this approach is stupid simple, but
    I'm just trying to figure out which way I could proceed and how stuff works
    down there.

    Thanks for any help!

    Greetings

    Nico
  • Nicolai Scheer at May 27, 2014 at 9:20 am
    Hi!
    On 23 May 2014 15:52, Nicolai Scheer wrote:


    [...]
    It seems, as if the opcode returned from zend_compile_string differs from
    the usual zend_compile and this crashes the engine when this opcode is
    executed again (fetched from opache). Also, there are memory leaks reported
    for the function above (zend_opcode.c and plain_wrapper.c), maybe I'm just
    doing it wrong?

    Any insight is very appreciated. I know this approach is stupid simple,
    but I'm just trying to figure out which way I could proceed and how stuff
    works down there.

    Thanks for any help!
    I filed a bug report for blenc https://bugs.php.net/bug.php?id=67344.
    I think it's the same issue I'm experiencing. From what I've learned so
    far, it seems that I'd have to fix some pointers inside the opcode
    structure. On the first run, everything is in place and works as expected,
    but the seconds run, being served from opcache is problematic.

    Can anybody give me a hint where to start?

    Thanks!

    Greetings

    Nico
  • Rowan Collins at May 21, 2014 at 11:08 pm

    On 21/05/2014 21:12, Nicolai Scheer wrote:
    Do you have an example of a tool that can reverse opcodes to php code?
    Maybe I did not search for the right thing, I did not stumble upon any.

    I always thought the opcodes where kind of cryptic, at least a bit...
    I don't know of any tools for "decompiling" PHP from opcodes, but that's
    probably because very few tools generate or distribute opcodes from
    anything other than PHP source, so there has been little desire for such
    a thing.

    I have, however, seen the result of a Java decompiler, which can perform
    a similar job on JVM bytecode; the results are less obfuscated than a
    lot of "minified" JS scripts deployed to save bandwidth. I imagine the
    Zend Engine's opcodes are even more closely bound to PHP than the JVM's
    instructions are to Java, so I can well imagine an effective decompiler
    being possible if the motivation were there.


    On a different note, I read somewhere that once HHVM has loaded each of
    your PHP files once, it no longer needs a copy on the file system, and
    can be told to never check for one. Thus you can deploy PHP code to a
    server, "prime" the HHVM memory, and then delete the source files. I
    don't know if there's any way to persist that memory state and
    distribute it to another HHVM instance, though.

    --
    Rowan Collins
    [IMSoP]
  • Pierre Joye at May 21, 2014 at 2:49 pm

    On May 21, 2014 4:28 PM, "Nicolai Scheer" wrote:
    Hi,

    yes, we are shipping code to customers and they should not read the source.
    The level of protection gained from obfuscated code is not enough, but just
    delivering the opcodes would be ok.

    I know that the opcode array might be dumped, this is just to raise the
    bar. If I just obfuscate the code there's still the possibilty left to edit
    the code directly.
    Php does not support that. There are solutions out there (like in pecl) but
    I have no idea about their state or support.
  • Thomas Bley at May 22, 2014 at 1:54 am
    Hi Nico,

    you can try to ship an encrypted virtual machine and run PHP inside it. Then point your web server to the fpm socket of the virtual machine.
    Maybe VMware Player suspend-to-disk works with full disk encryption without re-entering the password on wakeup, but I haven't tried it. This wouldn't be 100 percent secure, but it least compatible with all PHP versions.

    Regards
    Thomas


    Nicolai Scheer wrote on 21.05.2014 12:20:
    Hi all,

    I'm currently facing the situation, that I need to protect my php sources
    and retain opcache compatibility.

    I know there are quite a few commercial tools for "encoding" and protecting
    php sources, but none of them seems to work in conjunction with php's
    opcache extension.

    Most products see this as part of their protection scheme.

    Basically it would be ok to just dump the _zend_op_array struct (defined in
    zend_compile.h) to a file and make the zend engine able to load it again.
    Once it is loaded, it could be server from opcache.

    Unfortunately bcompiler is not (yet?) compatible with php 5.5.x, and
    digging through the source it seems to be not an easy task to serialize the
    opcode array (seems as if the code is borrowed from apc).

    I also had a look at blenc, which just overrides the compile_function to
    read an encrypted source file and then compile the resulting string. This
    might be a first solution, though I'd rather deliver opcodes to the
    client's server than just an encrypted script. Sadly blenc just crashes php
    when it tries to serve an encrypted script from opcache and I could not
    figure out yet, what's wrong there (tested on windows and linux using php
    5.5.12).

    Is there any solution for my situation?
    Are there any plans to add the "serialize opcode to string, dump string to
    file and load it again"-functionality to php?
    How easy would it be to add this functionality?

    Maybe there are already functions I don't know about to ease this process ?

    Any hint is greatly appreciated!

    Greetings

    Nico
  • Bas van Beek at May 22, 2014 at 7:08 am

    op 21-05-14 12:20, Nicolai Scheer schreef:
    Hi all,

    I'm currently facing the situation, that I need to protect my php sources
    and retain opcache compatibility.

    I know there are quite a few commercial tools for "encoding" and protecting
    php sources, but none of them seems to work in conjunction with php's
    opcache extension.

    Most products see this as part of their protection scheme.
    As said in the conversation spawned by your question it is possible to
    reverse engineer the opcodes to php script and as you noted you're ok
    with at least a first line of defense against customers altering
    scripts. I might have a workable solution to your problem.

    I faced a similar problem where I didn't want the PHP source code for a
    client application (win32 service/*nix daemon with embedded webserver,
    PHP API layer and AngularJS front-end) to be easily viewed and/or
    modified. So I built an embedded filesystem that is encrypted. For this
    embedded filesystem I wrote a PHP stream extension so I can access the
    files in that filesystem as if they reside on a regular disk. In the C++
    code of the main app I open the embedded filesystem with the decryption
    key and I make a filesystem handle available to the PHP stream
    extension. The embedded webserver can access the embedded filesystem
    directly with its API and within PHP the stream extension takes care of
    that. This solution is compatible with PHP 5.5 and opcache and has the
    added bonus of only needing to ship a single file for all PHP, JS, Image
    and other web resource files). Hope this solution points you in the
    right direction.

    Bas van Beek
  • Kevin Ingwersen at May 22, 2014 at 1:47 pm

    Am 22.05.2014 um 09:08 schrieb Bas van Beek <bas@tobin.nl>:


    op 21-05-14 12:20, Nicolai Scheer schreef:
    Hi all,

    I'm currently facing the situation, that I need to protect my php sources
    and retain opcache compatibility.

    I know there are quite a few commercial tools for "encoding" and protecting
    php sources, but none of them seems to work in conjunction with php's
    opcache extension.

    Most products see this as part of their protection scheme.
    As said in the conversation spawned by your question it is possible to reverse engineer the opcodes to php script and as you noted you're ok with at least a first line of defense against customers altering scripts. I might have a workable solution to your problem.

    I faced a similar problem where I didn't want the PHP source code for a client application (win32 service/*nix daemon with embedded webserver, PHP API layer and AngularJS front-end) to be easily viewed and/or modified. So I built an embedded filesystem that is encrypted. For this embedded filesystem I wrote a PHP stream extension so I can access the files in that filesystem as if they reside on a regular disk. In the C++ code of the main app I open the embedded filesystem with the decryption key and I make a filesystem handle available to the PHP stream extension. The embedded webserver can access the embedded filesystem directly with its API and within PHP the stream extension takes care of that. This solution is compatible with PHP 5.5 and opcache and has the added bonus of only needing to ship a single file for all PHP, JS, Image and other web resource files). Hope this solution points you in the right direction.
    This solution sounds very great! Creating a PHP extension to operate on an encrypted, virtual, filesystem mibht offer exactly what one is looking for. If the app is small, it could be loaded into memory, and be read by far faster from there.

    Definitively an aproach I am going to test out myself, to learn more about this.
    Kind regards, Ingwie.
  • Arvids Godjuks at May 22, 2014 at 2:01 pm
    Maybe the Zephyr http://zephir-lang.com/ could give you an alternative to
    messing with OPCache and encoders and give you some performance boost at
    the same time. But only if your client can configure PHP to load an
    extension of yours that Zephyr makes.


    2014-05-22 16:47 GMT+03:00 Kevin Ingwersen <ingwie2000@googlemail.com>:
    Am 22.05.2014 um 09:08 schrieb Bas van Beek <bas@tobin.nl>:
    op 21-05-14 12:20, Nicolai Scheer schreef:
    Hi all,

    I'm currently facing the situation, that I need to protect my php
    sources
    and retain opcache compatibility.

    I know there are quite a few commercial tools for "encoding" and
    protecting
    php sources, but none of them seems to work in conjunction with php's
    opcache extension.

    Most products see this as part of their protection scheme.
    As said in the conversation spawned by your question it is possible to
    reverse engineer the opcodes to php script and as you noted you're ok with
    at least a first line of defense against customers altering scripts. I
    might have a workable solution to your problem.
    I faced a similar problem where I didn't want the PHP source code for a
    client application (win32 service/*nix daemon with embedded webserver, PHP
    API layer and AngularJS front-end) to be easily viewed and/or modified. So
    I built an embedded filesystem that is encrypted. For this embedded
    filesystem I wrote a PHP stream extension so I can access the files in that
    filesystem as if they reside on a regular disk. In the C++ code of the main
    app I open the embedded filesystem with the decryption key and I make a
    filesystem handle available to the PHP stream extension. The embedded
    webserver can access the embedded filesystem directly with its API and
    within PHP the stream extension takes care of that. This solution is
    compatible with PHP 5.5 and opcache and has the added bonus of only needing
    to ship a single file for all PHP, JS, Image and other web resource files).
    Hope this solution points you in the right direction.
    This solution sounds very great! Creating a PHP extension to operate on an
    encrypted, virtual, filesystem mibht offer exactly what one is looking for.
    If the app is small, it could be loaded into memory, and be read by far
    faster from there.

    Definitively an aproach I am going to test out myself, to learn more about
    this.
    Kind regards, Ingwie.


    --
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: http://www.php.net/unsub.php
  • Nicolai Scheer at May 23, 2014 at 1:26 pm
    Hi!
    On 22 May 2014 16:01, Arvids Godjuks wrote:

    Maybe the Zephyr http://zephir-lang.com/ could give you an alternative to
    messing with OPCache and encoders and give you some performance boost at
    the same time. But only if your client can configure PHP to load an
    extension of yours that Zephyr makes.
    That again involves rewriting a lot of scripts which is unfortunately not
    feasible.

    Greetings

    Nico
  • Arvids Godjuks at May 23, 2014 at 1:39 pm

    2014-05-23 16:25 GMT+03:00 Nicolai Scheer <nicolai.scheer@gmail.com>:

    Hi!
    On 22 May 2014 16:01, Arvids Godjuks wrote:

    Maybe the Zephyr http://zephir-lang.com/ could give you an alternative to
    messing with OPCache and encoders and give you some performance boost at
    the same time. But only if your client can configure PHP to load an
    extension of yours that Zephyr makes.
    That again involves rewriting a lot of scripts which is unfortunately not
    feasible.

    Greetings

    Nico
    I'd suggest at least checking it out.
    It is a smaller subset of PHP and as far as I know, they have some kind of
    translator from PHP into Zephir, so you can just fix the parts that are
    dynamic in nature and should be done differently in Zephir. And you don't
    need to put all the code into it - just important classes that you really
    wana hide.
    You can't write direct code in Zephir, just the classes. It's a tool for
    creating library code that is done as a PHP extension.

    Arvids.
  • Nicolai Scheer at May 23, 2014 at 1:55 pm
    Hi!
    On 23 May 2014 15:39, Arvids Godjuks wrote:

    2014-05-23 16:25 GMT+03:00 Nicolai Scheer <nicolai.scheer@gmail.com>:

    Hi!
    On 22 May 2014 16:01, Arvids Godjuks wrote:

    Maybe the Zephyr http://zephir-lang.com/ could give you an alternative
    to
    messing with OPCache and encoders and give you some performance boost at
    the same time. But only if your client can configure PHP to load an
    extension of yours that Zephyr makes.
    That again involves rewriting a lot of scripts which is unfortunately not
    feasible.

    Greetings

    Nico
    I'd suggest at least checking it out.
    It is a smaller subset of PHP and as far as I know, they have some kind of
    translator from PHP into Zephir, so you can just fix the parts that are
    dynamic in nature and should be done differently in Zephir. And you don't
    need to put all the code into it - just important classes that you really
    wana hide.
    You can't write direct code in Zephir, just the classes. It's a tool for
    creating library code that is done as a PHP extension.

    Arvids.
    Yes, I will check it out, of course :)

    Greetings

    Nico
  • Johannes Schlüter at May 22, 2014 at 2:29 pm

    On Thu, 2014-05-22 at 15:47 +0200, Kevin Ingwersen wrote:
    Definitively an aproach I am going to test out myself, to learn more
    about this.
    Mind that a user could simply do something like this in an
    auto_append_file to get all scripts:

        <?php
        foreach (get_included_files() as $filename) {
            $sourcecode[$filename] = file_get_contents($filename);
        }
        ?>

    So this ains little over using a phar file.

    The question is from what kind of users one wants to hide this ...
    >
    The simple solutions provide ways to retrieve the source code easily (be
    it by a simple printf() in the engine .. even that should be doable by
    everybody who could understand the source and who has interest in it).
    The a bit more advanced ways allow dumping opcodes which can be used to
    Recreate the PHP code quite closely (our opcodes are quite high level
    and we don't do notable optimisations, we even keep original names for
    most things)
    More advanced solutions use an extra executor and (more or less)
    modified opcodes. This requires hacking this opcode ... has been done in
    the past.
    So maybe indeed go to system level (C / C++) languages.

    What you also can do is rethink your business model, if you distrust the
    users that much maybe you don't bring them the notable business value.
    I've seen different companies which got rid of opcode encryption and the
    customers loved the simpler deployment ...
    (and yes, there are [more or less] valid business models around specific
    algorithms, if the secrecy of the algorithm really is your value then
    put it in C)

    johannes
  • Bas van Beek at May 22, 2014 at 2:54 pm

    op 22-05-14 16:29, Johannes Schlüter schreef:
    On Thu, 2014-05-22 at 15:47 +0200, Kevin Ingwersen wrote:
    Definitively an aproach I am going to test out myself, to learn more
    about this.
    Mind that a user could simply do something like this in an
    auto_append_file to get all scripts:

    <?php
    foreach (get_included_files() as $filename) {
    $sourcecode[$filename] = file_get_contents($filename);
    }
    ?>

    So this ains little over using a phar file.
    Maybe I'm missing something but I don't see that happen if PHP is
    embedded in the C++ application through its own SAPI handler which will
    not pick up any ini directives from external php.ini files.

    Bas van Beek
  • Johannes Schlüter at May 22, 2014 at 3:17 pm

    On Thu, 2014-05-22 at 16:54 +0200, Bas van Beek wrote:
    Mind that a user could simply do something like this in an
    auto_append_file to get all scripts:

    <?php
    foreach (get_included_files() as $filename) {
    $sourcecode[$filename] = file_get_contents($filename);
    }
    ?>

    So this ains little over using a phar file.
    Maybe I'm missing something but I don't see that happen if PHP is
    embedded in the C++ application through its own SAPI handler which will
    not pick up any ini directives from external php.ini files.
    If you are not giving scripting access to the user so they can't execute
    (well, they might attach a debugger and call zend_eval_string() etc.)
    PHP code than this is ok. My response was mostly to Kevin, whom I
    understood in a way as we was up to making this a general purpose
    "source code hiding extension" for "normal" deployments.

    johannes
  • Lazy at May 22, 2014 at 7:18 pm

    2014-05-21 12:20 GMT+02:00 Nicolai Scheer <nicolai.scheer@gmail.com>:
    Hi all,

    I'm currently facing the situation, that I need to protect my php sources
    and retain opcache compatibility.
    Basically it would be ok to just dump the _zend_op_array struct (defined in
    zend_compile.h) to a file and make the zend engine able to load it again.
    Once it is loaded, it could be server from opcache.
    Is there any solution for my situation?
    Are there any plans to add the "serialize opcode to string, dump string to
    file and load it again"-functionality to php?
    How easy would it be to add this functionality?

    Maybe there are already functions I don't know about to ease this process ?
    you should look at https://github.com/TerryE/opcache by Terry Ellison
    and https://github.com/TerryE/opcache/wiki has many information about
    serializing/deserializing opcode

    This MLC Opcache is targeted at cli/cgi workloads (it loads cache from
    the file and fixes memory references).
    In Your scenario if You prepare a file with complete cache, and
    disable file existence/mtime checking in the
    opcache ini files this might be sufficient to achieve Your goal eaven
    if you use fcgi. The only problem might be the support for
    fastcgi/mod_php sapi, IMHO it will load a cache file based on the
    first request and behave like a regular opcache for the next requests
    but YMMV (I have loked at this some time ago).

    Alternatively if You are a brave person, or like some might say crazy ;)
    You might try my fork
    https://github.com/lazy404/ZendOptimizerPlus/tree/fcgid (check wiki
    for config directions). It
    supports memory reclamation (when cache is recycled), loading cache
    from a file (works best when the file is on
    tmpfs), sharing cache between php processes started by an external
    process manager (like mod_fcgid). A more
    "polished" version is used to serve thousands websites with millions
    of total request's daily. The bad part is that it is a
    hack done fast, documentation is non existent, the code is very ugly,
    I'm not sure if locking is implemented correctly,
    and there are no deadlock detection. It was only done to check if it
    was possible to make opcache work with mod_fcgid
    (parts of code ware taken from TerryE's fork). There are some known
    issues (sometimes php crash corrupts the cache,
    the code on github is old and has some known minor bugs which are
    fixed elsewhere).

    The idea behind this fork is simple
    1) use opcode reference address fixing from MLC Opcache
    2) store the result in a fixed address in a memory region backed by a
    mmaped tmpfs file (on linux this allows using madvise() to nuke the
    cache and return the memory to the os)

    --
    Michal Grzedzicki
  • Nicolai Scheer at May 23, 2014 at 1:23 pm
    Hi!
    On 22 May 2014 21:18, Lazy wrote:

    2014-05-21 12:20 GMT+02:00 Nicolai Scheer <nicolai.scheer@gmail.com>:
    Hi all,

    I'm currently facing the situation, that I need to protect my php sources
    and retain opcache compatibility.
    Basically it would be ok to just dump the _zend_op_array struct (defined in
    zend_compile.h) to a file and make the zend engine able to load it again.
    Once it is loaded, it could be server from opcache.
    Is there any solution for my situation?
    Are there any plans to add the "serialize opcode to string, dump string to
    file and load it again"-functionality to php?
    How easy would it be to add this functionality?

    Maybe there are already functions I don't know about to ease this
    process ?

    [MLC Opcache links]

    --
    Michal Grzedzicki
    That's very interesting! I'll look into that stuff!

    Thanks!

    Nico

Related Discussions

People

Translate

site design / logo © 2022 Grokbase