For several years now, Eset has been sponsoring a conference dedicated to the practical aspects of information security -
CONFidence . And every year we offer a task in the form of a crackme, for a quick solution of which valuable prizes are given. This year, our
Polish office , which officially opened at the beginning of the year, prepared a very original task. After all, the conference was held in their hometown, in Krakow.

If you want to try your hand, then do not read the information rolled up, as there we published a description of the registration code verification algorithm. Download crackme
here .
With the passage of last year's crackme can be found
here , but, in our opinion, this year's task is more interesting. We did not know in advance the principles of its successful passage, and we passed it under identical conditions with the participants of the competition.
')
A virtual machine that performs calculations with the entered data, based on the simplest bit operations, has fallen into the technological basis of computing the correct registration code. This kind of code virtualization is used to build software protection against illegal distribution and copying. For example, the protectors VmProtect and Themida (considered by the people as one of the most complex protections for reverse analysis) also use the technology of converting the original program code into some byte code. This byte code is already executed by the virtual machine's handlers, which is largely redundant in order to complicate the inverse analysis and restoration of the logic of the original algorithm.
Let's return to our virtual machine, which has at its disposal 8 pseudo-registers, let's call them conditionally: rA, rB, rC, rD, rE, rF, rG, rH. Each register has a size of 1 bit. The set of supported commands is as follows:
ret - virtual machine shutdown;
set < register_name
> - set the register value to one state;
jz < register_name > - conditional command transfer control (if the contents of the register is 0, then the control is transferred to the following procedure (procedures are arranged in the memory sequentially));
and <register_name1>, <register_name2> is a logical operation, the result is stored in the first register;
mov <register_name1>, <register_name2> - copy the contents of the second register to the first;
mov <register_name, <address> - copy the contents of the memory (bit) at the specified address into the specified register;
mov <address>, <register_name> - copy the contents of the specified register (bit) to the specified address in memory
The size of the virtual machine instruction has a fixed size and is 2 bytes. The principle of coding instructions can be represented in the form of the following scheme:

This virtual machine performs the conversion of the contents of the memory, in accordance with the control sequence (which just needs to be found), which is also located in the memory:
start of memory + 0x00: control sequence (16 bytes)beginning of memory + 0x10: hash value from the entered name (16 bytes)start of memory + 0x20: encrypted hash value (16 bytes)start of memory + 0x30: the result of the virtual machine function conversion (16 bytes)The processing cycle of the virtual machine commands does not look too hard compared to the analogs of commercial protectors.

For a more convenient analysis of the byte-code of commands executed by the virtual machine, we wrote a processor module for the IDA Pro disassembler, which greatly simplified our further analysis. This is how a set of commands looks like before their conversion by our processor module:

And in the picture below is a variant of processing by the processor module:

We gave the name to the teams, similar to the analogs from the x86 assembler already familiar to us. But further analysis revealed the redundancy of the initial instruction set, since modulo-two addition (exclusive or) operations were expressed in terms of equivalent calculations using other Boolean operations. After that, we decided to implement optimization in our processor module, which greatly reduced after that the volumes of the analyzed code that calculates the registration number.

We decided not to post the source code of the generator of the correct registration numbers so that you still have a research fuse, see for yourself this crackme.
But we still give some correct combinations as an example:
Name: habrahabr
Registration Code: 984116e52ad86d6bd144b11b975a595e
Name: SVH
Registration Code: 271a300e1174f46f944c5c67dc59dd57
Name: CONFidence
Registration Code: 24a2b8dc7c1578de64f8e8e114c2bf00