Valve VFONT to ttf/otf and back to VFONT

Programming related discussions related to game research
h3x3r
Posts: 165
Joined: Wed Jun 01, 2016 5:53 pm

Valve VFONT to ttf/otf and back to VFONT

Post by h3x3r »

Hi there. Can someone please figure out decompile and re-compile VFONT from ttf/otf.
There is decompiler source but i am a bit confused from it.

Code: Select all

using System;
using System.IO;
using System.Text;

namespace ValveResourceFormat
{
    public class ValveFont
    {
        private const string MAGIC = "VFONT1";
        private const byte MAGICTRICK = 167;

        /// <summary>
        /// Opens and reads the given filename.
        /// The file is held open until the object is disposed.
        /// </summary>
        /// <param name="filename">The file to open and read.</param>
        public byte[] Read(string filename)
        {
            using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                return Read(fs);
            }
        }

        /// <summary>
        /// Reads the given <see cref="Stream"/>.
        /// </summary>
        /// <param name="input">The input <see cref="Stream"/> to read from.</param>
        public byte[] Read(Stream input)
        {
            using (var reader = new BinaryReader(input))
            {
                // Magic is at the end
                reader.BaseStream.Seek(-MAGIC.Length, SeekOrigin.End);

                if (Encoding.ASCII.GetString(reader.ReadBytes(MAGIC.Length)) != MAGIC)
                {
                    throw new InvalidDataException("Given file is not a vfont, version 1.");
                }

                return Decode(reader);
            }
        }

        private byte[] Decode(BinaryReader reader)
        {
            reader.BaseStream.Seek(-1 - MAGIC.Length, SeekOrigin.End);

            // How many magic bytes there are
            var bytes = reader.ReadByte();
            var output = new byte[reader.BaseStream.Length - MAGIC.Length - bytes];
            int magic = MAGICTRICK;

            // Read the magic bytes
            reader.BaseStream.Seek(-bytes, SeekOrigin.Current);

            bytes--;

            for (var i = 0; i < bytes; i++)
            {
                magic ^= (reader.ReadByte() + MAGICTRICK) % 256;
            }

            // Decode the rest
            reader.BaseStream.Seek(0, SeekOrigin.Begin);

            for (var i = 0; i < output.Length; i++)
            {
                var currentByte = reader.ReadByte();

                output[i] = (byte)(currentByte ^ magic);

                magic = (currentByte + MAGICTRICK) % 256;
            }

            return output;
        }
    }
}

In attachement is compiled and decompiled font by using this code. I prefer 010 HEX Editor so you can create script for it.
atom0s
Posts: 250
Joined: Sat Dec 27, 2014 8:49 pm

Re: Valve VFONT to ttf/otf and back to VFONT

Post by atom0s »

Here's a script I just threw together based on that C# code:

Code: Select all

/**
 * Valve VFONT1 File Decoder Script (010 Editor)
 * Copyright (c) 2021 atom0s
 *
 * Contact: https://atom0s.com
 * Contact: https://discord.gg/UmXNvjq
 * Contact: atom0s#0001 (Discord)
 *
 * Code is based on the snippet shared here:
 * https://zenhax.com/viewtopic.php?p=65623#p65623
 */

/**
 * Magic Key Constant
 */
#define MAGIC_CONST 167

/**
 * Returns if the current file is a valid Valve VFONT1 file.
 *
 * @return {int} 1 if valid, 0 otherwise.
 */
int IsValidFile()
{
    // Obtain the file size and set the file position..
    local int64 fsize = FileSize();
    FSeek(fsize - 6);

    // Read the last 6 bytes and check the signature..
    local string signature = ReadString(FTell(), 6);
    return signature == "VFONT1";
}

/**
 * Decodes the file from a VFONT1 to its normal data.
 */
void DecodeFile()
{
    // Obtain the file size and set the file position..
    local int64 fsize = FileSize();
    FSeek(fsize - 7);

    // Read the magic bytes size..
    local byte msize = ReadByte(FTell());
    local int magic = MAGIC_CONST;

    // Set the file position to the start of the magic bytes..
    FSeek(fsize - 6 - msize);

    // Read and calculate the magic bytes..
    local int64 x = 0;
    for (x = 0; x < (msize - 1); x++) {
        magic ^= (ReadUByte(FTell() + x) + MAGIC_CONST) % 256;
    }

    // Reset the file position..
    FSeek(0);

    // Read, decode and replace the file data..
    local ubyte curr = 0;
    for (x = 0; x < (fsize - 6 - msize); x++) {
        curr = ReadUByte(FTell() + x);
        WriteUByte(FTell() + x, curr ^ magic);
        magic = (curr + MAGIC_CONST) % 256;
    }

    // Remove the magic and signature..
    DeleteBytes(fsize - 6 - msize, 6 + msize);
}

// Test and decode the file..
if (!IsValidFile()) {
    Printf("Invalid file detected; cannot decode.\n");
} else {
    DecodeFile();
}
Last edited by atom0s on Sun Aug 08, 2021 8:12 pm, edited 1 time in total.
h3x3r
Posts: 165
Joined: Wed Jun 01, 2016 5:53 pm

Re: Valve VFONT to ttf/otf and back to VFONT

Post by h3x3r »

Nice and thanks! I guess it's only for decompile?
atom0s
Posts: 250
Joined: Sat Dec 27, 2014 8:49 pm

Re: Valve VFONT to ttf/otf and back to VFONT

Post by atom0s »

Yes, I don't have time atm to write an encoder as well. But you can follow the leaked CS source here:

https://github.com/kisswdev/CSGO-LEAKED ... font.h#L19
https://github.com/kisswdev/CSGO-LEAKED ... odec.h#L21

And just mod the decode script for encoding. It's pretty straightforward and easy to do.
shindegeist
Posts: 21
Joined: Thu Dec 30, 2021 8:49 am

Re: Valve VFONT to ttf/otf and back to VFONT

Post by shindegeist »

any things new guys? I need help to compile and decompile Vfont :(