Skip to content

Commit

Permalink
Initial upload
Browse files Browse the repository at this point in the history
  • Loading branch information
darknight1050 committed Feb 3, 2024
1 parent ffc37b3 commit d8d18ea
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 1 deletion.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ publish/
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
Expand Down
72 changes: 72 additions & 0 deletions Patches.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace quest_bootloader_unlocker
{
public class Patches
{

public List<PatchesVersion> Versions { get; private set; }

public Patches()
{
Versions =
[
new PatchesVersion("q2_9248600200800000.pe", new Dictionary<int, byte>() {
{ 0x3e4c8, 0x21 },

{ 0x3e4dc, 0x08 },
{ 0x3e4dc + 1, 0x00 },
{ 0x3e4dc + 2, 0x00 },
{ 0x3e4dc + 3, 0x14 },

{ 0x3e4fc + 0, 0x28 },
{ 0x3e4fc + 1, 0x00 },
{ 0x3e4fc + 2, 0x80 },
{ 0x3e4fc + 3, 0xd2 },

{ 0x3e534 + 0, 0x20 },
{ 0x3e534 + 1, 0x00 },
{ 0x3e534 + 2, 0x80 },
{ 0x3e534 + 3, 0xd2 },
}),
];
}


public class PatchesVersion
{
public string Name { get; private set; }
public string File { get; private set; }

public Dictionary<int, byte> Patches { get; private set; }
public int MaxAddress { get => Patches.Keys.Max(); }

public PatchesVersion(string file, IEnumerable<KeyValuePair<int, byte>> patches) : this(file, file, patches) { }

public PatchesVersion(string name, string file, IEnumerable<KeyValuePair<int, byte>> patches)
{
Name = name;
File = file;
Patches = new Dictionary<int, byte>(patches);
}


public bool ApplyTo(ref byte[] buffer)
{
if (buffer.Length <= MaxAddress)
return false;
foreach (var patch in Patches)
{
buffer[patch.Key] = patch.Value;
}
return true;
}

}
}
}
52 changes: 52 additions & 0 deletions Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using LibUsbDotNet;
using LibUsbDotNet.LibUsb;
using LibUsbDotNet.Main;
using quest_bootloader_unlocker;
using System;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;
using static System.Net.Mime.MediaTypeNames;

namespace Examples;

internal class Program
{

public static void Main(string[] args)
{
var patches = new Patches();
using (var device = new QuestUsbDevice()) {
if (!device.TryConnect())
{
Console.WriteLine("Can't find the Quest Device!");
return;
}
var selectedVersion = patches.Versions[0];
var end = selectedVersion.MaxAddress + 1;
var buffer = Enumerable.Repeat((byte)0x0C, 0x100000 + end).ToArray();
var firmware = File.ReadAllBytes(selectedVersion.File);
selectedVersion.ApplyTo(ref firmware);
Array.Copy(firmware, 0, buffer, 0x100000, end);

device.WriteS("getvar:serialno");
Console.WriteLine("Read: " + device.ReadS());

Console.WriteLine("Unlock Device? y/n");
if(Console.ReadKey().Key == ConsoleKey.Y) {
device.Write(buffer);
Console.WriteLine("Read: " + device.ReadS());

device.WriteS("flash:unlock_token");
Console.WriteLine("Read: " + device.ReadS());
Console.WriteLine("Read: " + device.ReadS());

device.Close();
}
}
Console.WriteLine("Finished! Press any key to close...");
Console.ReadKey();
}

}
18 changes: 18 additions & 0 deletions Properties/PublishProfiles/FolderProfile.pubxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>publish\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net8.0</TargetFramework>
<SelfContained>false</SelfContained>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun>
</PropertyGroup>
</Project>
89 changes: 89 additions & 0 deletions QuestUsbDevice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using LibUsbDotNet.Main;
using LibUsbDotNet;
using System.Text;

namespace quest_bootloader_unlocker
{
public class QuestUsbDevice : IDisposable
{

private static readonly UsbDeviceFinder UsbDeviceFinder = new UsbDeviceFinder(0x2833, 0x81);

private UsbDevice _device;
private UsbEndpointWriter _writeEndpoint;
private UsbEndpointReader _readEnpoint;

public bool IsConnected()
{
return UsbDevice.AllDevices.Select(v => v.DevicePath).Contains(_device?.DevicePath);
}

public bool TryConnect()
{
_device = UsbDevice.OpenUsbDevice(UsbDeviceFinder);
if (_device == null)
return false;

_readEnpoint = _device.OpenEndpointReader(ReadEndpointID.Ep01);
_writeEndpoint = _device.OpenEndpointWriter(WriteEndpointID.Ep01);
return true;
}

public bool Close()
{
if (_device == null)
{
return false;
}
if (!IsConnected())
return false;
return _device.Close();
}

public int? Write(byte[] buffer)
{
if (!IsConnected())
return null;
int bytesWritten;
_writeEndpoint.Write(buffer, 10000, out bytesWritten);
return bytesWritten;
}

public int? WriteS(string data)
{
if (!IsConnected())
return null;
return Write(Encoding.ASCII.GetBytes(data));
}

public byte[]? Read()
{
if(!IsConnected())
return null;

List<byte> buffer = new List<byte>();
int readBytes = 0;
do
{
var readBuffer = new byte[512];
_readEnpoint.Read(readBuffer, 1000, out readBytes);
buffer.AddRange(readBuffer);
} while (readBytes == 512);
return buffer.ToArray();
}

public string? ReadS()
{
if (!IsConnected())
return null;
return Encoding.ASCII.GetString(Read());
}

public void Dispose()
{
_readEnpoint?.Dispose();
_writeEndpoint?.Dispose();
}

}
}
14 changes: 14 additions & 0 deletions quest-bootloader-unlocker.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>quest_bootloader_unlocker</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="LibUsbDotNet" Version="2.2.29" />
</ItemGroup>
</Project>
25 changes: 25 additions & 0 deletions quest-bootloader-unlocker.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34511.84
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "quest-bootloader-unlocker", "quest-bootloader-unlocker.csproj", "{9CD4D0B5-4455-474F-9696-545A14103BF1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9CD4D0B5-4455-474F-9696-545A14103BF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9CD4D0B5-4455-474F-9696-545A14103BF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9CD4D0B5-4455-474F-9696-545A14103BF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9CD4D0B5-4455-474F-9696-545A14103BF1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7163364C-2EEB-4E0D-BB27-6E04D32D75CD}
EndGlobalSection
EndGlobal

0 comments on commit d8d18ea

Please sign in to comment.