Rating:

# LessEQualmore

For the reversing part of this challenge, the intended solution is to lift the subleq code into elvm ir (or any other ir you desire), extract the matrixs, find the inverse, and decode the value from the matrix inverse.

I'll based this writeup on the fact that you know elvm, though some other recon step can lead you to the same conclusion (albeit in much longer time).

### Disassembling

However, Disassembling the bytecode itself is already quite difficult. Due to the way that the backend generates the subleq code, some constants used in the program are mixed with the instructions, so it's not a simple decode every three bytes sequence, but you need to follow some unconditional jumps to get there. A simple heuristic is that you can notice that if an instruction starts with 0 0 x, it's most likely jumping to x directly if x is somewhere after the current ip. Applying this, you can get a rough subleq instruction grouping.

### Lifting the instructions

With the subleq instructions, pattern matching is possible using either python 3.10's new matching syntax, or other languages with matching capabilities like rust. You can implement each cases shown in the backend code to get back the elvm ir.

At this point it might be clear that some memory locations are often referenced, so they are likely used as a constant or as a register. This can be verified with the elvm backend source and elvm structure.

However, we are not done yet, if you look at the ir, there are still a lot of repeating structures. As some people mentioned the push and pop macro are extremely long, as those are macro on the ir level. At this point, you should get something like [chal.eir](https://github.com/bronson113/My_CTF_Challenges/blob/main/HITCON%20CTF%202023/LessEQualmore/chal.eir).

### Matrix multiplication

The last part is to identify that the program is doing matrix multiplication on the input, but the matrix is dispersed across the instructions. thankfully each value in the matrix is at most plus or minus 3, so having 6 different match cases should be doable. Notice that the location where the matrix is zero is just obmitted, so some processing is also needed to fill in that blank.

Anyway, after those steps, two matrixes can be extracted, and multiplying the reference vector with the inverse matrix give us the flag.

Original writeup (https://bronson113.github.io/2023/09/10/hitcon-ctf-2023-lessequalmore-subformore.html).