Skip to content

Instantly share code, notes, and snippets.

@manciuszz
Created September 19, 2025 03:10
Show Gist options
  • Select an option

  • Save manciuszz/a3d3ee8d7d9f5f33d02c42c0d0f97d73 to your computer and use it in GitHub Desktop.

Select an option

Save manciuszz/a3d3ee8d7d9f5f33d02c42c0d0f97d73 to your computer and use it in GitHub Desktop.
External Deserializer for Vivetool.exe /Export /Filename:features.bin
<# :
@echo off
powershell /nologo /noprofile /command "&{[ScriptBlock]::Create((cat """%~f0""") -join [Char[]]10).Invoke(@(&{$args}%*))}"
exit /b
#>
Add-Type -Language CSharp -TypeDefinition @"
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Collections.Generic;
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct RTL_FEATURE_CONFIGURATION
{
public UInt32 FeatureId;
public UInt32 Variant;
public UInt32 ChangeStamp;
public byte EnabledState;
public byte EnabledStateOptions;
public UInt16 VariantPayloadKind;
public UInt64 VariantPayload;
public override string ToString()
{
return string.Format(
"FeatureId={0}, Variant={1}, ChangeStamp={2}, EnabledState={3}, Options={4}, PayloadKind={5}, Payload=0x{6:X}",
FeatureId, Variant, ChangeStamp, EnabledState, EnabledStateOptions, VariantPayloadKind, VariantPayload
);
}
}
public static class FeatureConfigDeserializer
{
public static List<RTL_FEATURE_CONFIGURATION> ReadConfigs(BinaryReader br)
{
int count = br.ReadInt32();
var list = new List<RTL_FEATURE_CONFIGURATION>(count);
for (int i = 0; i < count; i++)
{
RTL_FEATURE_CONFIGURATION cfg = new RTL_FEATURE_CONFIGURATION();
cfg.FeatureId = br.ReadUInt32();
cfg.Variant = br.ReadUInt32();
cfg.ChangeStamp = br.ReadUInt32();
cfg.EnabledState = br.ReadByte();
cfg.EnabledStateOptions = br.ReadByte();
cfg.VariantPayloadKind = br.ReadUInt16();
cfg.VariantPayload = br.ReadUInt64();
list.Add(cfg);
}
return list;
}
}
"@
# Input and output
$binFile = "features.bin"
$outFile = "features.txt"
$runtime = $null
$boot = $null
# Deserialize
[System.IO.File]::OpenRead($binFile) | ForEach-Object {
$br = New-Object System.IO.BinaryReader($_)
$runtime = [FeatureConfigDeserializer]::ReadConfigs($br)
$boot = [FeatureConfigDeserializer]::ReadConfigs($br)
$br.Close()
}
# Write human-readable output
$lines = @()
$lines += "=== Runtime Features ($($runtime.Count)) ==="
$lines += $runtime | ForEach-Object { $_.ToString() }
$lines += ""
$lines += "=== Boot Features ($($boot.Count)) ==="
$lines += $boot | ForEach-Object { $_.ToString() }
$lines | Set-Content $outFile -Encoding UTF8
Write-Host "Deserialized $($runtime.Count) runtime and $($boot.Count) boot features into $outFile"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment