

The method above will give you access to the decrypted data at the first try. subtract 7 * (size-1) = 70 = 0x46.Ġx8F - 0x46 = 0x49 which (surprise!) is the seed used for this example. Now, to obtain the seed it is sufficient to subtract 7 for every byte all the way up to the beginning of the data. Therefore the internal state at that point is 0xBD - 0x2E = 0x8F.
#Opcode 0xed in binary code
Given this information, we can say that the last byte 0xBD must convert to 0x2E, which is the ascii code for '.' Let's consider now that we have the previous knowledge that every data record ends with a '.' which is actually pretty similar to the approach used by A. Also, it is interesting to note that two different characters can translate to the same byte, as it happened in this example. This reminded me a little bit of the inner workings of the WW-II Enigma Machine. The data would become:Īs you can see, this cipher converts two equal characters into different bytes, due to the internal state being updated at every step. Now let's apply the encryption algorithm by choosing 0x49 as the seed. Let's imagine that the original data is the string "Helloworld." which in would correspond to the following hex stringĠx48 0圆5 0圆C 0圆C 0圆F 0x77 0圆F 0x72 0圆C 0圆4 0x2E However this is not even necessary, since a bruteforce attack is very feasible! Let me explain. Knowing the initial 8-bit seed is enough to decipher all the data. Obviously, the function to decrypt the data is exactly the same as this one, but instead of adding the state, it is removed from each data byte.Ĭlearly, this is a ridiculously weak way of protecting data. The addition is done byte by byte and the state is incremented by 7 at every iteration. The encryption is done simply by adding the lower 8 bits of the internal state to every byte of the input data, letting the number overflow. This function has an internal state which is initialized with the seed parameter. jnz short loc_6EF24820 The Z bit is set by the sub instruction Void encrypt(char *buf, size_t size, int seed)

* Encrypt the data stored in buf, byte by byte Which translates more or less to the following decompiled C code: /** IDA's proximity view of the disassemby of the encryption function

The picture below is a screenshot of IDA which shows the disassemby of the encryption subroutine. I'll now explain how the encryption works starting from the disassembly code and then I'll demonstrate how easy it is to simply do a bruteforce attack and decrypt the data.

Then, I started thinking about those companies that rely on securing the data using the built-in encryption mechanism found here. The naive encryption method that the engineers who designed the file format put in place made me smile, at first. In addition to simple index data storage, the file format allows for data encryption, on a record base. This must have been decided in order to allow indexed random access to the data records. After a few days of headaches and guesses, I managed to collect enough information to correctly dump the data out of the file, which is organized in a data structure very similar to a B-Tree. Unfortunately, the format of those files is proprietary and almost no useful information is available online: I was basically alone in the reverse engineering of the file format.įirst I disassembled, decompiled and analyzed the official DLL that is used to create and access the binary files. Reverse engineering a proprietary (and very weak) encryption mechanismĪs part of a personal project I am working on, I had the need to access data stored in some binary files.
#Opcode 0xed in binary software
Sometimes I like to dig deeply into some x86 Windows executables files so that I can better understand how certain pieces of software work.
