Redshirt2 algorithm

Some code to encrypt/decrypt

After reading this topic in the Introversion forums, I whipped up some Ruby code to do the Redshirt2 encryption/decryption. For those who don't know, Redshirt2 is the fairly simple algorithm used to obscure the user profile files - if you decrypt your user profile files with this, you can modify them and then re-ecrypt them to do pretty much whatever you want, such as enabling later levels and whatnot.

Hrm, perhaps I should play the game again but this time giving myself max research levels... 🆒

Anyway, the code is as follows:

#!/usr/bin/env ruby

module Redshirt
	TABLE = ( 0x1f, 0x07, 0x09, 0x01, 0x0b, 0x02, 0x05, 0x05,
     0x03, 0x11, 0x28, 0x0c, 0x23, 0x16, 0x1b, 0x02 )

	def self.deshirt(input, output)
  i = 0
  input.each_byte do |byte|
  	if byte > 0x20
    i += 1
    i %= 16
    byte -= TABLE(i)

    if byte < 0x20
    	byte += 0x5f
    end
  	end
  	output.putc byte
  end
	end

	def self.deshirtfile(filename)
  if filename != nil and filename.length > 0 and filename != "-"
  	begin
    File.open(filename, 'r') do |file|
    	if file.read("redshirt2".length) != "redshirt2"
      STDERR.puts "Error: not a redshirt2 file"
      exit 1
    	else
      deshirt(file, STDOUT)
    	end
    end
  	rescue Errno::ENOENT
    STDERR.puts "Error: Unable to open file `#{filename}'"
    exit 1
  	end
  else
  	if STDIN.read("redshirt2".length) != "redshirt2"
    STDIN.seek(0 - "redshirt2".length, IO::SEEK_CUR)
  	end
  	deshirt(STDIN, STDOUT)
  end
	end

	def self.enshirt(input, output)
  i = 0
  output.print "redshirt2"
  input.each_byte do |byte|
  	if byte > 0x20
    i += 1
    i %= 16
    byte += TABLE(i)

    if byte < 0x20
    	byte -= 0x5f
    end
  	end
  	output.putc byte
  end
	end

	def self.enshirtfile(filename)
  if filename != nil and filename.length > 0 and filename != "-"
  	begin
    File.open(filename, 'r') do |file|
    	enshirt(file, STDOUT)
    end
  	rescue Errno::ENOENT
    STDERR.puts "Error: Unable to open file `#{filename}'"
    exit 1
  	end
  else
  	enshirt(STDIN, STDOUT)
  end
	end
end

if ARGV(0) == '-e'
	Redshirt.enshirtfile(ARGV(1))
elsif ARGV(0) == '-d'
	Redshirt.deshirtfile(ARGV(1))
else
	print <<END
Usage: #{File.basename $0} (-e|-d) (filename)

	-e  Encrypts the given file
	-d  Decrypts the given file

This script encrypts or decrypts a file with the redshirt2 algorithm.
The resulting text is printed on stdout.
If you pass no filename or a -, it reads from stdin instead of the file.
END
end

Simply paste that into a new file (I called mine "redshirt2.rb"), mark it executable, and run it. Or don't mark it executable and run it through the ruby interpreter yourself (i.e. `ruby redshirt2.rb -d game.txt). Run the script with no arguments to get a short help text.

I hope this is useful to someone.

-Eridius

This post has been edited by Aranor : 07 April 2005 - 01:12 PM

