1. Announcing Mekorama on the Web!

    Now anyone can play levels from the forum online, with one click!

    Dismiss Notice
  2. Psst! If you're new here, welcome! Please visit these pages first for information about the forum and Mekorama:

    Welcome! ¡Bienvenido! Selamat datang! Добро пожаловать! Willkommen!
    and
    Everything you want to know about Mekorama

    Dismiss Notice

Help - Other QR code - Can it be reverse engineered?

Discussion in 'General (Issues, Help, Discussions)' started by QuantumForce, Oct 19, 2016.

  1. Gepeto

    Gepeto MekoStudio Architect Staff Member

    Messages:
    453
    Levels:
    48
    Albums:
    1
    Likes Received:
    2,516
    Joined:
    Jul 7, 2016
    @QuantumForce - Did you really extract the data from Python's zlib.decompress function? I tried and even build my own function to extract QR Code data straight from zbar module (which is used by qrtools) but the result still the same: "unknown compression method". I have compressed and uncompressed custom data, no problem. Something strange...

    Here is the complete hex result from a fresh new card (just a new void card, with no modification). Can you tell me if you've got the same?
    Code:
    01 13 0d fc 78 01 ed c0 41 0a 00 10 10 40 51 5b 1b 67 70 15 7b d9 39 c2 94 a2 51 c2 5c df 3d f4 9f 2f 62 31 cb 95 11 aa 76 9d a6 31 9d dd e6 72 00 00 00 00 00 e0 7b 0f 43 81 08 dd 
    Just in case the zbar implementation isn't good and I have to find another way...

    Note: I pass to the zlib function the string from the 5th Byte, starting with 7801.
     
    Last edited: Oct 26, 2016
    QuantumForce likes this.
  2. Gepeto

    Gepeto MekoStudio Architect Staff Member

    Messages:
    453
    Levels:
    48
    Albums:
    1
    Likes Received:
    2,516
    Joined:
    Jul 7, 2016
    Got it!!! :eek::D
    Stupid types convertions issues with Python 2. :mad: If only zbar was ported to Python 3...
    Now free games begin :cool: (but again, not as official level)

    For those who ever wonder what a blank level looks like:
    [​IMG]
    Well... That's av void one :D
     
  3. Gepeto

    Gepeto MekoStudio Architect Staff Member

    Messages:
    453
    Levels:
    48
    Albums:
    1
    Likes Received:
    2,516
    Joined:
    Jul 7, 2016
    Wow... That's soooo cool. Everything is so clear. The 3D organisation (from bottom to up, line per line), the blocks (01=stone, 05xx = stair #, 0c = grass, 02 = brick,...). If I didn't work tomorrow I could have stayed all night.

    But now it's time to close my eyes... to dream of hex number and enter into the matrix :D
    Cheers
     
    QuantumForce and nGord like this.
  4. QuantumForce

    QuantumForce Active Member

    Messages:
    37
    Levels:
    3
    Albums:
    1
    Likes Received:
    114
    Joined:
    Oct 19, 2016
    Awesome! Is your python2 code working, @Gepeto? It might be nice to switch to python. I had given up on it when I couldn't get zbar to work with python 3.

    My Java code should now read all levels. I also included a description of the level format in the README, if anyone is curious. I also have a complete list of all blocks here in case you haven't decoded all of them yet.
     
    Gepeto likes this.
  5. Gepeto

    Gepeto MekoStudio Architect Staff Member

    Messages:
    453
    Levels:
    48
    Albums:
    1
    Likes Received:
    2,516
    Joined:
    Jul 7, 2016
    @QuantumForce - Yep, my Python2 code works. :) For the moment it is only able to read and extract the QR Code data (the content of the level) from the card image file to a raw file. Eventually zbar works fine, but I achieved that using Linux as it is a mess to install using Windows (but possible, I did that once). Working with Python seems interesting because it would be great to spread the data in a numpy matrix and rotate the data with that (despite I never did that with 3D matrix...). Of course oriented blocks (2 bytes) will need to be rotate too.

    Your list of blocks is wonderfull! It will save a lot of time. I have guessed the 3D organisation of the data level in the hex result (after the title and author), but maybe you did it too. Eventually, it is not as difficult as I thought.

    The next step I want to test is :
    1. Trying to regenerate the QR Code to determine the appropriate parameters (the level param is not the only one, there is a Wbits one for zlib)
    2. Changing a block type and regenerate the QR Code image with the custom signature.
    3. Puting all data in an array of matrix and try to play with rotations functions
    4. Adapting the oriented blocks to the final orientation.
    5. Then... Well, we'll see, but for sure: reorganising my code! :D
     
    Last edited: Oct 28, 2016
  6. sawdust

    sawdust Retired Moderator

    Messages:
    149
    Levels:
    83
    Albums:
    4
    Likes Received:
    785
    Joined:
    Jun 8, 2016
    For the record, I think this is the one of most interesting conversations ever on this forum. I just don't have anything to add as I know nothing about python or java lol.
     
    BitByte, Chuckthulhu and cpw like this.
  7. Gepeto

    Gepeto MekoStudio Architect Staff Member

    Messages:
    453
    Levels:
    48
    Albums:
    1
    Likes Received:
    2,516
    Joined:
    Jul 7, 2016
    Well... For the moment, since I regenerate the zlib data after extraction I can't get the same than the original compressed data. I didn't try to modify anything yet as getting back to a readable QR Code is a key feature (otherwise anything is useless). When I try to pack the zlib data with the custom signature to a PNG QR Code, this is what I get:

    [​IMG]

    :rolleyes: So I still investigate on that part better than the game block part (and @QuantumForce did/is doing a great job on that).

    Indeed it's really interesting to know how all of this is packaged inside. But I don't wanna do too much work without knowing that I can use and test it.
     
    Last edited: Oct 28, 2016
  8. Gepeto

    Gepeto MekoStudio Architect Staff Member

    Messages:
    453
    Levels:
    48
    Albums:
    1
    Likes Received:
    2,516
    Joined:
    Jul 7, 2016
    Phew... I have succeeded to reproduce a valid QR Code for a level despite the fact that the re-encoded data are not done on the same format than the original one. I have even been able to compress more the zlib data! So it is not necessary to encode the level param in the same way than the original one, with the zlib no/low compression (0x78 01) but a more strong one (0x78 9c) works.

    Of course, when the data are decoded and re-interpreted by the software then everything still the same on the rendered card.

    Now I am confident in working with the level data as I know that they will be accepted by the software :D

    So fun...
     
    BitByte, cpw and sawdust like this.
  9. Gepeto

    Gepeto MekoStudio Architect Staff Member

    Messages:
    453
    Levels:
    48
    Albums:
    1
    Likes Received:
    2,516
    Joined:
    Jul 7, 2016
    @QuantumForce - I was curious and checked the desert effect on the grass. The "green" grass is 0x0c and the "desert" grass is 0x12. The value for the grass in your code is the desert one :)

    EDIT: Sorry you did right. You're expressing the value for grass (and other) in decimal, not hex
    GRASS = 0x0c = 12
    DESERT = 0x12 = 18

    Really nice list! Thanks again ;)
     
    Last edited: Oct 28, 2016
    TR O and cpw like this.
  10. sawdust

    sawdust Retired Moderator

    Messages:
    149
    Levels:
    83
    Albums:
    4
    Likes Received:
    785
    Joined:
    Jun 8, 2016
    It's probably a little early for this and it's definitely out in left field, but is it possible that @Martin Magni has block types programmed into the game that either were not in the original levels or the level editor? If so, they could be accessed this way, right? Is it even possible to use brute force to discover such blocks or eliminate the possibility of their existence?
     
    cpw likes this.
  11. cpw

    cpw Retired Moderator

    Messages:
    236
    Levels:
    65
    Albums:
    4
    Likes Received:
    884
    Joined:
    Jun 5, 2016
    @Gepeto Will there be a more direct way to place multiple B bots? Every time I do it by the "zapper overload" method I struggle with placing them at the right spots :rolleyes:
     
    QuantumForce likes this.
  12. Gepeto

    Gepeto MekoStudio Architect Staff Member

    Messages:
    453
    Levels:
    48
    Albums:
    1
    Likes Received:
    2,516
    Joined:
    Jul 7, 2016
    @sawdust for sure this is something that we're gonna check :cool: I don't know yet what will be find and if something will be find. But it will be easy to say that in a short amount of time (depending on my free time). Practically this can be achieved by changing a byte value with another one and check the results in the application.

    @cpw I am not sure that speaking of changing bytes could be called a direct way :D At least it is not the easiest. As we don't have a 3D editor of the objects and plan things have to be done as we can but are possible. I have looked at a 3D svg representation of the blocks in a html5 container but we are far, far away from that :eek:. So everything seems possible now, in the scope of the game and according to the "tools" we have.
     
    Last edited: Oct 28, 2016
    sawdust and cpw like this.
  13. Gepeto

    Gepeto MekoStudio Architect Staff Member

    Messages:
    453
    Levels:
    48
    Albums:
    1
    Likes Received:
    2,516
    Joined:
    Jul 7, 2016
    @cpw
    So... What do you think of this? :D

    [​IMG]

    [​IMG]

    Without any zapper trick!
    It really starts to get interesting. :cool:
     
    BitByte, TR O, B Hill and 2 others like this.
  14. cpw

    cpw Retired Moderator

    Messages:
    236
    Levels:
    65
    Albums:
    4
    Likes Received:
    884
    Joined:
    Jun 5, 2016
    Very nice :D Now I wish I could understand this thread so that I can do more than just reading. :rolleyes:
     
    BitByte and QuantumForce like this.
  15. Gepeto

    Gepeto MekoStudio Architect Staff Member

    Messages:
    453
    Levels:
    48
    Albums:
    1
    Likes Received:
    2,516
    Joined:
    Jul 7, 2016
    @cpw Yes, I admit that's a bit theoretical (or kind of nerds langages)... I need to release some code soon but for the moment I am just playing and don't really care of a code organisation. So that's a dirty brush for now :rolleyes:

    Just imagine that it is possible to open the box of the QR-Code, view all the objects/blocks of the game in the 3D location and give them another identity, in order to produce a new QR-Code. So we can add or modify them freely. I could even change the R-Bots to a grass block, or whatever.

    If @QuantumForce didn't challenge us I am not sure I would have spent my time and dig on this... :)
     
    cpw likes this.
  16. QuantumForce

    QuantumForce Active Member

    Messages:
    37
    Levels:
    3
    Albums:
    1
    Likes Received:
    114
    Joined:
    Oct 19, 2016
    I was also unable to reproduce the exact level data, but found that the game still reads it fine. My writing code is a bit buggy still, but after that I plan to write the rotate script. I haven't figured out any pattern to the rotation bytes, so I think I'll just have to hard-code the swaps. For instance, the half pillars have the following orientations:

    0 3 2 1
    20 23 22 21
    12 16 6 5


    I wouldn't be surprised if there were some secret blocks not included in the editor, but I haven't had a chance to test this yet. The block numbers are not sequential, so it would make sense if the missing numbers encode blocks that were removed. I'd be really excited if there's an L-bot!

    One thing I did look into is how water is encoded. Water has ID 11 and can appear in any block with the same height as the surface of the water. This explains how the desert trick works: you place a water block on level 16 (counting from 0), which works in the editor and causes all the grass blocks to be replaced with desert. But then when you save, level 16 (0x10) gets truncated to level 0.
     
    TR O, Gepeto, cpw and 1 other person like this.
  17. QuantumForce

    QuantumForce Active Member

    Messages:
    37
    Levels:
    3
    Albums:
    1
    Likes Received:
    114
    Joined:
    Oct 19, 2016
    It's interesting that the bot you control changes from the one in the middle to the one in the lower corner. I wonder if the game always uses the one that appears last in the level (e.g. the one furthest to the lower left, then the highest for ties, etc). That would mean that levels using this trick can't be rotated.
     
  18. Gepeto

    Gepeto MekoStudio Architect Staff Member

    Messages:
    453
    Levels:
    48
    Albums:
    1
    Likes Received:
    2,516
    Joined:
    Jul 7, 2016
    Still playing... A bot orientation is N, S, E, W. But what happen when you try to set a bot orientation U (Up) Or D (Down) - which is usually impossible? :D
    [​IMG]
    [​IMG]
    This is how everything can be messed up...

    @QuantumForce - I have watched your Java code and it is beautifully organised. :eek: I think I will take example on your for my Python code. I have opened a github account for my mekorama pseudo (not my personnal :cool: - usually I work with Bitbucket) and will share with you my code as soon as I could be proud of something :rolleyes:
     
    BitByte and TR O like this.
  19. cpw

    cpw Retired Moderator

    Messages:
    236
    Levels:
    65
    Albums:
    4
    Likes Received:
    884
    Joined:
    Jun 5, 2016
    @Gepeto Funny that the eyes detached from B. I always wanted to figure out a way to get the bots to walk like Inception when I see inverted / L-shaped staircases (which would be perfect in @richardfu_ 's Limbo! :D)
     
  20. QuantumForce

    QuantumForce Active Member

    Messages:
    37
    Levels:
    3
    Albums:
    1
    Likes Received:
    114
    Joined:
    Oct 19, 2016
    The motors use 0x0C for up, so you might want to try that instead of 0x05. Were you modifying only the orientation bits of the outside ring? It's weird that the middle B is still facing south.

    I've annotated a card with all the blocks and block data. I'm using decimal for the block type but hex for the orientations, since that reveals some patterns (sorry if that's confusing).

    all_blocks.png
     
    fire_rabbit, BangTe, TR O and 3 others like this.

Share This Page