pk-fr / yakpro-po

YAK Pro - Php Obfuscator
http://www.php-obfuscator.com
Other
1.27k stars 354 forks source link

Bug Fix and "Only private" feature #45

Closed lucasexe closed 4 years ago

lucasexe commented 5 years ago

Bug found: "Namespace scramble" wasn't covering all cases: Example:

try {
} catch (MyApp\Logs\Exception $e) {
}

In the code above, 'MyApp' and 'Logs' weren't being scrambled.

Another situation when the result code was ill-formed:

\MyApp\Logs\MyClass::doSomething();

Besides the bug fix, I also have added a new feature to obfuscate only private properties/methods inside a class. This is an intermediate alternative when we can't obfuscate all methods/properties.

I've used the code below to validate my implementation:

<?php
namespace Tester\Lucas\Obs;

class Test {
    private static $var = 0;
    private static $var2 = 1;
    protected static $var3 = 2;

    public function __construct(){
    }

    public function test($a, $b) {
        return \Tester\Lucas\Obs\Test::compute($a, $b) + self::$var + $this->var3;
    }

    private static function compute($a, $b = 5) {
        if ($b < $a) return self::compute($b, $a);
        $y = $a * $b + Test::$var;
        try {
            $t = $a + $b + \Tester\Lucas\Obs\Test::$var2;
        } catch(\Tester\Rangel\Obs $a) {
        }
        return $y - $t;
    }
}

echo (new Test())->test(1, 2, 3);

The result:

namespace vEvel\fTaPJ\ix2Bo;
class z429y {
    private static $QDgoR = 0;
    private static $ArYnb = 1;
    protected static $var3 = 2;
    public function __construct() { }
    public function r9arP($YLAuT, $UwsS1) {
        return \vevEl\ftApJ\ix2bO\z429Y::OEzRa($YLAuT, $UwsS1) + self::$QDgoR + $this->var3;
    }
    private static function OEzrA($YLAuT, $UwsS1 = 5) {
        goto rDTTn;
        FfJ6p:
        return self::oezRa($UwsS1, $YLAuT);
        goto dZ6Xv;
        ZEegy:
        return $Iw_vn - $jENna;
        goto r_BTA;
        iwYTD:
        try {
            $jENna = $YLAuT + $UwsS1 + \veVEl\ftapJ\ix2BO\z429Y::$ArYnb;
        } catch (\vevel\nN3yx\ix2Bo $YLAuT) { }
        goto ZEegy;
        rDTTn:
        if (!($UwsS1 < $YLAuT)) {
            goto WQfMd;
        }
        goto FfJ6p;
        dZ6Xv:
        WQfMd:
        goto b7RtX;
        b7RtX:
        $Iw_vn = $YLAuT * $UwsS1 + z429Y::$QDgoR;
        goto iwYTD;
        r_BTA:
    }
}
echo (new Z429y())->r9aRp(1, 2, 3);
pk-fr commented 4 years ago

tried to apply only bug fixes... perhaps i missed some ... only_private feature is not working, you can test this small example:

<?php
class test
{
    public function main()
    {
        $this::hello();
    }
    private function hello()
    {
        echo "hello {$this->x}\n";
        $this::hi();
    }
    private function hi()
    {
        echo "private hi\n";
    }
    private $x = "world";
}
$x = new test;
$x->main();
?>

method call is done at run time, it is impossible to easyly differentiate a call to a public method or to a private method within a class.... ( the function can be defined after the call ) perhaps a day, I will try it can be done with a mimimum of 2 passes, the first classifying all methods, than the second pas, analysing all calls... even with this, if some part of the class is defined within an include, it will be quite impossible.