[C#] oembios.dat decryption in C#

Discussion in 'Windows XP / Older OS' started by krlahna, Oct 7, 2012.

  1. krlahna

    krlahna MDL Novice

    Sep 16, 2012
    31
    38
    0
    #1 krlahna, Oct 7, 2012
    Last edited by a moderator: Apr 20, 2017
    Code:
    enum KeyType
    {
      WindowsXP,
      Windows2003
    }
    
    void DecryptOembios(byte[] data, KeyType keyType)
    {
      // select keys
      byte[] key0;
      uint[] key1;
    
      if (keyType == KeyType.WindowsXP)
      {
        key0 = new byte[] { 0x65, 0x48, 0x73, 0xb3, 0x19, 0x81, 0x67, 0xca, 0xbf, 0x02, 0xfd, 0x2e, 0xb7, 0xe3, 0x3d, 0x17 };
        key1 = new uint[] { 0x6bef9812, 0xe4ccc512, 0x08714298, 0x3ed2ee96 };
      }
      else
      {
        key0 = new byte[] { 0x76, 0xd0, 0xe7, 0x70, 0xf6, 0xb4, 0xd1, 0x76, 0x13, 0xcd, 0x6e, 0x06, 0xd7, 0x28, 0x2c, 0xce };
        key1 = new uint[] { 0xf3462a5d, 0xc605e0d6, 0x0e524b90, 0x80649049 };
      }
    
      // initialize keystream (using key0)
      byte[] keystream = new byte[256];
      for (int i = 0; i < 256; ++i)
        keystream = (byte)i;
    
      byte swapIndex = 0;
      for (int i = 0; i < 256; ++i)
      {
        swapIndex += (byte)(keystream + key0[i & 0xf]);
        byte swap = keystream;
        keystream = keystream[swapIndex];
        keystream[swapIndex] = swap;
      }
    
      // first step (using keystream)
      byte keystreamIndex0 = 0, keystreamIndex1 = 0;
      for (int offset = 0; offset < data.Length; ++offset)
      {
        keystreamIndex1 += keystream[++keystreamIndex0];
        byte swap = keystream[keystreamIndex1];
        keystream[keystreamIndex1] = keystream[keystreamIndex0];
        keystream[keystreamIndex0] = swap;
        data[offset] ^= keystream[(byte)(keystream[keystreamIndex0] + keystream[keystreamIndex1])];
      }
    
      // second step (using key1)
      for (int offset = data.Length - 8; offset >= 0; --offset)
      {
        uint data0 = BitConverter.ToUInt32(data, offset);
        uint data1 = BitConverter.ToUInt32(data, offset + 4);
        uint tmp = 0xc6ef3720;
        for (int i = 0; i < 32; ++i)
        {
          data1 -= tmp + key1[tmp >> 11 & 3] ^ data0 + (data0 << 4 ^ data0 >> 5);
          tmp += 0x61c88647;
          data0 -= tmp + key1[tmp & 3] ^ data1 + (data1 << 4 ^ data1 >> 5);
        }
        BitConverter.GetBytes(data0).CopyTo(data, offset);
        BitConverter.GetBytes(data1).CopyTo(data, offset + 4);
      }
    }
     
  2. FreeStyler

    FreeStyler MDL Guru

    Jun 23, 2007
    3,557
    3,832
    120
    Anyone knows how to use this? i tried writing a simple console app, but it always fails with some vague error
     
  3. krlahna

    krlahna MDL Novice

    Sep 16, 2012
    31
    38
    0
    #3 krlahna, Jun 25, 2013
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Code:
    byte[] oembios = System.IO.File.ReadAllBytes(@"C:\oembios.dat");
    DecryptOembios(oembios, KeyType.WindowsXP);
    System.IO.File.WriteAllBytes(@"C:\oembios_decrypted.txt", oembios);
     
  4. user_hidden

    user_hidden MDL Expert

    Dec 18, 2007
    1,034
    1,061
    60
    #5 user_hidden, Oct 15, 2013
    Last edited by a moderator: Apr 20, 2017
  5. Tito

    Tito Super Mod / Adviser
    Staff Member

    Nov 30, 2009
    18,681
    18,589
    340
  6. user_hidden

    user_hidden MDL Expert

    Dec 18, 2007
    1,034
    1,061
    60
    you amaze me...... do you have MDL indexed in your head ? :)

    on another note does anyone have the first post in a compileable form ?
     
  7. krlahna

    krlahna MDL Novice

    Sep 16, 2012
    31
    38
    0
    #8 krlahna, Oct 15, 2013
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Code:
    using System;
    using System.IO;
    
    namespace OembiosDecrypt
    {
      class Program
      {
        enum KeyType
        {
          WindowsXP,
          Windows2003
        }
    
        private static void DecryptOembios(byte[] data, KeyType keyType)
        {
          // select keys
          byte[] key0;
          uint[] key1;
    
          if (keyType == KeyType.WindowsXP)
          {
            key0 = new byte[] { 0x65, 0x48, 0x73, 0xb3, 0x19, 0x81, 0x67, 0xca, 0xbf, 0x02, 0xfd, 0x2e, 0xb7, 0xe3, 0x3d, 0x17 };
            key1 = new uint[] { 0x6bef9812, 0xe4ccc512, 0x08714298, 0x3ed2ee96 };
          }
          else
          {
            key0 = new byte[] { 0x76, 0xd0, 0xe7, 0x70, 0xf6, 0xb4, 0xd1, 0x76, 0x13, 0xcd, 0x6e, 0x06, 0xd7, 0x28, 0x2c, 0xce };
            key1 = new uint[] { 0xf3462a5d, 0xc605e0d6, 0x0e524b90, 0x80649049 };
          }
    
          // initialize keystream (using key0)
          byte[] keystream = new byte[256];
          for (int i = 0; i < 256; ++i)
            keystream = (byte)i;
    
          byte swapIndex = 0;
          for (int i = 0; i < 256; ++i)
          {
            swapIndex += (byte)(keystream + key0[i & 0xf]);
            byte swap = keystream;
            keystream = keystream[swapIndex];
            keystream[swapIndex] = swap;
          }
    
          // first step (using keystream)
          byte keystreamIndex0 = 0, keystreamIndex1 = 0;
          for (int offset = 0; offset < data.Length; ++offset)
          {
            keystreamIndex1 += keystream[++keystreamIndex0];
            byte swap = keystream[keystreamIndex1];
            keystream[keystreamIndex1] = keystream[keystreamIndex0];
            keystream[keystreamIndex0] = swap;
            data[offset] ^= keystream[(byte)(keystream[keystreamIndex0] + keystream[keystreamIndex1])];
          }
    
          // second step (using key1)
          for (int offset = data.Length - 8; offset >= 0; --offset)
          {
            uint data0 = BitConverter.ToUInt32(data, offset);
            uint data1 = BitConverter.ToUInt32(data, offset + 4);
            uint tmp = 0xc6ef3720;
            for (int i = 0; i < 32; ++i)
            {
              data1 -= tmp + key1[tmp >> 11 & 3] ^ data0 + (data0 << 4 ^ data0 >> 5);
              tmp += 0x61c88647;
              data0 -= tmp + key1[tmp & 3] ^ data1 + (data1 << 4 ^ data1 >> 5);
            }
            BitConverter.GetBytes(data0).CopyTo(data, offset);
            BitConverter.GetBytes(data1).CopyTo(data, offset + 4);
          }
        }
    
        static void Main(string[] args)
        {
          if (args.Length < 2 || args.Length > 3) goto ShowUsage;
          
          KeyType keyType;
    
          if (args[0] == "dx")
            keyType = KeyType.WindowsXP;
          else if (args[0] == "d3")
            keyType = KeyType.Windows2003;
          else
            goto ShowUsage;
    
          try
          {
            byte[] oembios = File.ReadAllBytes(args[1]);
            DecryptOembios(oembios, keyType);
            if (args.Length == 3)
              File.WriteAllBytes(args[2], oembios);
            else
              using (Stream stdout = Console.OpenStandardOutput())
                stdout.Write(oembios, 0, oembios.Length);
          }
          catch (Exception ex)
          {
            Console.Error.WriteLine("Error ({0}): {1}", ex.GetType(), ex.Message);
          }
    
          return;
    
        ShowUsage:
          Console.WriteLine("Usage: oembiosdecrypt.exe <command> <input file> [output file]");
          Console.WriteLine("Commands:");
          Console.WriteLine("\tdx\tDecrypt using XP key");
          Console.WriteLine("\td3\tDecrypt using 2003 key");
        }
      }
    }