OsomA
OsomA

Reputation: 147

Replace protected memeber in decoded base64 string

Let's say i have a class like this

class ClassA {
   public $publicMember;
   private $privateMember;
   protected $protected;
}

And i encoded the object ClassA like this:

$objectA = new ClassA();
$stringA = base64_encode(serialize($objectA));

I want to replace all protected member but i don't know how. I've tried like this:

$newString = str_replace('�*�', '', base64_decode($stringA));

I am sorry it this question is easy, but i really don't know how to handle this. Thank you!

Upvotes: 0

Views: 63

Answers (2)

sectus
sectus

Reputation: 15464

Let's try another way:

  1. convert serialzed class to stdClass
  2. unserialize
  3. add public protected properties
  4. serialize
  5. convert serialized stdClass to original

--

class ClassA
    {

    public $publicMember;
    private $privateMember;
    protected $protected;

    }

$objectA = new ClassA();
$stringA = serialize($objectA);

// 1. convert serialzed class to stdClass
$stringA = preg_replace('/' . strlen('ClassA') . '/', strlen('stdClass'), $stringA, 1);
$stringA = preg_replace('/ClassA/', 'stdClass', $stringA, 1);

// 2. unserialize
$object = unserialize($stringA);

// 3. add public protected properties
while (list($key, $value) = each($object)) // hack with each
    {
    if (strpos($key, "\x00*\x00") === 0)
        {
        $key = str_replace("\x00*\x00", '', $key);
        $object->$key = $value;
        }
    }

// 4. serialize
$stringB = serialize($object);

// 5. convert serialized stdClass to original
$stringB = preg_replace('/' . strlen('stdClass') . '/', strlen('ClassA'), $stringB, 1);
$stringB = preg_replace('/stdClass/', 'ClassA', $stringB, 1);

var_dump(unserialize($stringB));

Produces

class ClassA#3 (4) {
  public $publicMember =>
  NULL
  private $privateMember =>
  NULL
  protected $protected =>
  NULL
  public $protected =>
  NULL
}

P.S. it's safer than first one, but ... : )

Upvotes: 0

sectus
sectus

Reputation: 15464

Property name precedes with length.

string(92) "O:6:"ClassA":3:{s:12:"publicMember";N;s:21:"\000ClassA\000privateMember";N;s:12:"\000*\000protected";N;}"
| property name length        ^                     ^                                    ^
| we will try to capture this part                                                      ^         ^    

You ned reduce this length if you what to "convert" protected to public. For example.

class ClassA
    {

    public $publicMember;
    private $privateMember;
    protected $protected;

    }

$objectA = new ClassA();
$stringA = serialize($objectA);
$converted = preg_replace_callback('@:(\d+):"\x00\*\x00@', function($match)
//                                     ^ catch the number
//                                           ^     ^    null symbols        
    {
    $property_name_length = $match[1];
    return ':' . ($property_name_length - 3) . ':"'; // reduce catched number and do not return \x00*\x00
    }, $stringA);
var_dump(unserialize($converted));

Produces

class ClassA#2 (4) {
  public $publicMember =>
  NULL
  private $privateMember =>
  NULL
  protected $protected =>
  NULL
  public $protected =>
  NULL
}

P.S. But this code will fail when you start to store serialized like data as members values.

Upvotes: 1

Related Questions