Anti-external-editor locks

NOTE: I HATE A LOT OF YOUR ZZT GAMES, SO WATCH OUT!

Moderators: Commodore, Zenith Nadir

Post Reply
User avatar
Quantum P.
Level 17 Accordion Thief
Posts: 1433
Joined: Fri Sep 12, 2003 1:41 am
Location: Edmonds, WA
Contact:

Anti-external-editor locks

Post by Quantum P. »

First of all, a disclaimer: I strongly advise against locking ZZT games. Although locking a game makes it difficult to cheat by editing, it also makes it difficult to fix bugs. In addition, it's harder for new programmers to study your code and learn from it. The following technique could be used to strengthen a lock, but I'm posting it only because I thought it might interest my fellow ZZT experimenters. Please don't implement it in a real game.

Now that that's over with, here's a little ZZT world that dares you to deface it. The problem is, the file is locked - you can't edit it by conventional means. Most existing locks can be easily bypassed with an external editor. However, the method used to lock this file has an addition that (to my knowledge) has never been used before. This addition prevents the file from opening in both ZZTAE and KevEdit.

How it works (for those who feel so inclined as to figure it out themselves, the following contains spoilers):

ZZT stores terrain data using run-length encoding. This basically means that instead of describing all 1500 tiles on each board, ZZT will describe a tile once and specify how many times it occurs. For example, a line of 10 gems in a row could be described as [10][Tile ID for a Gem][Gem color]. The number of copies is stored in a single byte, which is treated as an 8-bit unsigned integer. This basically means that the number can go from 0 to 255. 1 through 255 make sense, but what does it mean when you state that zero of a tile should appear on the board?

It depends on who you ask. According to ZZTAE and KevEdit, it means the tile does not exist. They just skip that run-length-encoded triplet and move on to the next. However, it means a very different thing to ZZT - both ZZT and ZZT's default editor will interpret the 0 as meaning 256. Because of this difference of interpretation, it is possible to make a board that appears corrupt to an external editor but plays just fine in ZZT.

Why hasn't this been noticed before? Because ZZT will never encode a run of 256 tiles using a zero. If it encounters a run of tiles more than 255 long, it will encode the run as multiple separate, shorter runs. Ditto for all external editors. Run lengths of zero never occur naturally - you have to use a hex editor to get them - and so external editors are never tested for this condition. I'm guessing that ZZT's interpretation of 0 means 256 is more of an exploitable bug than a feature, as it's inconsistent with even its own board encoding algorithm.

Of course, it is important to realize that run lengths of zero do not prevent editing by external editors in general. The only reason they have this effect is because both ZZTAE and KevEdit parse ZZT files in the same way, a way that's slightly different from how ZZT does it. If either CyQ or Kev Vance had reordered the statements in his decoder loop, his editor would be immune to the technique described in this post. In fact, KevEdit is open source, and it would be trivial to build a modified version of KevEdit that could get past the locked file I have posted here. This is why locking is pointless - if you're clever enough to devise a stronger lock, there's always going to be somebody clever enough to crack it.

Now, if you have fun doing this kind of thing, here's a challenge: edit the file I uploaded using only ZZT and ZZTAE - no hex editors and no custom-built programs. It is possible, and it just goes to show that even this lock is far from perfect.
gingermuffins
Posts: 371
Joined: Fri Sep 01, 2006 1:30 am

Post by gingermuffins »

export board #3, import to zztae? blanking the corrupted board?

You can freeze KevEdit's board selector by starting a board name with a semicolon -- I don't know why that is.

You can't open A Heaven of Hell in Kevedit without blanking the title board (and maybe a couple others) with the normal editor. Maybe that board can be imported into other games and used as a lock? Like say use it as the last part of the game edited, and make it a board that's essential to gameplay?
User avatar
Quantum P.
Level 17 Accordion Thief
Posts: 1433
Joined: Fri Sep 12, 2003 1:41 am
Location: Edmonds, WA
Contact:

Post by Quantum P. »

I was thinking of starting and immediately saving the game in ZZT (this regenerates the terrain data for that board). Rename the .sav file to .zzt, open in ZZTAE, and disable lock. Go back to ZZT and edit with impunity.

I forgot about the semicolon one with KevEdit. I'm guessing that has something to do with the code that determines the appearance for a line ($text is white and centered, !label;text is highlighted with an arrow). But that's just a guess - I'd have to look through the source code to find out.

Also, I looked through A Heaven of Hell in a hex editor, and it looks like the first couple of boards have a title length of 255 (I believe the max length is something like 34). Don't know how that happened.
User avatar
Saxxon
the Gargoyle.
Posts: 608
Joined: Tue Jul 25, 2006 10:02 am
Contact:

Post by Saxxon »

This happens because ZZT automatically assumes there will be at LEAST one tile. Here's how it decodes:

* loop starts
* decrease counter by 1 (if this is zero already, it rolls over to 255)
* place tile
* loop repeats until counter is zero

I realize this thread is old, but it's a very interesting concept. However, locking worlds is pretty lame nowadays anyway. ZZT always struck me as an open-source type of thing. Anyone with a hex editor could put their name in there anyway.

Support for loading this has been added to ZAP. More for purposes of keeping accuracy than defeating a lock. AHOH's trick wouldn't work if ZZT didn't store the title in a fixed-length string. Well, logically it isn't, but technically it is. That one didn't need a fix.
User avatar
Quantum P.
Level 17 Accordion Thief
Posts: 1433
Joined: Fri Sep 12, 2003 1:41 am
Location: Edmonds, WA
Contact:

Post by Quantum P. »

Yeah, locking is lame. I only posted this because I wanted to document the bug - because in ZZT, where the implementation is frozen, all bugs are features.
User avatar
Dr. Dos
OH YES! USE VINE WHIP! <3
Posts: 1772
Joined: Tue Mar 11, 2003 12:00 am
Location: Washington

Post by Dr. Dos »

It crashes ZAP too.

You've bested us all.
Visit the Museum of ZZT
Follow Worlds of ZZT on Twitter

Apologies for the old post you may have just read.
User avatar
Saxxon
the Gargoyle.
Posts: 608
Joined: Tue Jul 25, 2006 10:02 am
Contact:

Post by Saxxon »

Indeed, great find.
User avatar
Surlent
Oh man not him again
Posts: 129
Joined: Fri Jan 12, 2007 5:16 pm
Location: Western US

Post by Surlent »

Quantum P. wrote:Yeah, locking is lame. I only posted this because I wanted to document the bug - because in ZZT, where the implementation is frozen, all bugs are features.
Spoken like a true programmer.
JESUS CHRIST- You start the New Testament
with this Jesus. He is so superpowered and awesome, you feel converted. You place your hope in this Jesus.
Post Reply