Add DLL to modify PlayFab url

This commit is contained in:
AeonLucid
2021-10-30 04:40:10 +02:00
parent 377b99b4a6
commit 560a39a70b
23 changed files with 501 additions and 40 deletions
+18 -7
View File
@@ -47,13 +47,21 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)bin\$(Platform)\$(Configuration)\</OutDir>
<OutDir>$(SolutionDir)Prospect.Launcher\Libs</OutDir>
<IntDir>$(ProjectDir)bin\intermediate\$(Platform)\$(Configuration)\</IntDir>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(ProjectDir)bin\$(Platform)\$(Configuration)\</OutDir>
<OutDir>$(SolutionDir)Prospect.Launcher\Libs</OutDir>
<IntDir>$(ProjectDir)bin\intermediate\$(Platform)\$(Configuration)\</IntDir>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgUseStatic>true</VcpkgUseStatic>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgUseStatic>true</VcpkgUseStatic>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@@ -63,13 +71,13 @@
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(ProjectDir)libs\detours\;$(UESDK);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>detours.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -82,7 +90,8 @@
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(ProjectDir)libs\detours\;$(UESDK);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>MinSpace</Optimization>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -90,12 +99,14 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>detours.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="hooks.h" />
<ClInclude Include="logger.h" />
<ClInclude Include="main.h" />
<ClInclude Include="SDK.h" />
<ClInclude Include="SDK_Memory.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="logger.cpp" />
@@ -15,10 +15,16 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="main.h">
<ClInclude Include="logger.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="logger.h">
<ClInclude Include="SDK.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="hooks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SDK_Memory.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
+96
View File
@@ -0,0 +1,96 @@
#pragma once
#include <cstdint>
#include <locale>
#include <string>
#include "SDK_Memory.h"
namespace SDK
{
template<class T>
struct TArray
{
friend struct FString;
TArray()
{
Data = nullptr;
Count = Max = 0;
}
int Num() const
{
return Count;
}
T& operator[](int i)
{
return Data[i];
}
const T& operator[](int i) const
{
return Data[i];
}
bool IsValidIndex(int i) const
{
return i < Num();
}
private:
T* Data;
int32_t Count;
int32_t Max;
};
struct FString : private TArray<wchar_t>
{
FString(const wchar_t* other)
{
Max = Count = *other ? std::wcslen(other) + 1 : 0;
if (Count)
{
Data = static_cast<wchar_t*>(GMalloc->Malloc(Count));
wcscpy_s(Data, Count, other);
}
}
FString(const std::wstring& other) : FString(other.c_str())
{
}
bool IsValid() const
{
return Data != nullptr;
}
const wchar_t* c_str() const
{
return Data;
}
std::string ToString() const
{
const auto length = std::wcslen(Data);
std::string str(length, '\0');
std::use_facet<std::ctype<wchar_t>>(std::locale()).narrow(Data, Data + length, '?', &str[0]);
return str;
}
};
struct UPlayFabAPISettings
{
FString VerticalName;
FString BaseServiceHost;
FString TitleId;
FString AdvertisingIdType;
FString AdvertisingIdValue;
bool DisableAdvertising = false;
};
}
+79
View File
@@ -0,0 +1,79 @@
#pragma once
#include <cstdint>
#define DEFAULT_ALIGNMENT 0
namespace SDK
{
class FExec
{
public:
virtual ~FExec() = default;
private:
virtual bool Exec(void* world, void* cmd, void* ar) = 0;
};
class FMalloc : FExec
{
public:
virtual void* Malloc(SIZE_T Count, uint32_t Alignment = DEFAULT_ALIGNMENT) = 0;
virtual void* TryMalloc(SIZE_T Count, uint32_t Alignment = DEFAULT_ALIGNMENT) = 0;
virtual void* Realloc(void* Original, SIZE_T Count, uint32_t Alignment = DEFAULT_ALIGNMENT) = 0;
virtual void* TryRealloc(void* Original, SIZE_T Count, uint32_t Alignment = DEFAULT_ALIGNMENT) = 0;
virtual void Free(void* Original) = 0;
virtual SIZE_T QuantizeSize(SIZE_T Count, uint32_t Alignment)
{
return Count;
}
virtual bool GetAllocationSize(void* Original, SIZE_T& SizeOut)
{
return false;
}
virtual void Trim(bool bTrimThreadCaches)
{
}
virtual void SetupTLSCachesOnCurrentThread()
{
}
virtual void ClearAndDisableTLSCachesOnCurrentThread()
{
}
virtual void InitializeStatsMetadata();
virtual bool Exec(void* InWorld, void* Cmd, void* Ar) override
{
return false;
}
virtual void UpdateStats() = 0;
virtual void GetAllocatorStats(void* out_Stats) = 0;
virtual void DumpAllocatorStats(class FOutputDevice& Ar) = 0;
virtual bool IsInternallyThreadSafe() const
{
return false;
}
virtual bool ValidateHeap()
{
return(true);
}
virtual const TCHAR* GetDescriptiveName() = 0;
};
FMalloc* GMalloc;
}
+3
View File
@@ -0,0 +1,3 @@
#pragma once
#include "SDK.h"
+3
View File
@@ -1,5 +1,8 @@
#include "logger.h"
#include <cstdio>
#include <Windows.h>
HANDLE h_out = nullptr, h_old_out = nullptr;
HANDLE h_err = nullptr, h_old_err = nullptr;
HANDLE h_in = nullptr, h_old_in = nullptr;
+1 -4
View File
@@ -1,8 +1,5 @@
#pragma once
#include <cstdio>
#include <Windows.h>
namespace logger
{
void Attach();
@@ -12,4 +9,4 @@ namespace logger
bool Print(const char* fmt, ...);
char ReadKey();
};
}
+68 -6
View File
@@ -1,17 +1,71 @@
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <MinHook.h>
#include <cstdio>
#include "main.h"
#include "logger.h"
#include <detours.h>
#include "SDK.h"
#include "SDK_Memory.h"
/**
* Variable offset, find with "STOPMOVIECAPTURE", scroll up.
*/
constexpr uintptr_t OffsetGMalloc = 0x5C9A3F8;
/**
* Function offset, find with "?sdk=".
*/
constexpr uintptr_t OffsetPlayFabApiGetUrl = 0xCA5010;
/**
* Function hooks.
*/
typedef SDK::FString(__fastcall* tPlayFabApiGetUrl)(SDK::UPlayFabAPISettings*, const SDK::FString&);
tPlayFabApiGetUrl OldPlayFabApiGetUrl;
SDK::FString __fastcall PlayFabApiGetUrlProxy(SDK::UPlayFabAPISettings* thiz, const SDK::FString& callPath)
{
logger::Print("[Agent] GetURL called with callPath %s\n", callPath.ToString().c_str());
return std::wstring(L"http://127.0.0.1:8888") + std::wstring(callPath.c_str());
}
DWORD WINAPI OnDllAttach(LPVOID base)
{
logger::Attach();
logger::Print("[Agent] DLL Attached\n");
// TODO: Patch.
const auto hModule = GetModuleHandleW(nullptr);
const auto hModulePtr = reinterpret_cast<uintptr_t>(hModule);
logger::Print("[Agent] DLL Exit\n");
FreeLibraryAndExitThread(static_cast<HMODULE>(base), 1);
// Initialize GMalloc.
SDK::GMalloc = *reinterpret_cast<SDK::FMalloc**>(hModulePtr + OffsetGMalloc);
// Initialize MinHook.
if (MH_Initialize() != MH_OK)
{
logger::Print("[Agent] Failed to initialize MinHook\n");
FreeLibraryAndExitThread(hModule, 1);
}
// Hook UPlayFabAPISettings::GetUrl.
const auto pTarget = reinterpret_cast<LPVOID>(hModulePtr + OffsetPlayFabApiGetUrl);
const auto ppOriginal = reinterpret_cast<LPVOID*>(&OldPlayFabApiGetUrl);
const auto mhStatus = MH_CreateHook(pTarget, &PlayFabApiGetUrlProxy, ppOriginal);
if (mhStatus != MH_OK)
{
logger::Print("[Agent] Failed to create PlayFabAPIGetUrl hook (%d)\n", mhStatus);
FreeLibraryAndExitThread(hModule, 1);
}
if (MH_EnableHook(pTarget) != MH_OK)
{
logger::Print("[Agent] Failed to enable PlayFabAPIGetUrl hook\n");
FreeLibraryAndExitThread(hModule, 1);
}
logger::Print("[Agent] DLL Initialized\n");
ExitThread(1);
}
BOOL WINAPI DllMain(
@@ -28,9 +82,17 @@ BOOL WINAPI DllMain(
AllocConsole();
freopen_s(reinterpret_cast<FILE**>(stdout), "CONOUT$", "w", stdout);
// Attach logger.
logger::Attach();
// Spawn thread.
CreateThread(nullptr, 0, OnDllAttach, hinstDll, 0, nullptr);
}
else if (fdwReason == DLL_PROCESS_DETACH)
{
// Detach logger.
logger::Detach();
}
return TRUE;
}
-4
View File
@@ -1,4 +0,0 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+56
View File
@@ -0,0 +1,56 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using Prospect.Launcher.Invoke;
namespace Prospect.Launcher
{
public static class Inject
{
const int PROCESS_CREATE_THREAD = 0x0002;
const int PROCESS_QUERY_INFORMATION = 0x0400;
const int PROCESS_VM_OPERATION = 0x0008;
const int PROCESS_VM_WRITE = 0x0020;
const int PROCESS_VM_READ = 0x0010;
const uint MEM_COMMIT = 0x00001000;
const uint MEM_RESERVE = 0x00002000;
const uint PAGE_READWRITE = 4;
// https://codingvision.net/c-inject-a-dll-into-a-process-w-createremotethread
public static unsafe bool Library(uint processId, string path)
{
IntPtr procHandle = Kernel32.OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, (int)processId);
var loadLibraryAddr = Kernel32.GetProcAddress(Kernel32.GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if (loadLibraryAddr == IntPtr.Zero)
{
Console.WriteLine("Failed GetProcAddress.");
return false;
}
var allocMemAddress = Kernel32.VirtualAllocEx(procHandle, IntPtr.Zero, (uint)((path.Length + 1) * Marshal.SizeOf(typeof(char))), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (allocMemAddress == IntPtr.Zero)
{
Console.WriteLine("Failed VirtualAllocEx.");
return false;
}
var libraryBytes = Encoding.Default.GetBytes(path);
fixed (byte* pLibraryBytes = libraryBytes)
{
Kernel32.WriteProcessMemory(procHandle, allocMemAddress, pLibraryBytes, libraryBytes.Length + 1, out _);
}
var threadHandle = Kernel32.CreateRemoteThread(procHandle, IntPtr.Zero, 0, loadLibraryAddr, allocMemAddress, 0, IntPtr.Zero);
if (threadHandle == IntPtr.Zero)
{
Console.WriteLine("Failed CreateRemoteThread.");
return false;
}
return true;
}
}
}
+18
View File
@@ -42,5 +42,23 @@ namespace Prospect.Launcher.Invoke
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, uint flNewProtect, out uint lpflOldProtect);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint ResumeThread(IntPtr hThread);
}
}
Binary file not shown.
+6 -3
View File
@@ -44,10 +44,13 @@ namespace Prospect.Launcher
Write(offset, data);
}
public unsafe void Write(int offset, Span<byte> data)
public unsafe void Write(int offset, ReadOnlySpan<byte> data)
{
var addr = _baseAddress + offset;
Write(_baseAddress + offset, data);
}
public unsafe void Write(IntPtr addr, ReadOnlySpan<byte> data)
{
// Modify protection.
if (!Kernel32.VirtualProtectEx(_handle, addr, data.Length, 0x40, out var oldProtect))
{
@@ -56,7 +59,7 @@ namespace Prospect.Launcher
fixed (byte* pData = data)
{
var write = Kernel32.WriteProcessMemory(_handle, _baseAddress + offset, pData, data.Length, out _);
var write = Kernel32.WriteProcessMemory(_handle, addr, pData, data.Length, out _);
// Restore protection.
Kernel32.VirtualProtectEx(_handle, addr, data.Length, oldProtect, out _);
+12 -13
View File
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using Prospect.Launcher.Invoke;
using Prospect.Launcher.Invoke.Structs;
@@ -33,6 +32,7 @@ namespace Prospect.Launcher
// 2EA46 = Default
// A22AB = The Cycle Playtest
gameArgs.Add("-empty");
gameArgs.Add("-log");
gameArgs.Add("-windowed");
gameArgs.Add("-noeac");
@@ -51,7 +51,7 @@ namespace Prospect.Launcher
// Spawn.
var startupInfo = new StartupInfo();
if (!Kernel32.CreateProcess(gameBinary, string.Join(' ', gameArgs), ProcessCreationFlags.ZERO_FLAG, ref startupInfo, out var processInfo))
if (!Kernel32.CreateProcess(gameBinary, string.Join(' ', gameArgs), ProcessCreationFlags.CREATE_SUSPENDED, ref startupInfo, out var processInfo))
{
Console.WriteLine("Failed to spawn game.");
return;
@@ -59,22 +59,21 @@ namespace Prospect.Launcher
Console.WriteLine("Spawned.");
// Modify.
MemoryHelper memory;
// Inject DLL.
var agentPath = Path.Combine(AppContext.BaseDirectory, "Libs", "Prospect.Agent.dll");
while ((memory = MemoryHelper.CreateForHandle(processInfo.hProcess, gameBinary)) == null)
if (!Inject.Library(processInfo.dwProcessId, agentPath))
{
Console.WriteLine("Failed to obtain MemoryHelper.");
Thread.Sleep(100);
}
if (!Patches.ChangePlayFabUrl(memory, ".localhost"))
{
Console.WriteLine("Failed to patch playfab url.");
Console.WriteLine("Failed to inject library.");
return;
}
Console.WriteLine("Patched.");
Console.WriteLine("Injected.");
// Resume.
Kernel32.ResumeThread(processInfo.hThread);
Console.WriteLine("Resumed.");
}
}
}
@@ -14,4 +14,14 @@
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Folder Include="Libs" />
</ItemGroup>
<ItemGroup>
<None Update="Libs\Prospect.Agent.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
+45
View File
@@ -0,0 +1,45 @@
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Events;
namespace Prospect.Server.Api
{
public static class Program
{
public static int Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Console()
.CreateLogger();
try
{
Log.Information("Starting web host");
CreateHostBuilder(args).Build().Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
@@ -0,0 +1,13 @@
{
"profiles": {
"Prospect.Server.Api": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"applicationUrl": "https://A22AB.localhost:5555",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
</ItemGroup>
</Project>
+33
View File
@@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
namespace Prospect.Server.Api
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSerilogRequestLogging();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
@@ -0,0 +1,2 @@
{
}
+2
View File
@@ -0,0 +1,2 @@
{
}
+10
View File
@@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Prospect.Agent", "Prospect.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prospect.Launcher", "Prospect.Launcher\Prospect.Launcher.csproj", "{1C8F4637-9552-4726-818B-196ECE2AE966}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prospect.Server.Api", "Prospect.Server.Api\Prospect.Server.Api.csproj", "{A539B020-8BEC-497F-9176-DC2665D927A1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -29,6 +31,14 @@ Global
{1C8F4637-9552-4726-818B-196ECE2AE966}.Release|x64.Build.0 = Release|Any CPU
{1C8F4637-9552-4726-818B-196ECE2AE966}.Release|x86.ActiveCfg = Release|Any CPU
{1C8F4637-9552-4726-818B-196ECE2AE966}.Release|x86.Build.0 = Release|Any CPU
{A539B020-8BEC-497F-9176-DC2665D927A1}.Debug|x64.ActiveCfg = Debug|Any CPU
{A539B020-8BEC-497F-9176-DC2665D927A1}.Debug|x64.Build.0 = Debug|Any CPU
{A539B020-8BEC-497F-9176-DC2665D927A1}.Debug|x86.ActiveCfg = Debug|Any CPU
{A539B020-8BEC-497F-9176-DC2665D927A1}.Debug|x86.Build.0 = Debug|Any CPU
{A539B020-8BEC-497F-9176-DC2665D927A1}.Release|x64.ActiveCfg = Release|Any CPU
{A539B020-8BEC-497F-9176-DC2665D927A1}.Release|x64.Build.0 = Release|Any CPU
{A539B020-8BEC-497F-9176-DC2665D927A1}.Release|x86.ActiveCfg = Release|Any CPU
{A539B020-8BEC-497F-9176-DC2665D927A1}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+6
View File
@@ -0,0 +1,6 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Abbreviations/=API/@EntryIndexedValue">API</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Abbreviations/=SDK/@EntryIndexedValue">SDK</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Classes_0020and_0020structs/@EntryIndexedValue">&lt;NamingElement Priority="1"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="__interface" /&gt;&lt;type Name="class" /&gt;&lt;type Name="struct" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Class_0020and_0020struct_0020methods/@EntryIndexedValue">&lt;NamingElement Priority="10"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="member function" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Namespaces/@EntryIndexedValue">&lt;NamingElement Priority="17"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="namespace" /&gt;&lt;type Name="namespace alias" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/NamingElement&gt;</s:String></wpf:ResourceDictionary>