ej
from wolvctf in English
ej
Firstly, the program outputsputs("solve my puzzle for a flag ;) (use u, d, l, r) \nwait i forgot to implement the display functionality :/");
.I suppose u
means up
, d
is down, l
is left and r
is right. (If you didn’t find it, that doesn’t matter)
It’s clearly that the program only checks our input after strlen
, in the if
statement.
1 | if ( maze((__int64)input, s_len) ) |
so all we need to do is to solve maze
. Let’s begin !!
maze
At the beginning of puzzle
, the function iterates our input line.v2
stands for the bytes we input. From the variable v4 and v5 we can know that the puzzle is a 64*4+8
byte puzzle, which is 6*6*4. That means it’s a 6*6
puzzle.
And the logic is like this. Suppose we have a pointer
starting at position 0
.(Like a person trapped in the puzzle, the variable name is v7
)
1. if `v2` is `u`
It first check if we are at the first line
(v7<=5), and then writes 3
to the position, and decreases pointer v7
by 6(going up a line)
2. if `v2` is `r`
It first check if we are at the right bound
((v7 + 1) % 6==0), and then writes 6
to the position, and adds pointer v7
by 1(going right)
3. if `v2` is `l` </br>
It first check if we are at the left bound
((v7 - 1) % 6 == 5), and then writes 4
to the position, and minus pointer v7
by 1(going left)
4. if `v2` is `d`</br>
It first check if we are at the last line
(v7 > 29), and then writes 5
to the position, and adds pointer v7
by 6(going down a line)
this procedure, literally, remembers
all the choices
of the direction changing of the pointer inside the maze at every block. At the last of maze
function, there are three confinements we should meet.
1 | return !v7 && (unsigned int)circle((__int64)v4) && (unsigned int)trinagle((__int64)v4); |
the first !v7
means we should go back to the starting point. And the next 2 functions are some checkings for the former choices
you have made.I named them after circle
and trinagle
circle
To be explict, the circle function checks ** whether the pointer at some certain position forms the same direction from the former block**. And there is a rule
block, which looks like this.
1 | 0 1 2 3 4 5 |
Let me explain my former words. for ciecle
, it means that when we run into the 1
in (2,1)
(the one with star) from the left
, for example, we did from (1,1) to (2,1), we should only turn left in (2,1), so we have no choice but go to (3,1)
. All the points with 1
acts the same thing.
(The reason is that in circle
, it reverses the direction when meets ‘1’, left to right, down to up, and checks whether the number stored are the same. and to sum up. it did the direction checking)
trinagle
To be explict, the trinagle
function checks whether the next block of some certain position acts the same thing like I do for example:
1 | 0 1 2 3 4 5 |
when we reach(0,5), if we want to turn right to (1,5), this rule checks that when in (1,5), we should turn right again, that means we have to go like this (0,5)--->(1,5)--->(2,5)
What’s more, It alse checks that when we reach blocks with 2
, we should go from two blocks with the same direction.For example, if we want to go to (4,4)
, we can only have the following choices: (2,4)—>(3,4)—>(4,4) and (4,2)—>(4,3)—>(4,4).The code is shown below
1 | if ( v2 == 3 || v2 == 5 ) |
And that’s it ! the maze
game.
solution
While my solution is shown below. the program gives the output correct
but didn’t give the flag :) It may because there are various solutions for that
1 | 0 1 2 3 4 5 |
the string input is dddddrrrrruuulddlllurrullurrrrulllll
The output is
1 | ➜ ej ./ej |
But anyway, the task is fun !!! :p