Looking in to the mirror
============================

## Introduction

This challenge was about employing reflection techniques to modify and view internal structures of the virtual machine.

Pharo is a Smalltalk environment, most widely known for its metaprogramming and reflection capabilities. Everything in Smalltalk is an object, and every object is an instance of a class, even a class itself is an instance of something (a metaclass).

The syntax of a Smalltalk program is relatively simple, the most important part is how to send messages (in other object oriented languages also called: invoking a method).

Lets say we want to send a message `newWithName` to a class `Person`, this can be achieved as follows:

```
p := Person newWithName:'Bram'.
```

Now the variable `p` contains a reference to an instance of the class `Person`.

Messages that can be send to classes themselves are defined on the metaclass of a class. In this case the metaclass is the `Person class` class. We can obtain a reference to a method itself by using the `>>` (lookup) operator:

```
(Person class)>>#newWithName
```

## The Challenge

The challenge consisted of connecting to a remote endpoint using netcat, which provided a Smalltalk REPL where Smalltalk expressions
could be executed.

The Pharo VM contained serveral user-defined classes:

* Challenge
* Squeak

The REPL suggested that you could obtain the flag by using:

```
Challenge new flag
```

however, when trying to do this, the REPL would yield that `only a Squeak could to that`, which means that the method `flag` could only be called from an instance of the class `Squeak`.

Luckily, the `Squeak` class contained a method named `fetchFlag`. So lets try to do this:

```
Squeak new fetchFlag.
```

This however, yields an initialisation error, suggesting that no instance of a `Squeak` could be created.

## Solution(s)

As Pharo has many ways to interact with classes and objects, the challenge has many solutions. Here, I will only present two possible solutions. One involves inspecting the method dictionnary of the `Challenge` class, the other involves overwriting the behaviour in the `Squeak` class that prevents its instance creation.

### Inspecting the Challenge class

Its is clear that we need to obtain some representation of the source of the `flag` method of the `Challenge` class.

We can try to obtain a reference to this method by using the lookup operator:

```
Challenge>>#flag
```

however, this results in a `LookupError`, the `Challenge` class seems to be too well protected.

However, Pharo has many ways to get references to methods, so we can try another one:

```
Challenge methodDict at:#flag
```

This seems to work well. Now we only need to print its source code.

```
(Challenge methodDict at:#flag) ast nodesDo: [:n | Transcript show: n; cr. ]
```

Which yields:

```
RBTemporaryNode(caller)
RBAssignmentNode(caller := thisContext client)
RBMessageNode(thisContext client)
RBThisContextNode(thisContext)
RBTemporaryNode(caller)
RBMessagifTrue: [ ^ 'IG{ImSoMetaEvenThisAcronym}' ])
RBMessageNode(caller class = Squeak)
RBMessageNode(caller class)
RBTemporaryNode(caller)
RBGlobalNode(Squeak)
RBBlockNode([ ^ 'IG{ImSoMetaEvenThisAcronym}' ])
RBSequenceNode(^ 'IG{ImSoMetaEvenThisAcronym}')
RBReturnNode(^ 'IG{ImSoMetaEvenThisAcronym}')
RBLiteralValueNode('IG{ImSoMetaEvenThisAcronym}')
RBReturnNode(^ 'Only a Squeak can do that (see Squeak>>#fetchFlag)')
RBLiteralValueNode('Only a Squeak can do that (see Squeak>>#fetchFlag)')

```

And there is our flag.

### Recompiling the Squeak class

Another way to solve this challenge is to allow the `Squeak` class to be initialised.

At first, we are not entirely sure why the `Squeak` class fails to initialise.
It could be that its `initialize` method has been overridden.

We can find out which methods have been overriden by retrieving the methods of the `Squeak` class.

```
Squeak methods
```

which only yields `Squeak>>#fetchFlag`. We can conclude that the `InitialisationError` is signaled elsewhere.

Maybe it is at the class side?

```
(Squeak class) methods
```

which yields `(Squeak class)>>#basicNew`. 

Obtaining a reference to this method using `(Squeak class)>>#basicNew` yields:

```
basicNew InitialisationError signal.
```

Hence, we found the culprit. We can disable this behaviour by recompiling that method to something that just 
delegates the `basicNew` message to its parent:

```
(Squeak class) compile: 'basicNew ^ super basicNew'
```

Now, we can try to get an instance of our `Squeak` again.

```
Squeak new.
```

Which, indeed, yields `a Squeak`, mission accomplished.

The last part of this solution consisted of calling the `fetchFlag` method on that instance:

```
Squeak new fetchFlag.
```

Which yields:

```
IG{ImSoMetaEvenThisAcronym}
Challenge
```

Success!
