feat: CurrentApp from RodDurangoX2015 and detours installed

This commit is contained in:
CT5
2026-01-29 14:37:16 +11:00
parent 66ebd1bd62
commit 4f6fd28bf2
6 changed files with 441 additions and 18 deletions

View File

@@ -4,20 +4,12 @@ project(WinDurango.KernelX VERSION 1.0.0)
set(VERSION_SUFFIX "-dev.1") # used for non-stable versions, otherwise blank
set(CMAKE_CXX_STANDARD 20)
include(FetchContent)
# Safetyhook
FetchContent_Declare(
safetyhook
GIT_REPOSITORY "https://github.com/cursey/safetyhook.git"
GIT_TAG "origin/main"
)
FetchContent_MakeAvailable(safetyhook)
set(FILES
src/kernelx.cpp
src/dllmain.cpp
src/Hooks.cpp
src/CurrentApp.cpp
include/WinDurango.KernelX/CurrentApp.h
include/WinDurango.KernelX/kernelx.h
include/WinDurango.KernelX/Logan.h
include/WinDurango.KernelX/Hooks.h
@@ -25,7 +17,11 @@ set(FILES
add_library(WinDurango.KernelX SHARED ${FILES})
target_link_libraries(WinDurango.KernelX PRIVATE WinDurango.Common WinDurango.Implementation.WinRT)
target_link_libraries(WinDurango.KernelX PRIVATE
WinDurango.Common
WinDurango.Implementation.WinRT
"${CMAKE_SOURCE_DIR}/vcpkg_installed/vcpkg/pkgs/detours_x64-windows/lib/detours.lib"
)
target_link_options(WinDurango.KernelX
PUBLIC
@@ -36,6 +32,7 @@ target_include_directories(WinDurango.KernelX PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include/WinDurango.KernelX/
${CMAKE_SOURCE_DIR}/projects/WinDurango.Common/include
${CMAKE_SOURCE_DIR}/projects/WinDurango.Implementation.WinRT/include
${CMAKE_SOURCE_DIR}/vcpkg_installed/vcpkg/pkgs/detours_x64-windows/include/detours
)
set_target_properties(WinDurango.KernelX PROPERTIES

View File

@@ -0,0 +1,149 @@
#pragma once
#include "CoreWindow.h"
#include <windows.applicationmodel.store.h>
#include <windows.foundation.h>
#include <windows.system.h>
#include <winrt/base.h>
using namespace ABI::Windows::System;
using namespace ABI::Windows::Foundation;
MIDL_INTERFACE("d52dc065-da3f-4685-995e-9b482eb5e603")
EraICurrentApp : IInspectable
{
public:
virtual HRESULT STDMETHODCALLTYPE get_LicenseInformation(
ABI::Windows::ApplicationModel::Store::ILicenseInformation * *value) = 0;
virtual HRESULT STDMETHODCALLTYPE get_LinkUri(ABI::Windows::Foundation::IUriRuntimeClass * *value) = 0;
virtual HRESULT STDMETHODCALLTYPE get_AppId(GUID * value) = 0;
virtual HRESULT STDMETHODCALLTYPE RequestAppPurchaseAsync(
boolean includeReceipt, __FIAsyncOperation_1_HSTRING * *requestAppPurchaseOperation) = 0;
virtual HRESULT STDMETHODCALLTYPE RequestProductPurchaseAsync(
HSTRING productId, boolean includeReceipt, __FIAsyncOperation_1_HSTRING * *requestProductPurchaseOperation) = 0;
virtual HRESULT STDMETHODCALLTYPE LoadListingInformationAsync(
__FIAsyncOperation_1_Windows__CApplicationModel__CStore__CListingInformation * *loadListingOperation) = 0;
virtual HRESULT STDMETHODCALLTYPE GetAppReceiptAsync(__FIAsyncOperation_1_HSTRING * *appReceiptOperation) = 0;
virtual HRESULT STDMETHODCALLTYPE GetProductReceiptAsync(HSTRING productId, __FIAsyncOperation_1_HSTRING *
*getProductReceiptOperation) = 0;
};
MIDL_INTERFACE("8eb7dc30-f170-4ed5-8e21-1516da3fd367")
EraILicenseInformation : IInspectable
{
public:
virtual HRESULT STDMETHODCALLTYPE get_ProductLicenses(
__FIMapView_2_HSTRING_Windows__CApplicationModel__CStore__CProductLicense * *value) = 0;
virtual HRESULT STDMETHODCALLTYPE get_IsActive(boolean * value) = 0;
virtual HRESULT STDMETHODCALLTYPE get_IsTrial(boolean * value) = 0;
virtual HRESULT STDMETHODCALLTYPE get_ExpirationDate(ABI::Windows::Foundation::DateTime * value) = 0;
virtual HRESULT STDMETHODCALLTYPE add_LicenseChanged(
ABI::Windows::ApplicationModel::Store::ILicenseChangedEventHandler * handler,
EventRegistrationToken * cookie) = 0;
virtual HRESULT STDMETHODCALLTYPE remove_LicenseChanged(EventRegistrationToken cookie) = 0;
};
MIDL_INTERFACE("AA98C583-A3C8-4F51-A5BC-463AE0C23EAA")
EraIXboxUserLicenseInformation : public IInspectable
{
public:
virtual HRESULT STDMETHODCALLTYPE get_CurrentLicenseUserXuid(winrt::hstring * value) = 0;
};
class EraXboxUserLicenseInformationWrapper : public EraIXboxUserLicenseInformation
{
public:
EraXboxUserLicenseInformationWrapper()
{
InterlockedIncrement(&m_RefCount);
}
HRESULT QueryInterface(REFIID riid, void **ppvObject) override;
ULONG AddRef() override;
ULONG Release() override;
HRESULT GetIids(ULONG *iidCount, IID **iids) override;
HRESULT GetRuntimeClassName(HSTRING *className) override;
HRESULT GetTrustLevel(TrustLevel *trustLevel) override;
HRESULT STDMETHODCALLTYPE get_CurrentLicenseUserXuid(winrt::hstring *value) override;
private:
ULONG m_RefCount = 0;
};
class EraLicenseInformationWrapper : public EraILicenseInformation
{
public:
EraLicenseInformationWrapper(ABI::Windows::ApplicationModel::Store::ILicenseInformation *realLicenseInformation) : m_realLicenseInformation(realLicenseInformation)
{
InterlockedIncrement(&m_RefCount);
}
HRESULT QueryInterface(REFIID riid, void **ppvObject) override;
ULONG AddRef() override;
ULONG Release() override;
HRESULT GetIids(ULONG *iidCount, IID **iids) override;
HRESULT GetRuntimeClassName(HSTRING *className) override;
HRESULT GetTrustLevel(TrustLevel *trustLevel) override;
HRESULT STDMETHODCALLTYPE
get_ProductLicenses(__FIMapView_2_HSTRING_Windows__CApplicationModel__CStore__CProductLicense **value) override;
HRESULT STDMETHODCALLTYPE get_IsActive(boolean *value) override;
HRESULT STDMETHODCALLTYPE get_IsTrial(boolean *value) override;
HRESULT STDMETHODCALLTYPE get_ExpirationDate(ABI::Windows::Foundation::DateTime *value) override;
HRESULT STDMETHODCALLTYPE
add_LicenseChanged(ABI::Windows::ApplicationModel::Store::ILicenseChangedEventHandler *handler,
EventRegistrationToken *cookie) override;
HRESULT STDMETHODCALLTYPE remove_LicenseChanged(EventRegistrationToken cookie) override;
private:
ULONG m_RefCount = 0;
ABI::Windows::ApplicationModel::Store::ILicenseInformation *m_realLicenseInformation;
};
class EraCurrentAppWrapper : EraICurrentApp
{
public:
EraCurrentAppWrapper(ABI::Windows::ApplicationModel::Store::ICurrentApp *realApp) : m_realCurrentApp(realApp)
{
InterlockedIncrement(&m_RefCount);
}
HRESULT QueryInterface(REFIID riid, void **ppvObject) override;
ULONG AddRef() override;
ULONG Release() override;
HRESULT GetIids(ULONG *iidCount, IID **iids) override;
HRESULT GetRuntimeClassName(HSTRING *className) override;
HRESULT GetTrustLevel(TrustLevel *trustLevel) override;
HRESULT STDMETHODCALLTYPE
get_LicenseInformation(ABI::Windows::ApplicationModel::Store::ILicenseInformation **value) override;
HRESULT STDMETHODCALLTYPE get_LinkUri(ABI::Windows::Foundation::IUriRuntimeClass **value) override;
HRESULT STDMETHODCALLTYPE get_AppId(GUID *value) override;
HRESULT STDMETHODCALLTYPE RequestAppPurchaseAsync(
boolean includeReceipt, __FIAsyncOperation_1_HSTRING **requestAppPurchaseOperation) override;
HRESULT STDMETHODCALLTYPE
RequestProductPurchaseAsync(HSTRING productId, boolean includeReceipt,
__FIAsyncOperation_1_HSTRING **requestProductPurchaseOperation) override;
HRESULT STDMETHODCALLTYPE LoadListingInformationAsync(
__FIAsyncOperation_1_Windows__CApplicationModel__CStore__CListingInformation **loadListingOperation) override;
HRESULT STDMETHODCALLTYPE GetAppReceiptAsync(__FIAsyncOperation_1_HSTRING **appReceiptOperation) override;
HRESULT STDMETHODCALLTYPE
GetProductReceiptAsync(HSTRING productId, __FIAsyncOperation_1_HSTRING **getProductReceiptOperation) override;
private:
ULONG m_RefCount = 0;
ABI::Windows::ApplicationModel::Store::ICurrentApp *m_realCurrentApp;
};

View File

@@ -1,4 +1,5 @@
#pragma once
#pragma comment(lib, "runtimeobject.lib")
#include <Shlwapi.h>
#include <codecvt>
#include <filesystem>
@@ -9,6 +10,7 @@
#include <winrt/Windows.ApplicationModel.h>
#include <winrt/windows.storage.provider.h>
#include <wrl/client.h>
#include <detours.h>
typedef int32_t (__stdcall *GetActivationFactory_t)(HSTRING classId, IActivationFactory** factory);
@@ -21,3 +23,18 @@ HRESULT PatchNeededImports(_In_opt_ HMODULE Module, _In_ HMODULE ImportModule, _
HMODULE GetRuntimeModule();
inline HRESULT WINAPI EraRoGetActivationFactory(HSTRING classId, REFIID iid, void **factory);
HRESULT WINAPI GetActivationFactoryRedirect(PCWSTR str, REFIID riid, void **ppFactory);
HRESULT STDMETHODCALLTYPE EraAppActivateInstance(IActivationFactory *thisptr, IInspectable **instance);
template <typename T> inline T GetVTableMethod(void *table_base, std::uintptr_t index);
inline bool IsClassName(HSTRING classId, const char *classIdName)
{
const wchar_t *classIdString = WindowsGetStringRawBuffer(classId, nullptr);
std::wstring classIdWString(classIdString);
const std::string classIdStringUTF8(classIdWString.begin(), classIdWString.end());
return (classIdStringUTF8 == classIdName);
}
HRESULT(WINAPI *TrueActivateInstance)(IActivationFactory *thisptr, IInspectable **instance) = nullptr;

View File

@@ -0,0 +1,232 @@
#include "CurrentApp.h"
HRESULT EraXboxUserLicenseInformationWrapper::QueryInterface(const IID &riid, void **ppvObject)
{
if (riid == __uuidof(EraIXboxUserLicenseInformation))
{
*ppvObject = reinterpret_cast<EraICurrentApp*>(this);
AddRef();
return S_OK;
}
*ppvObject = nullptr;
return E_NOINTERFACE;
}
ULONG EraXboxUserLicenseInformationWrapper::AddRef()
{
return InterlockedIncrement(&m_RefCount);
}
ULONG EraXboxUserLicenseInformationWrapper::Release()
{
ULONG refCount = InterlockedDecrement(&m_RefCount);
if (!refCount) delete this;
return refCount;
}
HRESULT EraXboxUserLicenseInformationWrapper::GetIids(ULONG *iidCount, IID **iids)
{
return E_NOTIMPL;
}
HRESULT EraXboxUserLicenseInformationWrapper::GetRuntimeClassName(HSTRING *className)
{
return E_NOTIMPL;
}
HRESULT EraXboxUserLicenseInformationWrapper::GetTrustLevel(TrustLevel *trustLevel)
{
return E_NOTIMPL;
}
HRESULT EraXboxUserLicenseInformationWrapper::get_CurrentLicenseUserXuid(winrt::hstring *value)
{
*value = L"0";
return S_OK;
}
HRESULT EraLicenseInformationWrapper::QueryInterface(const IID &riid, void **ppvObject)
{
if (riid == __uuidof(EraILicenseInformation))
{
*ppvObject = reinterpret_cast<EraICurrentApp*>(this);
AddRef();
return S_OK;
}
if (riid == __uuidof(EraIXboxUserLicenseInformation))
{
*ppvObject = reinterpret_cast<EraIXboxUserLicenseInformation*>(new EraXboxUserLicenseInformationWrapper());
AddRef();
return S_OK;
}
HRESULT hr = m_realLicenseInformation->QueryInterface(riid, ppvObject);
if (FAILED(hr))
{
char iidstr[sizeof("{AAAAAAAA-BBBB-CCCC-DDEE-FFGGHHIIJJKK}")];
OLECHAR iidwstr[sizeof(iidstr)];
StringFromGUID2(riid, iidwstr, ARRAYSIZE(iidwstr));
WideCharToMultiByte(CP_UTF8, 0, iidwstr, -1, iidstr, sizeof(iidstr), nullptr, nullptr);
printf("[LicenseInformationWrapperX] Interface Not Implemented: %s\n", iidstr);
}
*ppvObject = nullptr;
return E_NOINTERFACE;
}
ULONG EraLicenseInformationWrapper::AddRef()
{
return InterlockedIncrement(&m_RefCount);
}
ULONG EraLicenseInformationWrapper::Release()
{
ULONG refCount = InterlockedDecrement(&m_RefCount);
if (!refCount) delete this;
return refCount;
}
HRESULT EraLicenseInformationWrapper::GetIids(ULONG *iidCount, IID **iids)
{
return m_realLicenseInformation->GetIids(iidCount, iids);
}
HRESULT EraLicenseInformationWrapper::GetRuntimeClassName(HSTRING *className)
{
return m_realLicenseInformation->GetRuntimeClassName(className);
}
HRESULT EraLicenseInformationWrapper::GetTrustLevel(TrustLevel *trustLevel)
{
return m_realLicenseInformation->GetTrustLevel(trustLevel);
}
HRESULT EraLicenseInformationWrapper::get_ProductLicenses(ABI::Windows::Foundation::Collections::__FIMapView_2_HSTRING_Windows__CApplicationModel__CStore__CProductLicense_t **value)
{
return E_NOTIMPL;
}
HRESULT EraLicenseInformationWrapper::get_IsActive(boolean *value)
{
*value = true;
return S_OK;
}
HRESULT EraLicenseInformationWrapper::get_IsTrial(boolean *value)
{
*value = false;
return S_OK;
}
HRESULT EraLicenseInformationWrapper::get_ExpirationDate(ABI::Windows::Foundation::DateTime *value)
{
ABI::Windows::Foundation::DateTime time;
time.UniversalTime = UINT64_MAX;
*value = time;
return S_OK;
}
HRESULT EraLicenseInformationWrapper::add_LicenseChanged(ABI::Windows::ApplicationModel::Store::ILicenseChangedEventHandler *handler, EventRegistrationToken *cookie)
{
return S_OK;
}
HRESULT EraLicenseInformationWrapper::remove_LicenseChanged(EventRegistrationToken cookie)
{
return S_OK;
}
HRESULT __stdcall EraCurrentAppWrapper::QueryInterface(REFIID riid, void **ppvObject)
{
if (riid == __uuidof(EraICurrentApp))
{
*ppvObject = reinterpret_cast<EraICurrentApp*>(this);
AddRef();
return S_OK;
}
HRESULT hr = m_realCurrentApp->QueryInterface(riid, ppvObject);
if (FAILED(hr))
{
char iidstr[sizeof("{AAAAAAAA-BBBB-CCCC-DDEE-FFGGHHIIJJKK}")];
OLECHAR iidwstr[sizeof(iidstr)];
StringFromGUID2(riid, iidwstr, ARRAYSIZE(iidwstr));
WideCharToMultiByte(CP_UTF8, 0, iidwstr, -1, iidstr, sizeof(iidstr), nullptr, nullptr);
printf("[EraCurrentAppWrapper] Interface Not Implemented: %s\n", iidstr);
}
*ppvObject = nullptr;
return E_NOINTERFACE;
}
ULONG __stdcall EraCurrentAppWrapper::AddRef()
{
return InterlockedIncrement(&m_RefCount);
}
ULONG __stdcall EraCurrentAppWrapper::Release()
{
ULONG refCount = InterlockedDecrement(&m_RefCount);
if (!refCount) delete this;
return refCount;
}
HRESULT EraCurrentAppWrapper::GetIids(ULONG *iidCount, IID **iids)
{
return m_realCurrentApp->GetIids(iidCount, iids);
}
HRESULT EraCurrentAppWrapper::GetRuntimeClassName(HSTRING *className)
{
return m_realCurrentApp->GetRuntimeClassName(className);
}
HRESULT EraCurrentAppWrapper::GetTrustLevel(TrustLevel *trustLevel)
{
return m_realCurrentApp->GetTrustLevel(trustLevel);
}
HRESULT EraCurrentAppWrapper::get_LicenseInformation(ABI::Windows::ApplicationModel::Store::ILicenseInformation **value)
{
return E_NOTIMPL;
}
HRESULT EraCurrentAppWrapper::get_LinkUri(ABI::Windows::Foundation::IUriRuntimeClass **value)
{
return m_realCurrentApp->get_LinkUri(value);
}
HRESULT EraCurrentAppWrapper::get_AppId(GUID *value)
{
return m_realCurrentApp->get_AppId(value);
}
HRESULT EraCurrentAppWrapper::RequestAppPurchaseAsync(boolean includeReceipt, ABI::Windows::Foundation::__FIAsyncOperation_1_HSTRING_t **requestAppPurchaseOperation)
{
return m_realCurrentApp->RequestAppPurchaseAsync(includeReceipt, requestAppPurchaseOperation);
}
HRESULT EraCurrentAppWrapper::RequestProductPurchaseAsync(HSTRING productId, boolean includeReceipt, ABI::Windows::Foundation::__FIAsyncOperation_1_HSTRING_t **requestProductPurchaseOperation)
{
return S_OK;
}
HRESULT EraCurrentAppWrapper::LoadListingInformationAsync(ABI::Windows::Foundation::__FIAsyncOperation_1_Windows__CApplicationModel__CStore__CListingInformation_t **loadListingOperation)
{
return m_realCurrentApp->LoadListingInformationAsync(loadListingOperation);
}
HRESULT EraCurrentAppWrapper::GetAppReceiptAsync(
ABI::Windows::Foundation::__FIAsyncOperation_1_HSTRING_t **appReceiptOperation)
{
return m_realCurrentApp->GetAppReceiptAsync(appReceiptOperation);
}
HRESULT EraCurrentAppWrapper::GetProductReceiptAsync(
HSTRING productId, ABI::Windows::Foundation::__FIAsyncOperation_1_HSTRING_t **getProductReceiptOperation)
{
return m_realCurrentApp->GetProductReceiptAsync(productId, getProductReceiptOperation);
}

View File

@@ -2,6 +2,9 @@
#include "WinDurango.Common/Interfaces/Storage/Directory.h"
#include "WinDurango.Common/WinDurango.h"
#include "WinDurango.Implementation.WinRT/Interfaces/Storage/Directory.h"
#include "CurrentApp.h"
using namespace ABI::Windows::ApplicationModel::Store;
std::shared_ptr<wd::common::WinDurango> winDurango;
GetActivationFactory_t p_GetActivationFactory;
@@ -113,10 +116,19 @@ HMODULE GetRuntimeModule()
return hModule;
}
/*
* Dynamicly load a func
* https://stackoverflow.com/questions/8696653/dynamically-load-a-function-from-a-dll
*/
template <typename T> inline T GetVTableMethod(void *table_base, std::uintptr_t index)
{
return (T)((*reinterpret_cast<std::uintptr_t **>(table_base))[index]);
}
HRESULT __stdcall EraAppActivateInstance(IActivationFactory *thisptr, IInspectable **instance)
{
*instance = reinterpret_cast<ILicenseInformation *>(
new EraLicenseInformationWrapper(reinterpret_cast<ILicenseInformation *>(*instance)));
return S_OK;
}
inline HRESULT WINAPI EraRoGetActivationFactory(HSTRING classId, REFIID iid, void **factory)
{
const wchar_t *rawString = WindowsGetStringRawBuffer(classId, nullptr);
@@ -128,6 +140,21 @@ inline HRESULT WINAPI EraRoGetActivationFactory(HSTRING classId, REFIID iid, voi
winDurango->log.Log("WinDurango::KernelX", "EraRoGetActivationFactory: {}", rss);
if (IsClassName(classId, "Windows.ApplicationModel.Store.CurrentApp"))
{
HRESULT hr = RoGetActivationFactory(classId, iid, factory);
if (FAILED(hr))
return hr;
TrueActivateInstance = GetVTableMethod<decltype(TrueActivateInstance)>(*factory, 6);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(reinterpret_cast<PVOID *>(&TrueActivateInstance), reinterpret_cast<PVOID>(EraAppActivateInstance));
DetourTransactionCommit();
}
if (!p_GetActivationFactory)
{
HINSTANCE hGetActivationFactoryDLL = LoadLibrary("winrt_x.dll");

View File

@@ -2,6 +2,7 @@
"name": "windurango",
"version": "1.0",
"dependencies": [
"cppwinrt"
"cppwinrt",
"detours"
]
}