Homebrew Pyramids QR Code Hacking

  • Thread starter Thread starter elisherer
  • Start date Start date
  • Views Views 23,150
  • Replies Replies 92
  • Likes Likes 1
Wait, the QR codes contain icons?

Anyway, I don't have this game, but I'm looking forward to see a level editor for it :)
 
i got this game, played around with the main game a little...i do not like it at all :(. BUT i do hope you are able to make a level editor :D!
 
Wait, the QR codes contain icons?

Anyway, I don't have this game, but I'm looking forward to see a level editor for it :)

No, the qr codes contains (supposedly) icons identfiers (much like the pushmo's object struct, maybe even the same)
The icons are not really icons but real 3d objects.

You can see that all the "QR Cards" published by 'Enjoy Gaming' don't align the same (qr not in the same place exactly) and some have the money rotated
or the snakes or skulls not aligned to the level's grid. So it suggests that the "QR cards" are nothing more than screen shots with QR codes glued to them by MSPaint.
So it leads me to think that the developer didn't create a level's QR exporter but rather makes it manually each time...weird...

How you can help??
If you have any reverse engineering skills or have a gift of understanding stuff just by looking at hex digits :) then look at the files linked at the first post and try to figure
out what the h*** 'Enjoy Gaming' was thinking when making those QR codes...

Thanks again...
 
Each object appears to use 1 byte or less, If you look at "p7-1c.jpg"

2eA9K.png


This Level Contains:

40 Blocks
14 Snakes
06 Coins
01 Amulet
14 Bullets
01 Door
01 RockDoor
-- -------
77 Objects In Level

p7-1c.bin filesize = 81 bytes minus the 4 byte header (10AA0000) = 77 bytes data.

So the data must be stored as multiple arrays, maybe something like:
Array 1: ,,,,,,
Array 2: ,,,,,,


Where:
BlockType = The type of block (E.g Bullet, Snake, Coin etc)
NumberofBlocks = How many blocks are in the array (e.g how many times PositionX+PositionY are repeated?)
PositionX = X Position of the block on the board (e.g 5)
PositionY = Y Position of the block on the board (e.g 3)

The Player Start Position might not be stored in an array.

I don't see it possible to store each object on the board in 1 byte / 8 bits without using
an array considering there are 40 blocks total and a board height of 10 and width of 16.
(maybe there is some sort of compression used?)

Just thought I'd post my thoughts :)


----

edit: p1-2.bin is 103 bytes long, but there is only 68 total blocks used in the level with 14 Unique Blocks.
 
That's a good theory...and compression could be too...we need to do what you did there on more levels and then maybe we could have a clue...

EDIT: another thought...maybe the big blocks are not divided to 4, maybe they are 'big' icons which given a (x,y) the same as others...so instead of 12 icons it's only 3
leaving us with 31 icons total which is 5 bits (makes sense), but the 3 bits left is not enough for x,y so we need to further investigate...
 
  • Like
Reactions: marc00077
I'll be happy to help, Eli, when my 3DS returns from repair :)

I planned on investigating these QR codes after we finished with Pushmo anyway, but a necessary repair prevented that from happening.
 
Some thoughts from me:

Do not forget that some objects might require more information than just type and position
(in which direction do the skulls/spikes start to fly/roll? This might be solved by using
diffrent "types" for different directions)

The eighth to last byte seems to be the "par" time for the level. (Just flew over the levels
but I think it works except for p2-6 and p2-7). The next byte is in many cases 0x00.

If you want to check whether there is some kind of checksum involved (I am pretty sure it is;
could be at the end of the data) try changing the "time" byte...
 
Some thoughts from me:

Do not forget that some objects might require more information than just type and position
(in which direction do the skulls/spikes start to fly/roll? This might be solved by using
diffrent "types" for different directions)

The eighth to last byte seems to be the "par" time for the level. (Just flew over the levels
but I think it works except for p2-6 and p2-7). The next byte is in many cases 0x00.