If I try to run this by itself it says "bad interpreter: permission denied" and if I go "ruby" first it complains about a whole pile of invalid chars `\312'. Did I not copy the text right or what?

Guy, on Apr 11 2005, 12:06 PM, said:

If I try to run this by itself it says "bad interpreter: permission denied" ...

You must make it executable to run it by itself. From the command line, try something like this:
$ chmod u+x redshirt2.rb

This will make the file executable by the user who owns it.

xander

The invalid characters are from copying the script from a website. Make sure you get rid of any space at the beginning and end of each line to get rid of the '\312' characters. You can also try replacing all occurrences of a '\312' character with nothing using your text editor's find and replace feature.

Rigdern, on Apr 11 2005, 08:23 PM, said:

The invalid characters are from copying the script from a website. Make sure you get rid of any space at the beginning and end of each line to get rid of the '\312' characters. You can also try replacing all occurrences of a '\312' character with nothing using your text editor's find and replace feature.
View Post

Got rid of indents. That fixed it, thanks. 🙂
Also realised I had mistakenly only made it exuctable for others. :rolleyes:

To answer a potential question in advance:

If you decrypt a file and re-encrypt it, the output you get is different from the original file. This is not a problem. Why? The decryption process is a one-way transform. The encryption process can therefore not reconstruct the exact original encrypted text, but instead produces an equivalent text. If you decrypt the newly-generated encrypted text you will see that it is identical to decrypting the original text.

Ruby code? Mark it executable?

To a coding idiot this makes no sense. What program do I enter that into?

CJM2:

  1. In the Finder, open /Applications/Utilities
  2. Find 'Terminal', and double-click on it. This will open a terminal window.
  3. At the prompt (where the blinking cursor is), type 'cd (directory)', where directory is the location of 'redshirt2.rb', and hit enter*
  4. At the prompt, type 'chmod u+x redshirt2.rb'**
  • i.e. If your login is 'xander' and you have saved redshirt2.rb in your Documents directory, you would type 'cd /Users/xander/Documents'
    ** chmod changes user privlages. u+x gives you the ability to execute the file. If you type 'ls -l' at the prompt, it will give you a listing of the files in the directory, with lots of usefull information. In the first column, it will tell you about user premissions, like this: -rwxr--r-- The first dash flags something as a directory (if it is a directory, it will be a 'd' rather than a dash). The next nine characters show premissions. The first group of three is the user's premissions. An 'r' means that the owner of the file can read the file; a 'w' means that the owner can write to the file; an 'x' means that the owner can execute the file. The next two groups of three characters are formatted in the same way, but give premissions for other users in the group, and for all other users (don't worry about this if it doesn't make sense). If you want to execute the file, the fourth character in this string should be an 'x', which can be changed by using the command chmod as described above.

xander

Seen as it's quite fiddly (with all the funny symbols you end up with) to get code out of this forum's code style thingy I've added it here as an attachment so it can just be downloaded.

Rename it to 'redshirt2.rb' then do what Darwinian says.

Attached File(s)

Almost succeeded. I have managed to decode the game.txt file with the ruby interpreter but I don't know how to edit it and I have also managed to mark it as executable but I don't know how to run it. I tried the 'open' command but it didn't like the file.

CJM2, on Apr 21 2005, 05:10 PM, said:

Almost succeeded. I have managed to decode the game.txt file with the ruby interpreter but I don't know how to edit it and I have also managed to mark it as executable but I don't know how to run it. I tried the 'open' command but it didn't like the file.
View Post

Marking the 'game.txt' file as executable will not do anything for you. You need to mark the decoder as executable. However, as you have decoded 'game.txt', you must have figured that out. If you have decoded it, you should have a text document. Open it up in SimpleText, or BBEdit, or something.

Just to make sure that we are all clear on what we are talking about:

  1. In the Finder, copy 'game.txt' to the same directory as 'redshirt2.rb'*
  2. Open up a terminal window, as outlined above
  3. Change to the directory that contains your copy of 'game.txt' (i.e. 'cd (directory))
  4. At the prompt, type './redshirt2.rb -d game.txt > game_decode.txt'**
  5. Open 'game_decode.txt' with a text editor.***
  6. Make the changes that you want to make.
  7. Replace the original 'game.txt' with 'game_decode.txt' and rename 'game_decode.txt' to 'game.txt'
  • Strictly speaking, this is not necessary, but it will make things easier for those that are not familier with the command line. Either way, it is wise to work with a copy of 'game.txt'.

** What this does:
./redshirt2.rb is the script. If you have marked it as executable, just calling it should cause it to run. The ./ in front of it tells the shell that you want to run a program that is in the current directory rather than in one of the standard places (i.e. /bin, /usr/bin, &c.).
-d tells the script that you wish to decode a file.
game.txt is the encoded file that you wish to decode.

directs the output of the script to a file. The way that the script is written, it directs its output to standard out... this means that it will just appear on the terminal. If you use the greater than sign, it will write to a file.
game_decode.txt is the file that you will be writing to. If the file does not exist, it will create it. If it does exist, it will overwrite it.

*** i.e. SimpleText, MSWord, AppleWorks, BBEdit, vi, emacs, pico, &c. -- WARNING: if you use something like SimpleText, MSWord, AppleWorks, or any other word processor, make sure that you save the file as plain text after you make changes.

xander