If you want to check whether there is some kind of checksum involved (I am pretty sure it is;
could be at the end of the data) try changing the "time" byte...
That's awesome....just checked the files myself and it seems ok...

I notices something else...the byte after that is usually 0x00 and sometimes 0x80...maybe a flag of some kind...
after those 2 bytes it's gotta be the checksum...every bin file has a different one...
 
Some thoughts from me:

Do not forget that some objects might require more information than just type and position
(in which direction do the skulls/spikes start to fly/roll? This might be solved by using
diffrent "types" for different directions)

The eighth to last byte seems to be the "par" time for the level. (Just flew over the levels
but I think it works except for p2-6 and p2-7). The next byte is in many cases 0x00.

If you want to check whether there is some kind of checksum involved (I am pretty sure it is;
could be at the end of the data) try changing the "time" byte...
That's awesome....just checked the files myself and it seems ok...

I notices something else...the byte after that is usually 0x00 and sometimes 0x80...maybe a flag of some kind...
after those 2 bytes it's gotta be the checksum...every bin file has a different one...
do you mind posting a few examples of the flag and then the checksum? it might help us know how much bits each checksum has, suggesting what kind of checksum it uses, for example if it would've been an MD5 checksum, it would've been 16 byte checksum, if this is true, a MD5 flag should be represented before the MD5 hex code to let the camera lock on the code and confirm it's position bit-wise, explaining well why the flag before the md5 checksum code is an hex 0x80 (dec for 128, which is 16 byte) it might be something different all together, the only thing that will help me to guess what it is is by you either giving me the hex code or by you giving me the address that reads that and let me pick it out myself, if I happen to have an idea I'd share that

after we do know what kind of checksum it uses, we can have easier time decrypting the image to it's full raw-data format
 
do you mind posting a few examples of the flag and then the checksum? it might help us know how much bits each checksum has, suggesting what kind of checksum it uses, for example if it would've been an MD5 checksum, it would've been 16 byte checksum, if this is true, a MD5 flag should be represented before the MD5 hex code to let the camera lock on the code and confirm it's position bit-wise, explaining well why the flag before the md5 checksum code is an hex 0x80 (dec for 128, which is 16 byte) it might be something different all together, the only thing that will help me to guess what it is is by you either giving me the hex code or by you giving me the address that reads that and let me pick it out myself, if I happen to have an idea I'd share that

after we do know what kind of checksum it uses, we can have easier time decrypting the image to it's full raw-data format
You are right. Though I don't believe it's MD5 (too long) but rather something simple like CRC16/32 or just a checksum ...
Just go to the link on the 1st post...all bin files are there with the data for each level (same name as the image's name)..
 
Not saying you are wrong ....how certain are you with your QR decoding? I ran http://www.sherer.co...ramids/p1-2.jpg (cropped to just the QR) through http://zxing.org/w/decode.jspx

Here is the HEX ... different than your .bin

It lines up ...short of a different header/footer

10 ef bf bd 00 00 02 01 00 18 00 21 21 00 04 18
5c 00 50 04 00 30 01 00 15 10 05 00 05 77 05 00
11 10 03 10 06 05 20 02 10 0e 30 02 ef bf bd 00
19 09 50 30 50 10 40 1e 30 32 05 13 ef bf bd 30
25 60 20 10 3a 70 06 00 59 12 05 2b 48 2c 20 62
27 28 10 5d 06 05 05 20 2d 2e 10 67 06 29 2a 06
05 08 06 06 05 1d 00 ef bf bd ef bf bd ef bf bd
1e 00 11 0a
 
I don't know why it came out different but i'm using zxing as well...i guess the online version outputs the qr header/footer as well...

Edit: I checked the output you got.. it's because the online version tries to find text and the bytes which are high value are decoded to "ef bf bd" (you can see it in your output,
every "ef bf bd" is originaly some other byte in my bin file)
so it's essentialy the same output...

P.S. I forgot I changed zxing.dll to not throw an exception when it finds UTF-8 code page in the qr code.
 
I don't know why it came out different but i'm using zxing as well...i guess the online version outputs the qr header/footer as well...

Edit: I checked the output you got.. it's because the online version tries to find text and the bytes which are high value are decoded to "ef bf bd" (you can see it in your output,
every "ef bf bd" is originaly some other byte in my bin file)
so it's essentialy the same output...

P.S. I forgot I changed zxing.dll to not throw an exception when it finds UTF-8 code page in the qr code.

Yes. The online decoder is not reliable when it comes to exact byte representations of the QR-code.

P.S. The fact that the developer has said they have no plans to release a level editor of any sort makes this project much more attractive to me. I wish my 3DS would arrive back from Nintendo!
 
I don't know why it came out different but i'm using zxing as well...i guess the online version outputs the qr header/footer as well...

Edit: I checked the output you got.. it's because the online version tries to find text and the bytes which are high value are decoded to "ef bf bd" (you can see it in your output,
every "ef bf bd" is originaly some other byte in my bin file)
so it's essentialy the same output...

P.S. I forgot I changed zxing.dll to not throw an exception when it finds UTF-8 code page in the qr code.

Yes. The online decoder is not reliable when it comes to exact byte representations of the QR-code.

P.S. The fact that the developer has said they have no plans to release a level editor of any sort makes this project much more attractive to me. I wish my 3DS would arrive back from Nintendo!


ok good to know about the online version.

If you read those emails , there seems to be a "private" level editor.....but it can not export to QRcode. Seems the guys at Visual Impact Productions are the only ones that can.
 
after observing some of the data with an hex editor I can confirm that with at least detonator.png, spike.png and money.png that it uses RGB due to the nature of some selected hex addresses that I know would be for example, without any RED or GREEN, which on the unencrypted format would make the value be like
Without red : 00XXXX
full red : FFXXXX
I noticed that with the different pngs I saw, each of `em would have a different type encoded "00" or "FF" for lets say RED but there is an address that is always matching that value, meaning the decoder built in the 3DS might just search for those addresses to know which is full and empty value and simply fill in the values to make a full 255 gap between `em to be decoded and finally readden as an RGB pixel...
however with each time of reading the QR image that address changes, exactly as such it would be influeced by a pointer address/value, which leads me to the suggestion : either I made a whole big mess and did it all wrong else the decoder for QR pyramids can be three softwares running one after the other
* first one would read the code and "compile" it
* second one that would decode it
* third one that would see what "format" the software is and open it with a fitting software, let's say Mii? Web browser, picture? picture viewer, and such and such

I am more convinced I did something wrong that smacked the whole results and hex viewing I did
 
after observing some of the data with an hex editor I can confirm that with at least detonator.png, spike.png and money.png that it uses RGB due to the nature of some selected hex addresses that I know would be for example, without any RED or GREEN, which on the unencrypted format would make the value be like
Without red : 00XXXX
full red : FFXXXX
I noticed that with the different pngs I saw, each of `em would have a different type encoded "00" or "FF" for lets say RED but there is an address that is always matching that value, meaning the decoder built in the 3DS might just search for those addresses to know which is full and empty value and simply fill in the values to make a full 255 gap between `em to be decoded and finally readden as an RGB pixel...
however with each time of reading the QR image that address changes, exactly as such it would be influeced by a pointer address/value, which leads me to the suggestion : either I made a whole big mess and did it all wrong else the decoder for QR pyramids can be three softwares running one after the other
* first one would read the code and "compile" it
* second one that would decode it
* third one that would see what "format" the software is and open it with a fitting software, let's say Mii? Web browser, picture? picture viewer, and such and such

I am more convinced I did something wrong that smacked the whole results and hex viewing I did

well the png files are just ripped from the image files that have the QRcode pasted to them. They are not present in the QRcode itself.
 

Site & Scene News

Popular threads in this forum